1 Commits

Autor SHA1 Mensagem Data
edubecks 3305e23b01 resolviendo bug 2013-05-03 11:58:40 -03:00
1005 arquivos alterados com 56636 adições e 42253 exclusões
+1 -5
Ver Arquivo
@@ -94,8 +94,4 @@ keystore.ks
/modules/JFreeChartWrapper/target/
/modules/CommonsWrapper/target/
/modules/CoreLibraryWrapper/target/
/modules/UILibraryWrapper/target/
/modules/AppearanceAPI/target/
/modules/AppearancePlugin/target/
/modules/AppearancePluginUI/target/
/modules/DesktopAppearance/target/
/modules/UILibraryWrapper/target/
+1 -1
Ver Arquivo
@@ -71,7 +71,7 @@ Gephi is extensible and lets users create plug-ins to add new features, or to mo
- [**Plugins Portal**](http://wiki.gephi.org/index.php/Plugins_portal)
- [Plugins Quick Start (5 minutes)](http://wiki.gephi.org/index.php/Plugin_Quick_Start_(5_minutes))
- [Plugins Quick Start (5 minutes)](http://wiki.gephi.org/index.php/Plugin_Quick_Start_(5_minutes\))
- Browse the [plugins](http://gephi.org/plugins) created by the community
+8
Ver Arquivo
@@ -14,6 +14,14 @@
<packaging>nbm</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dynamic-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>data-attributes-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>graph-api</artifactId>
@@ -45,6 +45,7 @@ import java.awt.Color;
import java.util.HashMap;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeData;
/**
*
@@ -52,27 +53,27 @@ import org.gephi.graph.api.Node;
*/
public abstract class AbstractShortestPathAlgorithm {
protected final HashMap<Node, Color> colors;
protected final HashMap<Node, Double> distances;
protected final HashMap<NodeData, Color> colors;
protected final HashMap<NodeData, Double> distances;
protected final Node sourceNode;
protected double maxDistance = 0;
public AbstractShortestPathAlgorithm(Node sourceNode) {
this.sourceNode = sourceNode;
colors = new HashMap<Node, Color>();
distances = new HashMap<Node, Double>();
colors = new HashMap<NodeData, Color>();
distances = new HashMap<NodeData, Double>();
}
protected boolean relax(Edge edge) {
Node source = edge.getSource();
Node target = edge.getTarget();
double distSource = distances.get(source);
double distTarget = distances.get(target);
double distSource = distances.get(source.getNodeData());
double distTarget = distances.get(target.getNodeData());
double weight = edgeWeight(edge);
double sourceWeight = distSource + weight;
if (sourceWeight < distTarget) {
distances.put(target, sourceWeight);
distances.put(target.getNodeData(), sourceWeight);
maxDistance = Math.max(maxDistance, sourceWeight);
return true;
} else {
@@ -90,7 +91,7 @@ public abstract class AbstractShortestPathAlgorithm {
public abstract Edge getPredecessorIncoming(Node node);
public HashMap<Node, Double> getDistances() {
public HashMap<NodeData, Double> getDistances() {
return distances;
}
@@ -1,50 +1,55 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.algorithms.shortestpath;
import java.util.HashMap;
import org.gephi.data.attributes.type.TimeInterval;
import org.gephi.dynamic.DynamicUtilities;
import org.gephi.dynamic.api.DynamicController;
import org.gephi.graph.api.DirectedGraph;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeData;
import org.openide.util.Lookup;
/**
*
@@ -53,15 +58,19 @@ import org.gephi.graph.api.Node;
public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgorithm {
protected final DirectedGraph graph;
protected final HashMap<Node, Edge> predecessors;
protected final HashMap<NodeData, Edge> predecessors;
protected TimeInterval timeInterval;
public BellmanFordShortestPathAlgorithm(DirectedGraph graph, Node sourceNode) {
super(sourceNode);
this.graph = graph;
predecessors = new HashMap<Node, Edge>();
predecessors = new HashMap<NodeData, Edge>();
DynamicController dynamicController = Lookup.getDefault().lookup(DynamicController.class);
if (dynamicController != null) {
timeInterval = DynamicUtilities.getVisibleInterval(dynamicController.getModel(graph.getGraphModel().getWorkspace()));
}
}
@Override
public void compute() {
graph.readLock();
@@ -69,10 +78,10 @@ public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgori
//Initialize
int nodeCount = 0;
for (Node node : graph.getNodes()) {
distances.put(node, Double.POSITIVE_INFINITY);
distances.put(node.getNodeData(), Double.POSITIVE_INFINITY);
nodeCount++;
}
distances.put(sourceNode, 0d);
distances.put(sourceNode.getNodeData(), 0d);
//Relax edges repeatedly
@@ -83,7 +92,7 @@ public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgori
Node target = edge.getTarget();
if (relax(edge)) {
relaxed = true;
predecessors.put(target, edge);
predecessors.put(target.getNodeData(), edge);
}
}
if (!relaxed) {
@@ -94,7 +103,7 @@ public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgori
//Check for negative-weight cycles
for (Edge edge : graph.getEdges()) {
if (distances.get(edge.getSource()) + edgeWeight(edge) < distances.get(edge.getTarget())) {
if (distances.get(edge.getSource().getNodeData()) + edgeWeight(edge) < distances.get(edge.getTarget().getNodeData())) {
graph.readUnlock();
throw new RuntimeException("The Graph contains a negative-weighted cycle");
}
@@ -105,14 +114,16 @@ public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgori
@Override
protected double edgeWeight(Edge edge) {
if (timeInterval != null) {
return edge.getWeight(timeInterval.getLow(), timeInterval.getHigh());
}
return edge.getWeight();
}
@Override
public Node getPredecessor(Node node) {
Edge edge = predecessors.get(node);
Edge edge = predecessors.get(node.getNodeData());
if (edge != null) {
if (edge.getSource() != node) {
if (edge.getSource().getNodeData() != node.getNodeData()) {
return edge.getSource();
} else {
return edge.getTarget();
@@ -121,8 +132,7 @@ public class BellmanFordShortestPathAlgorithm extends AbstractShortestPathAlgori
return null;
}
@Override
public Edge getPredecessorIncoming(Node node) {
return predecessors.get(node);
return predecessors.get(node.getNodeData());
}
}
@@ -44,93 +44,104 @@ package org.gephi.algorithms.shortestpath;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import org.gephi.data.attributes.type.TimeInterval;
import org.gephi.dynamic.DynamicUtilities;
import org.gephi.dynamic.api.DynamicController;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeData;
import org.openide.util.Lookup;
/**
*
* @author Mathieu Bastian
*/
public class DijkstraShortestPathAlgorithm extends AbstractShortestPathAlgorithm {
protected final Graph graph;
protected final HashMap<Node, Edge> predecessors;
protected final HashMap<NodeData, Edge> predecessors;
protected TimeInterval timeInterval;
public DijkstraShortestPathAlgorithm(Graph graph, Node sourceNode) {
super(sourceNode);
this.graph = graph;
predecessors = new HashMap<Node, Edge>();
predecessors = new HashMap<NodeData, Edge>();
DynamicController dynamicController = Lookup.getDefault().lookup(DynamicController.class);
if (dynamicController != null) {
timeInterval = DynamicUtilities.getVisibleInterval(dynamicController.getModel(graph.getGraphModel().getWorkspace()));
}
}
@Override
public void compute() {
graph.readLock();
Set<Node> unsettledNodes = new HashSet<Node>();
Set<Node> settledNodes = new HashSet<Node>();
Set<NodeData> settledNodes = new HashSet<NodeData>();
//Initialize
for (Node node : graph.getNodes()) {
distances.put(node, Double.POSITIVE_INFINITY);
distances.put(node.getNodeData(), Double.POSITIVE_INFINITY);
}
distances.put(sourceNode, 0d);
distances.put(sourceNode.getNodeData(), 0d);
unsettledNodes.add(sourceNode);
while (!unsettledNodes.isEmpty()) {
// find node with smallest distance value
Double minDistance = Double.POSITIVE_INFINITY;
Node minDistanceNode = null;
for (Node k : unsettledNodes) {
Double dist = distances.get(k);
Double dist = distances.get(k.getNodeData());
if (minDistanceNode == null) {
minDistanceNode = k;
}
if (dist.compareTo(minDistance) < 0) {
minDistance = dist;
minDistanceNode = k;
}
}
unsettledNodes.remove(minDistanceNode);
settledNodes.add(minDistanceNode);
settledNodes.add(minDistanceNode.getNodeData());
for (Edge edge : graph.getEdges(minDistanceNode)) {
Node neighbor = graph.getOpposite(minDistanceNode, edge);
if (!settledNodes.contains(neighbor)) {
if (!settledNodes.contains(neighbor.getNodeData())) {
double dist = getShortestDistance(minDistanceNode) + edgeWeight(edge);
if (getShortestDistance(neighbor) > dist) {
distances.put(neighbor, dist);
predecessors.put(neighbor, edge);
distances.put(neighbor.getNodeData(), dist);
predecessors.put(neighbor.getNodeData(), edge);
unsettledNodes.add(neighbor);
maxDistance = Math.max(maxDistance, dist);
}
}
}
}
graph.readUnlock();
}
private double getShortestDistance(Node destination) {
Double d = distances.get(destination);
Double d = distances.get(destination.getNodeData());
if (d == null) {
return Double.POSITIVE_INFINITY;
} else {
return d;
}
}
@Override
protected double edgeWeight(Edge edge) {
if (timeInterval != null) {
return edge.getWeight(timeInterval.getLow(), timeInterval.getHigh());
}
return edge.getWeight();
}
@Override
public Node getPredecessor(Node node) {
Edge edge = predecessors.get(node);
Edge edge = predecessors.get(node.getNodeData());
if (edge != null) {
if (edge.getSource() != node) {
return edge.getSource();
@@ -140,9 +151,8 @@ public class DijkstraShortestPathAlgorithm extends AbstractShortestPathAlgorithm
}
return null;
}
@Override
public Edge getPredecessorIncoming(Node node) {
return predecessors.get(node);
return predecessors.get(node.getNodeData());
}
}
@@ -1,156 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance;
import org.gephi.appearance.api.AppearanceController;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.spi.Transformer;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.graph.api.Element;
import org.gephi.graph.api.ElementIterable;
import org.gephi.graph.api.GraphModel;
import org.gephi.project.api.ProjectController;
import org.gephi.project.api.Workspace;
import org.gephi.project.api.WorkspaceListener;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = AppearanceController.class)
public class AppearanceControllerImpl implements AppearanceController {
private AppearanceModelImpl model;
public AppearanceControllerImpl() {
//Workspace events
ProjectController pc = Lookup.getDefault().lookup(ProjectController.class);
pc.addWorkspaceListener(new WorkspaceListener() {
@Override
public void initialize(Workspace workspace) {
}
@Override
public void select(Workspace workspace) {
model = workspace.getLookup().lookup(AppearanceModelImpl.class);
if (model == null) {
model = new AppearanceModelImpl(workspace);
workspace.add(model);
}
// model.select();
}
@Override
public void unselect(Workspace workspace) {
// model.unselect();
model = null;
}
@Override
public void close(Workspace workspace) {
}
@Override
public void disable() {
model = null;
}
});
if (pc.getCurrentWorkspace() != null) {
model = pc.getCurrentWorkspace().getLookup().lookup(AppearanceModelImpl.class);
if (model == null) {
model = new AppearanceModelImpl(pc.getCurrentWorkspace());
pc.getCurrentWorkspace().add(model);
}
}
}
@Override
public void transform(Function function) {
if (model != null) {
GraphModel graphModel = model.getGraphModel();
ElementIterable<? extends Element> iterable;
if (function.getTransformer().isNode()) {
iterable = graphModel.getGraphVisible().getNodes();
} else {
iterable = graphModel.getGraphVisible().getEdges();
}
for (Element element : iterable) {
function.transform(element);
}
}
}
@Override
public AppearanceModelImpl getModel() {
return model;
}
@Override
public AppearanceModelImpl getModel(Workspace workspace) {
AppearanceModelImpl m = workspace.getLookup().lookup(AppearanceModelImpl.class);
if (m == null) {
m = new AppearanceModelImpl(workspace);
workspace.add(m);
}
return m;
}
@Override
public Transformer getTransformer(TransformerUI ui) {
Class<? extends Transformer> transformerClass = ui.getTransformerClass();
Transformer transformer = Lookup.getDefault().lookup(transformerClass);
if (transformer != null) {
return transformer;
}
return null;
}
@Override
public void setUseLocalScale(boolean useLocalScale) {
if (model != null) {
model.setLocalScale(useLocalScale);
}
}
}
@@ -1,271 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gephi.appearance.api.AppearanceModel;
import org.gephi.appearance.api.AttributeFunction;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.Interpolator;
import org.gephi.appearance.spi.PartitionTransformer;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.attribute.api.AttributeModel;
import org.gephi.attribute.api.AttributeUtils;
import org.gephi.attribute.api.Column;
import org.gephi.attribute.api.Index;
import org.gephi.graph.api.GraphController;
import org.gephi.graph.api.GraphModel;
import org.gephi.project.api.Workspace;
import org.openide.util.Lookup;
/**
*
* @author mbastian
*/
public class AppearanceModelImpl implements AppearanceModel {
private final Workspace workspace;
private final AttributeModel attributeModel;
private final GraphModel graphModel;
private final Interpolator defaultInterpolator;
private boolean localScale = false;
//Functions
private final Object functionLock;
private List<Function> nodeFunctions;
private List<Function> edgeFunctions;
public AppearanceModelImpl(Workspace workspace) {
this.workspace = workspace;
this.graphModel = Lookup.getDefault().lookup(GraphController.class).getGraphModel(workspace);
this.attributeModel = Lookup.getDefault().lookup(GraphController.class).getAttributeModel(workspace);
this.defaultInterpolator = Interpolator.LINEAR;
this.functionLock = new Object();
//Functions
refreshFunctions();
}
@Override
public Workspace getWorkspace() {
return workspace;
}
@Override
public boolean isLocalScale() {
return localScale;
}
@Override
public Function[] getNodeFunctions() {
refreshFunctions();
return nodeFunctions.toArray(new Function[0]);
}
@Override
public Function[] getEdgeFunctions() {
refreshFunctions();
return edgeFunctions.toArray(new Function[0]);
}
private void refreshFunctions() {
synchronized (functionLock) {
//Index UIs
Map<Class, TransformerUI> uis = new HashMap<Class, TransformerUI>();
for (TransformerUI ui : Lookup.getDefault().lookupAll(TransformerUI.class)) {
Class transformerClass = ui.getTransformerClass();
if (transformerClass == null) {
throw new NullPointerException("Transformer class can' be null");
}
if (uis.containsKey(transformerClass)) {
throw new RuntimeException("A Transformer can't be attach to multiple TransformerUI");
}
uis.put(transformerClass, ui);
}
//Index existing funcs
Set<Column> attributeNodeFunctions = new HashSet<Column>();
Set<Column> attributeEdgeFunctions = new HashSet<Column>();
if (nodeFunctions != null) {
for (Function f : nodeFunctions) {
if (f.isAttribute()) {
attributeNodeFunctions.add(((AttributeFunction) f).getColumn());
}
}
}
if (edgeFunctions != null) {
for (Function f : edgeFunctions) {
if (f.isAttribute()) {
attributeEdgeFunctions.add(((AttributeFunction) f).getColumn());
}
}
}
//Simple transformers
if (nodeFunctions == null) {
nodeFunctions = new ArrayList<Function>();
edgeFunctions = new ArrayList<Function>();
for (Transformer transformer : Lookup.getDefault().lookupAll(Transformer.class)) {
if (transformer instanceof SimpleTransformer) {
if (transformer.isNode()) {
nodeFunctions.add(new FunctionImpl(this, null, transformer, uis.get(transformer.getClass())));
}
if (transformer.isEdge()) {
edgeFunctions.add(new FunctionImpl(this, null, transformer, uis.get(transformer.getClass())));
}
}
}
}
//Atts
Set<Column> foundNodeColumns = new HashSet<Column>();
Set<Column> foundEdgeColumns = new HashSet<Column>();
for (Transformer transformer : Lookup.getDefault().lookupAll(Transformer.class)) {
if (transformer instanceof RankingTransformer || transformer instanceof PartitionTransformer) {
if (transformer.isNode()) {
for (Column col : attributeModel.getNodeTable()) {
if (!col.isProperty()) {
Index index = localScale ? graphModel.getNodeIndex(graphModel.getVisibleView()) : graphModel.getNodeIndex();
if (transformer instanceof RankingTransformer && isRanking(col) && !attributeNodeFunctions.contains(col)) {
nodeFunctions.add(new FunctionImpl(this, col, transformer, uis.get(transformer.getClass()), new RankingImpl(col, index, defaultInterpolator)));
} else if (transformer instanceof PartitionTransformer && isPartition(col) && !attributeNodeFunctions.contains(col)) {
nodeFunctions.add(new FunctionImpl(this, col, transformer, uis.get(transformer.getClass()), new PartitionImpl(col, index)));
}
foundNodeColumns.add(col);
}
}
}
if (transformer.isEdge()) {
for (Column col : attributeModel.getEdgeTable()) {
if (!col.isProperty() && col.isNumber()) {
Index index = localScale ? graphModel.getEdgeIndex(graphModel.getVisibleView()) : graphModel.getEdgeIndex();
if (transformer instanceof RankingTransformer && isRanking(col) && !attributeEdgeFunctions.contains(col)) {
edgeFunctions.add(new FunctionImpl(this, col, transformer, uis.get(transformer.getClass()), new RankingImpl(col, index, defaultInterpolator)));
} else if (transformer instanceof PartitionTransformer && isPartition(col) && !attributeEdgeFunctions.contains(col)) {
edgeFunctions.add(new FunctionImpl(this, col, transformer, uis.get(transformer.getClass()), new PartitionImpl(col, index)));
}
foundEdgeColumns.add(col);
}
}
}
}
}
attributeNodeFunctions.removeAll(foundNodeColumns);
attributeEdgeFunctions.removeAll(foundEdgeColumns);
//Remove
for (Iterator<Function> nodeItr = nodeFunctions.iterator(); nodeItr.hasNext();) {
Function f = nodeItr.next();
if (f.isAttribute() && attributeNodeFunctions.contains(((AttributeFunction) f).getColumn())) {
nodeItr.remove();
}
}
for (Iterator<Function> edgeItr = edgeFunctions.iterator(); edgeItr.hasNext();) {
Function f = edgeItr.next();
if (f.isAttribute() && attributeEdgeFunctions.contains(((AttributeFunction) f).getColumn())) {
edgeItr.remove();
}
}
}
}
private boolean isPartition(Column column) {
Index index;
if (AttributeUtils.isNodeColumn(column)) {
index = localScale ? graphModel.getNodeIndex(graphModel.getVisibleView()) : graphModel.getNodeIndex();
} else {
index = localScale ? graphModel.getEdgeIndex(graphModel.getVisibleView()) : graphModel.getEdgeIndex();
}
int valueCount = index.countValues(column);
int elementCount = index.countElements(column);
double ratio = valueCount / (double) elementCount;
if (column.isNumber()) {
Class columnTypeClass = column.getTypeClass();
if (columnTypeClass.equals(Integer.class)) {
if (ratio < 0.6) {
return true;
}
} else {
if (ratio < 0.1) {
return true;
}
}
} else {
if (ratio < 0.8) {
return true;
}
}
return false;
}
private boolean isRanking(Column column) {
if (column.isNumber()) {
Index index;
if (AttributeUtils.isNodeColumn(column)) {
index = localScale ? graphModel.getNodeIndex(graphModel.getVisibleView()) : graphModel.getNodeIndex();
} else {
index = localScale ? graphModel.getEdgeIndex(graphModel.getVisibleView()) : graphModel.getEdgeIndex();
}
if (index.countValues(column) > 0 && !isPartition(column)) {
return true;
}
}
return false;
}
public void setLocalScale(boolean localScale) {
this.localScale = localScale;
}
protected GraphModel getGraphModel() {
return graphModel;
}
}
@@ -1,202 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance;
import org.gephi.appearance.api.Partition;
import org.gephi.appearance.api.PartitionFunction;
import org.gephi.appearance.api.Ranking;
import org.gephi.appearance.api.RankingFunction;
import org.gephi.appearance.api.SimpleFunction;
import org.gephi.appearance.spi.PartitionTransformer;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.attribute.api.Column;
import org.gephi.graph.api.Element;
/**
*
* @author mbastian
*/
public class FunctionImpl implements RankingFunction, PartitionFunction, SimpleFunction {
protected final AppearanceModelImpl model;
protected final Column column;
protected final Transformer transformer;
protected final TransformerUI transformerUI;
protected final PartitionImpl partition;
protected final RankingImpl ranking;
public FunctionImpl(AppearanceModelImpl model, Column column, Transformer transformer, TransformerUI transformerUI) {
this(model, column, transformer, transformerUI, null, null);
}
public FunctionImpl(AppearanceModelImpl model, Column column, Transformer transformer, TransformerUI transformerUI, RankingImpl ranking) {
this(model, column, transformer, transformerUI, null, ranking);
}
public FunctionImpl(AppearanceModelImpl model, Column column, Transformer transformer, TransformerUI transformerUI, PartitionImpl partition) {
this(model, column, transformer, transformerUI, partition, null);
}
public FunctionImpl(AppearanceModelImpl model, Column column, Transformer transformer, TransformerUI transformerUI, PartitionImpl partition, RankingImpl ranking) {
this.model = model;
this.column = column;
try {
this.transformer = transformer.getClass().newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
this.transformerUI = transformerUI;
this.partition = partition;
this.ranking = ranking;
}
@Override
public void transform(Element element) {
if (isSimple()) {
((SimpleTransformer) transformer).transform(element);
} else if (isRanking()) {
Number val = (Number) element.getAttribute(column);
((RankingTransformer) transformer).transform(element, ranking, val);
} else if (isPartition()) {
Object val = element.getAttribute(column);
((PartitionTransformer) transformer).transform(element, partition, val);
}
}
@Override
public Column getColumn() {
return column;
}
public AppearanceModelImpl getModel() {
return model;
}
@Override
public Transformer getTransformer() {
return transformer;
}
@Override
public TransformerUI getUI() {
return transformerUI;
}
@Override
public boolean isSimple() {
return column == null;
}
@Override
public boolean isAttribute() {
return column != null;
}
@Override
public boolean isPartition() {
return partition != null;
}
@Override
public boolean isRanking() {
return ranking != null;
}
@Override
public Partition getPartition() {
return partition;
}
@Override
public Ranking getRanking() {
return ranking;
}
@Override
public String toString() {
if (column != null) {
if (column.getTitle() != null) {
return column.getTitle();
} else {
return column.getId();
}
}
return super.toString();
}
@Override
public int hashCode() {
int hash = 5;
hash = 47 * hash + (this.column != null ? this.column.hashCode() : 0);
hash = 47 * hash + (this.transformer != null ? this.transformer.hashCode() : 0);
hash = 47 * hash + (this.partition != null ? this.partition.hashCode() : 0);
hash = 47 * hash + (this.ranking != null ? this.ranking.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final FunctionImpl other = (FunctionImpl) obj;
if (this.column != other.column && (this.column == null || !this.column.equals(other.column))) {
return false;
}
if (this.transformer != other.transformer && (this.transformer == null || !this.transformer.equals(other.transformer))) {
return false;
}
if (this.partition != other.partition && (this.partition == null || !this.partition.equals(other.partition))) {
return false;
}
if (this.ranking != other.ranking && (this.ranking == null || !this.ranking.equals(other.ranking))) {
return false;
}
return true;
}
}
@@ -1,129 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance;
import java.awt.Color;
import java.util.HashMap;
import java.util.Map;
import org.gephi.appearance.api.Partition;
import org.gephi.attribute.api.Column;
import org.gephi.attribute.api.Index;
/**
*
* @author mbastian
*/
public class PartitionImpl implements Partition {
private final Index index;
private final Column column;
private final Map<Object, Color> colorMap;
public PartitionImpl(Column column, Index index) {
this.column = column;
this.index = index;
this.colorMap = new HashMap<Object, Color>();
}
@Override
public Iterable getValues() {
return index.values(column);
}
@Override
public int getElementCount() {
return index.countElements(column);
}
@Override
public int count(Object value) {
return index.count(column, value);
}
@Override
public Color getColor(Object value) {
return colorMap.get(value);
}
@Override
public void setColor(Object value, Color color) {
colorMap.put(value, color);
}
@Override
public float percentage(Object value) {
int count = index.count(column, value);
return (float) count / index.countElements(column);
}
@Override
public int size() {
return index.countValues(column);
}
@Override
public Column getColumn() {
return column;
}
@Override
public int hashCode() {
int hash = 3;
hash = 23 * hash + (this.column != null ? this.column.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PartitionImpl other = (PartitionImpl) obj;
if (this.column != other.column && (this.column == null || !this.column.equals(other.column))) {
return false;
}
return true;
}
}
@@ -1,112 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance;
import org.gephi.appearance.api.Interpolator;
import org.gephi.appearance.api.Ranking;
import org.gephi.attribute.api.Column;
import org.gephi.attribute.api.Index;
/**
*
* @author mbastian
*/
public class RankingImpl implements Ranking {
private final Index index;
private final Column column;
private Interpolator interpolator;
public RankingImpl(Column column, Index index, Interpolator interpolator) {
this.column = column;
this.index = index;
this.interpolator = interpolator;
}
@Override
public Number getMinValue() {
return index.getMinValue(column);
}
@Override
public Number getMaxValue() {
return index.getMaxValue(column);
}
@Override
public Interpolator getInterpolator() {
return interpolator;
}
@Override
public void setInterpolator(Interpolator interpolator) {
this.interpolator = interpolator;
}
@Override
public float normalize(Number value) {
float normalizedValue = (float) (value.doubleValue() - getMinValue().doubleValue()) / (float) (getMaxValue().doubleValue() - getMinValue().doubleValue());
return interpolator.interpolate(normalizedValue);
}
@Override
public int hashCode() {
int hash = 3;
hash = 67 * hash + (this.column != null ? this.column.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final RankingImpl other = (RankingImpl) obj;
if (this.column != other.column && (this.column == null || !this.column.equals(other.column))) {
return false;
}
return true;
}
}
@@ -1,72 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
import org.gephi.appearance.spi.Transformer;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.project.api.Workspace;
/**
*
* @author mbastian
*/
public interface AppearanceController {
/**
* Sets whether rankings use a local or a global scale. When calculating the
* minimum and maximum value (i.e. the scale) rankings can use the complete
* graph or only the currently visible graph. When using the visible graph
* it is called the <b>local</b> scale.
*
* @param useLocalScale <code>true</code> for local, <code>false</code> for
* global
*/
public void setUseLocalScale(boolean useLocalScale);
public void transform(Function function);
public AppearanceModel getModel();
public AppearanceModel getModel(Workspace workspace);
public Transformer getTransformer(TransformerUI ui);
}
@@ -1,74 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
import org.gephi.project.api.Workspace;
/**
*
* @author mbastian
*/
public interface AppearanceModel {
/**
* Return the workspace this model is associated with
*
* @return the workspace of this model
*/
public Workspace getWorkspace();
/**
* Returns
* <code>true</code> if rankings are using the currently visible graph as a
* scale. If
* <code>false</code> the complete graph is used to determine minimum and
* maximum values, the ranking scale.
*
* @return <code>true</code> if using a local scale, <code>false</code> if
* global scale
*/
public boolean isLocalScale();
public Function[] getNodeFunctions();
public Function[] getEdgeFunctions();
}
@@ -1,53 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
import org.gephi.attribute.api.Column;
/**
*
* @author mbastian
*/
public interface AttributeFunction extends Function {
public Column getColumn();
}
@@ -1,67 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
import org.gephi.appearance.spi.Transformer;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.graph.api.Element;
/**
*
* @author mbastian
*/
public interface Function {
public void transform(Element element);
public Transformer getTransformer();
public TransformerUI getUI();
public boolean isSimple();
public boolean isAttribute();
public boolean isRanking();
public boolean isPartition();
}
@@ -1,325 +0,0 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.appearance.api;
import java.awt.geom.Point2D;
/**
* Abstract clas that defines the single {@link #interpolate(float)} method.
* This abstract class is implemented by built-in interpolators.
*
* @author Mathieu Bastian
*/
public abstract class Interpolator {
/**
* Linear interpolation
* <code>x = interpolate(x)
* <code>
*/
public static final Interpolator LINEAR = new Interpolator() {
@Override
public float interpolate(float x) {
return x;
}
};
/**
* Log2 interpolation
* <code>Math.log(1 + x)/Math.log(2) = interpolate(x)</code>
*/
public static final Interpolator LOG2 = new Interpolator() {
@Override
public float interpolate(float x) {
return (float) (Math.log(1 + x) / Math.log(2));
}
};
/**
* Builds a bezier interpolator with two control points (px1, py1) and (px2,
* py2). The points should all be in range [0, 1].
*
* @param px1 the x-coordinate of first control point, between [0, 1]
* @param py1 the y-coordinate of first control point, between [0, 1]
* @param px2 the x-coordinate of second control point, between [0, 1]
* @param py2 the y-coordinate of second control point, between [0, 1]
* @return new bezier interpolator
*/
public static Interpolator newBezierInterpolator(float px1, float py1, float px2, float py2) {
return new BezierInterpolator(px1, py1, px2, py2);
}
/**
* This function takes an input value between 0 and 1 and returns another
* value, also between 0 and 1.
*
* @param x a value between 0 and 1
* @return a value between 0 and 1. Values outside of this boundary may be
* clamped to the interval [0,1] and cause undefined results.
*/
public abstract float interpolate(float x);
/**
* Bezier curve interpolator.
* <p>
* Basically, a cubic Bezier curve is created with start point (0,0) and
* endpoint (1,1). The other two control points (px1, py1) and (px2, py2)
* are given by the user, where px1, py1, px1, and px2 are all in the range
* [0,1].
* </p>
*/
//Author David C. Browne
public static class BezierInterpolator extends Interpolator {
/**
* the coordinates of the 2 2D control points for a cubic Bezier curve,
* with implicit start point (0,0) and end point (1,1) -- each
* individual coordinate value must be in range [0,1]
*/
private final float x1, y1, x2, y2;
/**
* do the input control points form a line with (0,0) and (1,1), i.e.,
* x1 == y1 and x2 == y2 -- if so, then all x(t) == y(t) for the curve
*/
private final boolean isCurveLinear;
/**
* power of 2 sample size for lookup table of x values
*/
private static final int SAMPLE_SIZE = 16;
/**
* difference in t used to calculate each of the xSamples values --
* power of 2 sample size should provide exact representation of this
* value and its integer multiples (integer in range of [0..SAMPLE_SIZE]
*/
private static final float SAMPLE_INCREMENT = 1f / SAMPLE_SIZE;
/**
* x values for the bezier curve, sampled at increments of 1/SAMPLE_SIZE
* -- this is used to find the good initial guess for parameter t, given
* an x
*/
private final float[] xSamples = new float[SAMPLE_SIZE + 1];
/**
* constructor -- cubic bezier curve will be represented by control
* points (0,0) (px1,py1) (px2,py2) (1,1) -- px1, py1, px2, py2 all in
* range [0,1]
*
* @param px1 is x-coordinate of first control point, in range [0,1]
* @param py1 is y-coordinate of first control point, in range [0,1]
* @param px2 is x-coordinate of second control point, in range [0,1]
* @param py2 is y-coordinate of second control point, in range [0,1]
*/
public BezierInterpolator(float px1, float py1, float px2, float py2) {
// check user input for precondition
if (px1 < 0 || px1 > 1 || py1 < 0 || py1 > 1
|| px2 < 0 || px2 > 1 || py2 < 0 || py2 > 1) {
throw new IllegalArgumentException("control point coordinates must "
+ "all be in range [0,1]");
}
// save control point data
x1 = px1;
y1 = py1;
x2 = px2;
y2 = py2;
// calc linearity/identity curve
isCurveLinear = ((x1 == y1) && (x2 == y2));
// make the array of x value samples
if (!isCurveLinear) {
for (int i = 0; i < SAMPLE_SIZE + 1; ++i) {
xSamples[i] = eval(i * SAMPLE_INCREMENT, x1, x2);
}
}
}
public Point2D getControl1() {
return new Point2D.Float(x1, y1);
}
public Point2D getControl2() {
return new Point2D.Float(x2, y2);
}
/**
* get the y-value of the cubic bezier curve that corresponds to the x
* input
*
* @param x is x-value of cubic bezier curve, in range [0,1]
* @return corresponding y-value of cubic bezier curve -- in range [0,1]
*/
@Override
public float interpolate(float x) {
// check user input for precondition
if (x < 0) {
x = 0;
} else if (x > 1) {
x = 1;
}
// check quick exit identity cases (linear curve or curve endpoints)
if (isCurveLinear || x == 0 || x == 1) {
return x;
}
// find the t parameter for a given x value, and use this t to calculate
// the corresponding y value
return eval(findTForX(x), y1, y2);
}
/**
* use Bernstein basis to evaluate 1D cubic Bezier curve (quicker and
* more numerically stable than power basis) -- 1D control coordinates
* are (0, p1, p2, 1), where p1 and p2 are in range [0,1], and there is
* no ordering constraint on p1 and p2, i.e., p1 <= p2 does not have to
* be true @param t is the pa
*
* ramaterized value in range [0,1] @param p1 is 1st control point
* coordinate in range [0,1] @param p2 is 2nd control point coor
*
* d
* inate in range [0,1] @return the value of the Bezier curve at
* parameter t
*/
private float eval(float t, float p1, float p2) {
// Use optimzied version of the normal Bernstein basis form of Bezier:
// (3*(1-t)*(1-t)*t*p1)+(3*(1-t)*t*t*p2)+(t*t*t), since p0=0, p3=1
// The above unoptimized version is best using -server, but since we are
// probably doing client-side animation, this is faster.
float compT = 1 - t;
return t * (3 * compT * (compT * p1 + t * p2) + (t * t));
}
/**
* evaluate Bernstein basis derivative of 1D cubic Bezier curve, where
* 1D control points are (0, p1, p2, 1), where p1 and p2 are in range
* [0,1], and there is no ordering constraint on p1 and p2, i.e., p1 <=
* p2 does not have to be true @param t is the paramaterized
*
* value in range [0,1] @param p1 is 1st control point coordinate in
* range [0,1] @param p2 is 2nd control point coo
*
* r
* dinate in range [0,1] @return the value of the Bezier curve at
* parameter t
*/
private float evalDerivative(float t, float p1, float p2) {
// use optimzed version of Berstein basis Bezier derivative:
// (3*(1-t)*(1-t)*p1)+(6*(1-t)*t*(p2-p1))+(3*t*t*(1-p2)), since p0=0, p3=1
// The above unoptimized version is best using -server, but since we are
// probably doing client-side animation, this is faster.
float compT = 1 - t;
return 3 * (compT * (compT * p1 + 2 * t * (p2 - p1)) + t * t * (1 - p2));
}
/**
* find an initial good guess for what parameter t might produce the
* x-value on the Bezier curve -- uses linear interpolation on the
* x-value sample array that was created on construction
*
* @param x is x-value of cubic bezier curve, in range [0,1]
* @return a good initial guess for parameter t (in range [0,1]) that
* gives x
*/
private float getInitialGuessForT(float x) {
// find which places in the array that x would be sandwiched between,
// and then linearly interpolate a reasonable value of t -- array values
// are ascending (or at least never descending) -- binary search is
// probably more trouble than it is worth here
for (int i = 1; i < SAMPLE_SIZE + 1; ++i) {
if (xSamples[i] >= x) {
float xRange = xSamples[i] - xSamples[i - 1];
if (xRange == 0) {
// no change in value between samples, so use earlier time
return (i - 1) * SAMPLE_INCREMENT;
} else {
// linearly interpolate the time value
return ((i - 1) + ((x - xSamples[i - 1]) / xRange))
* SAMPLE_INCREMENT;
}
}
}
// shouldn't get here since 0 <= x <= 1, and xSamples[0] == 0 and
// xSamples[SAMPLE_SIZE] == 1 (using power of 2 SAMPLE_SIZE for more
// exact increment arithmetic)
return 1;
}
/**
* find the parameter t that produces the given x-value for the curve --
* uses Newton-Raphson to refine the value as opposed to subdividing
* until we are within some tolerance
*
* @param x is x-value of cubic bezier curve, in range [0,1]
* @return the parameter t (in range [0,1]) that produces x
*/
private float findTForX(float x) {
// get an initial good guess for t
float t = getInitialGuessForT(x);
// use Newton-Raphson to refine the value for t -- for this constrained
// Bezier with float accuracy (7 digits), any value not converged by 4
// iterations is cycling between values, which can minutely affect the
// accuracy of the last digit
final int numIterations = 4;
for (int i = 0; i < numIterations; ++i) {
// stop if this value of t gives us exactly x
float xT = (eval(t, x1, x2) - x);
if (xT == 0) {
break;
}
// stop if derivative is 0
float dXdT = evalDerivative(t, x1, x2);
if (dXdT == 0) {
break;
}
// refine t
t -= xT / dXdT;
}
return t;
}
}
}
@@ -1,68 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
import java.awt.Color;
import org.gephi.attribute.api.Column;
/**
*
* @author mbastian
*/
public interface Partition {
public Iterable getValues();
public int getElementCount();
public int count(Object value);
public Color getColor(Object value);
public void setColor(Object value, Color color);
public float percentage(Object value);
public int size();
public Column getColumn();
}
@@ -1,51 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
/**
*
* @author mbastian
*/
public interface PartitionFunction extends AttributeFunction {
public Partition getPartition();
}
@@ -1,59 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
/**
*
* @author mbastian
*/
public interface Ranking {
public Number getMinValue();
public Number getMaxValue();
public Interpolator getInterpolator();
public void setInterpolator(Interpolator interpolator);
public float normalize(Number value);
}
@@ -1,51 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
/**
*
* @author mbastian
*/
public interface RankingFunction extends AttributeFunction {
public Ranking getRanking();
}
@@ -1,49 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.api;
/**
*
* @author mbastian
*/
public interface SimpleFunction extends Function {
}
@@ -1,54 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
import org.gephi.appearance.api.Partition;
import org.gephi.graph.api.Element;
/**
*
* @author mbastian
*/
public interface PartitionTransformer<E extends Element> extends Transformer {
public void transform(E element, Partition partition, Object value);
}
@@ -1,54 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
import org.gephi.appearance.api.Ranking;
import org.gephi.graph.api.Element;
/**
*
* @author mbastian
*/
public interface RankingTransformer<E extends Element> extends Transformer {
public void transform(E element, Ranking ranking, Number value);
}
@@ -1,53 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
import org.gephi.graph.api.Element;
/**
*
* @author mbastian
*/
public interface SimpleTransformer<E extends Element> extends Transformer {
public void transform(E element);
}
@@ -1,53 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
/**
*
* @author mbastian
*/
public interface Transformer {
public boolean isNode();
public boolean isEdge();
}
@@ -1,55 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
import javax.swing.Icon;
/**
*
* @author mbastian
*/
public interface TransformerCategory {
public String getDisplayName();
public Icon getIcon();
}
@@ -1,68 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.spi;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
/**
*
* @author mbastian
*/
public interface TransformerUI<T extends Transformer> {
public TransformerCategory getCategory();
public JPanel getPanel(Function function);
public String getDisplayName();
public String getDescription();
public Icon getIcon();
public AbstractButton[] getControlButton();
public Class<? extends T> getTransformerClass();
}
@@ -1,5 +0,0 @@
OpenIDE-Module-Display-Category=Gephi Core
OpenIDE-Module-Long-Description=\
API for the visual appearance of elements
OpenIDE-Module-Name=Appearance API
OpenIDE-Module-Short-Description=API for the visual appearance of elements
@@ -1,81 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import java.awt.Color;
import org.gephi.appearance.api.Partition;
import org.gephi.appearance.plugin.palette.PaletteManager;
import org.gephi.appearance.spi.PartitionTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Element;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class PartitionElementColorTransformer implements PartitionTransformer<Element> {
@Override
public void transform(Element element, Partition partition, Object value) {
Color color = partition.getColor(value);
if (color == null) {
color = Color.BLACK;
}
element.setColor(color);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return true;
}
public PaletteManager getPaletteManager() {
return PaletteManager.getInstance();
}
}
@@ -1,189 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import java.awt.Color;
import java.io.Serializable;
import java.util.Arrays;
import org.gephi.appearance.api.Ranking;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Element;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class RankingElementColorTransformer implements RankingTransformer<Element> {
protected final LinearGradient linearGradient = new LinearGradient(new Color[]{Color.WHITE, Color.BLACK}, new float[]{0f, 1f});
@Override
public void transform(Element element, Ranking ranking, Number value) {
Color color = linearGradient.getValue(ranking.normalize(value));
element.setColor(color);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return true;
}
public float[] getColorPositions() {
return linearGradient.getPositions();
}
public Color[] getColors() {
return linearGradient.getColors();
}
public void setColorPositions(float[] positions) {
linearGradient.setPositions(positions);
}
public void setColors(Color[] colors) {
linearGradient.setColors(colors);
}
public LinearGradient getLinearGradient() {
return linearGradient;
}
public static class LinearGradient implements Serializable, Cloneable {
private Color[] colors;
private float[] positions;
public LinearGradient(Color colors[], float[] positions) {
if (colors == null || positions == null) {
throw new NullPointerException();
}
if (colors.length != positions.length) {
throw new IllegalArgumentException();
}
this.colors = colors;
this.positions = positions;
}
public Color getValue(float pos) {
for (int a = 0; a < positions.length - 1; a++) {
if (positions[a] == pos) {
return colors[a];
}
if (positions[a] < pos && pos < positions[a + 1]) {
float v = (pos - positions[a]) / (positions[a + 1] - positions[a]);
return tween(colors[a], colors[a + 1], v);
}
}
if (pos <= positions[0]) {
return colors[0];
}
if (pos >= positions[positions.length - 1]) {
return colors[colors.length - 1];
}
return null;
}
private Color tween(Color c1, Color c2, float p) {
return new Color(
(int) (c1.getRed() * (1 - p) + c2.getRed() * (p)),
(int) (c1.getGreen() * (1 - p) + c2.getGreen() * (p)),
(int) (c1.getBlue() * (1 - p) + c2.getBlue() * (p)),
(int) (c1.getAlpha() * (1 - p) + c2.getAlpha() * (p)));
}
public Color[] getColors() {
return colors;
}
public float[] getPositions() {
return positions;
}
public void setColors(Color[] colors) {
this.colors = colors;
}
public void setPositions(float[] positions) {
this.positions = positions;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final LinearGradient other = (LinearGradient) obj;
if (!Arrays.deepEquals(this.colors, other.colors)) {
return false;
}
if (!Arrays.equals(this.positions, other.positions)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 3;
hash = 17 * hash + Arrays.deepHashCode(this.colors);
hash = 17 * hash + Arrays.hashCode(this.positions);
return hash;
}
@Override
protected Object clone() throws CloneNotSupportedException {
LinearGradient cl = new LinearGradient(colors, positions);
return cl;
}
}
}
@@ -1,72 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import java.awt.Color;
import org.gephi.appearance.api.Ranking;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Element;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class RankingLabelColorTransformer extends RankingElementColorTransformer {
@Override
public void transform(Element element, Ranking ranking, Number value) {
Color color = linearGradient.getValue(ranking.normalize(value));
element.getTextProperties().setColor(color);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return true;
}
}
@@ -1,92 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import org.gephi.appearance.api.Ranking;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Node;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class RankingNodeSizeTransformer implements RankingTransformer<Node> {
protected float minSize = 1f;
protected float maxSize = 4f;
@Override
public void transform(Node node, Ranking ranking, Number value) {
float rankingValue = ranking.normalize(value);
float size = rankingValue * (maxSize - minSize) + minSize;
node.setSize(size);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return false;
}
public float getMaxSize() {
return maxSize;
}
public float getMinSize() {
return minSize;
}
public void setMaxSize(float maxSize) {
this.maxSize = maxSize;
}
public void setMinSize(float minSize) {
this.minSize = minSize;
}
}
@@ -1,81 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import java.awt.Color;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Element;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class UniqueElementColorTransformer implements SimpleTransformer<Element> {
private Color color = Color.BLACK;
@Override
public void transform(Element element) {
element.setColor(color);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return true;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
@@ -1,80 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.Transformer;
import org.gephi.graph.api.Node;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = Transformer.class)
public class UniqueNodeSizeTransformer implements SimpleTransformer<Node> {
private float size = 10f;
@Override
public void transform(Node node) {
node.setSize(size);
}
@Override
public boolean isNode() {
return true;
}
@Override
public boolean isEdge() {
return false;
}
public float getSize() {
return size;
}
public void setSize(float size) {
this.size = size;
}
}
@@ -1,75 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin.palette;
import java.awt.Color;
/**
*
* @author mbastian
*/
public class Palette {
private final String name;
private final Color[] colors;
public Palette(Color[] colors) {
this(null, colors);
}
public Palette(String name, Color[] colors) {
this.colors = colors;
this.name = name;
}
public Color[] getColors() {
return colors;
}
public String getName() {
return name;
}
public int size() {
return colors.length;
}
}
@@ -1,351 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin.palette;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
/**
*
* @author mbastian
*/
public class PaletteGenerator {
private static final float[] DEFAULT_FILTER = new float[]{0, 360, 0, 3, 0, 1.5f};
public static Color[] generatePalette(int colorsCount, int quality) {
return generatePalette(colorsCount, quality, false, null, null);
}
public static Color[] generatePalette(int colorsCount, int quality, float[] filter) {
return generatePalette(colorsCount, quality, false, null, filter);
}
public static Color[] generatePalette(int colorsCount, int quality, boolean ultraPrecision, Random random, float[] filter) {
if (filter == null) {
filter = DEFAULT_FILTER;
}
if (random == null) {
random = new Random();
}
double[][] kMeans = generateRandomKmeans(colorsCount, random, filter);
List<double[]> colorSamples = new ArrayList<double[]>();
if (ultraPrecision) {
for (double l = 0; l <= 1; l += 0.01) {
for (double a = -1; a <= 1; a += 0.05) {
for (double b = -1; b <= 1; b += 0.05) {
if (checkColor2(l, a, b, filter)) {
colorSamples.add(new double[]{l, a, b});
}
}
}
}
} else {
for (double l = 0; l <= 1; l += 0.05) {
for (double a = -1; a <= 1; a += 0.1) {
for (double b = -1; b <= 1; b += 0.1) {
if (checkColor2(l, a, b, filter)) {
colorSamples.add(new double[]{l, a, b});
}
}
}
}
}
// Steps
int[] samplesClosest = new int[colorSamples.size()];
int steps = quality;
while (steps-- > 0) {
// kMeans -> Samples Closest
for (int i = 0; i < colorSamples.size(); i++) {
double[] lab = colorSamples.get(i);
double minDistance = 1000000;
for (int j = 0; j < kMeans.length; j++) {
double[] kMean = kMeans[j];
double distance = Math.sqrt(Math.pow(lab[0] - kMean[0], 2) + Math.pow(lab[1] - kMean[1], 2) + Math.pow(lab[2] - kMean[2], 2));
if (distance < minDistance) {
minDistance = distance;
samplesClosest[i] = j;
}
}
}
// Samples -> kMeans
List<double[]> freeColorSamples = colorSamples;
for (int j = 0; j < kMeans.length; j++) {
int count = 0;
double[] candidateKMean = new double[]{0, 0, 0};
for (int i = 0; i < colorSamples.size(); i++) {
if (samplesClosest[i] == j) {
count++;
double[] colorSample = colorSamples.get(i);
candidateKMean[0] += colorSample[0];
candidateKMean[1] += colorSample[1];
candidateKMean[2] += colorSample[2];
}
}
if (count != 0) {
candidateKMean[0] /= count;
candidateKMean[1] /= count;
candidateKMean[2] /= count;
}
if (count != 0 && checkColor2(candidateKMean[0], candidateKMean[1], candidateKMean[2], filter)) {
kMeans[j] = candidateKMean;
} else {
// The candidate kMean is out of the boundaries of the color space, or unfound.
if (freeColorSamples.size() > 0) {
// We just search for the closest FREE color of the candidate kMean
double minDistance = 10000000000.0;
int closest = -1;
for (int i = 0; i < freeColorSamples.size(); i++) {
double distance = Math.sqrt(Math.pow(freeColorSamples.get(i)[0] - candidateKMean[0], 2) + Math.pow(freeColorSamples.get(i)[1] - candidateKMean[1], 2) + Math.pow(freeColorSamples.get(i)[2] - candidateKMean[2], 2));
if (distance < minDistance) {
minDistance = distance;
closest = i;
}
}
kMeans[j] = colorSamples.get(closest);
} else {
// Then we just search for the closest color of the candidate kMean
double minDistance = 10000000000.0;
int closest = -1;
for (int i = 0; i < colorSamples.size(); i++) {
double distance = Math.sqrt(Math.pow(colorSamples.get(i)[0] - candidateKMean[0], 2) + Math.pow(colorSamples.get(i)[1] - candidateKMean[1], 2) + Math.pow(colorSamples.get(i)[2] - candidateKMean[2], 2));
if (distance < minDistance) {
minDistance = distance;
closest = i;
}
}
kMeans[j] = colorSamples.get(closest);
}
}
List<double[]> newFreeColorSamples = new ArrayList<double[]>();
for (double[] color : freeColorSamples) {
double[] kMean = kMeans[j];
if (color[0] != kMean[0]
|| color[1] != kMean[1]
|| color[2] != kMean[2]) {
newFreeColorSamples.add(color);
}
}
freeColorSamples = newFreeColorSamples;
}
}
kMeans = sortColors(kMeans);
Color[] res = new Color[kMeans.length];
for (int i = 0; i < kMeans.length; i++) {
double[] kmean = kMeans[i];
int[] rgb = lab2rgb(kmean[0], kmean[1], kmean[2]);
res[i] = new Color(rgb[0], rgb[1], rgb[2]);
}
return res;
}
private static double[][] generateRandomKmeans(int colorsCount, Random random, float[] filter) {
double[][] kMeans = new double[colorsCount][];
for (int i = 0; i < colorsCount; i++) {
double[] lab = new double[]{random.nextDouble(), 2 * random.nextDouble() - 1, 2 * random.nextDouble() - 1};
while (!checkColor2(lab, filter)) {
lab = new double[]{random.nextDouble(), 2 * random.nextDouble() - 1, 2 * random.nextDouble() - 1};
}
kMeans[i] = lab;
}
return kMeans;
}
private static double[][] sortColors(double[][] colors) {
LinkedList<double[]> colorsToSort = new LinkedList<double[]>(Arrays.asList(colors));
List<double[]> diffColors = new ArrayList<double[]>();
diffColors.add(colorsToSort.pop());
while (colorsToSort.size() > 0) {
int index = -1;
double maxDistance = -1;
for (int candidate_index = 0; candidate_index < colorsToSort.size(); candidate_index++) {
double d = 1000000000;
for (int i = 0; i < diffColors.size(); i++) {
double[] colorA = colorsToSort.get(candidate_index);
double[] colorB = diffColors.get(i);
double dl = colorA[0] - colorB[0];
double da = colorA[1] - colorB[1];
double db = colorA[2] - colorB[2];
d = Math.min(d, Math.sqrt(Math.pow(dl, 2) + Math.pow(da, 2) + Math.pow(db, 2)));
}
if (d > maxDistance) {
maxDistance = d;
index = candidate_index;
}
}
double[] color = colorsToSort.get(index);
diffColors.add(color);
colorsToSort.remove(index);
}
double[][] res = new double[diffColors.size()][];
for (int i = 0; i < diffColors.size(); i++) {
res[i] = diffColors.get(i);
}
return res;
}
private static boolean checkColor2(double[] lab, float[] filter) {
return checkColor2(lab[0], lab[1], lab[2], filter);
}
private static boolean checkColor2(double l, double a, double b, float[] filter) {
int[] rgb = lab2rgb(l, a, b);
double[] hcl = lab2hcl(l, a, b);
// Check that a color is valid: it must verify our checkColor condition, but also be in the color space
return !Double.isNaN(rgb[0]) && rgb[0] >= 0 && rgb[1] >= 0
&& rgb[2] >= 0 && rgb[0] < 256 && rgb[1] < 256 && rgb[2] < 256
&& hcl[0] >= filter[0] && hcl[0] <= filter[1]
&& hcl[1] >= filter[2] && hcl[1] <= filter[3]
&& hcl[2] >= filter[4] && hcl[2] <= filter[5];
}
private static int[] lab2rgb(double l, double a, double b) {
double[] xyz = lab2xyz(l, a, b);
return xyz2rgb(xyz[0], xyz[1], xyz[2]);
}
private static double[] lab2xyz(double l, double a, double b) {
double sl = (l + 0.16) / 1.16;
double[] ill = new double[]{0.96421, 1.00000, 0.82519};
double y = ill[1] * finv(sl);
double x = ill[0] * finv(sl + (a / 5.0));
double z = ill[2] * finv(sl - (b / 2.0));
return new double[]{x, y, z};
}
private static int[] xyz2rgb(double x, double y, double z) {
double rl = 3.2406 * x - 1.5372 * y - 0.4986 * z;
double gl = -0.9689 * x + 1.8758 * y + 0.0415 * z;
double bl = 0.0557 * x - 0.2040 * y + 1.0570 * z;
boolean clip = Math.min(rl, Math.min(gl, bl)) < -0.001 || Math.max(rl, Math.max(gl, bl)) > 1.001;
if (clip) {
rl = rl < 0.0 ? 0.0 : rl > 1.0 ? 1.0 : rl;
gl = gl < 0.0 ? 0.0 : gl > 1.0 ? 1.0 : gl;
bl = bl < 0.0 ? 0.0 : bl > 1.0 ? 1.0 : bl;
}
int r = (int) Math.round(255.0 * correct1(rl));
int g = (int) Math.round(255.0 * correct1(gl));
int b = (int) Math.round(255.0 * correct1(bl));
return new int[]{r, g, b};
}
private static double[] rgb2lab(int r, int g, int b) {
double[] xyz = rgb2xyz(r, g, b);
return xyz2lab(xyz[0], xyz[1], xyz[2]);
}
private static double[] rgb2xyz(int r, int g, int b) {
double rl = correct2(r / 255.0);
double gl = correct2(g / 255.0);
double bl = correct2(b / 255.0);
double x = 0.4124 * rl + 0.3576 * gl + 0.1805 * bl;
double y = 0.2126 * rl + 0.7152 * gl + 0.0722 * bl;
double z = 0.0193 * rl + 0.1192 * gl + 0.9505 * bl;
return new double[]{x, y, z};
}
private static double[] xyz2lab(double x, double y, double z) {
double[] ill = new double[]{0.96421, 1.00000, 0.82519};
double l = 1.16 * flab(y / ill[1]) - 0.16;
double a = 5 * (flab(x / ill[0]) - flab(y / ill[1]));
double b = 2 * (flab(y / ill[1]) - flab(z / ill[2]));
return new double[]{l, a, b};
}
private static double[] lab2hcl(double l, double a, double b) {
l = (l - 0.09) / 0.61;
double r = Math.sqrt(a * a + b * b);
double s = r / (l * 0.311 + 0.125);
double TAU = 6.283185307179586476925287;
double angle = Math.atan2(a, b);
double c = (TAU / 6.0 - angle) / TAU;
c *= 360;
if (c < 0) {
c += 360;
}
return new double[]{c, s, l};
}
private static double finv(double t) {
if (t > (6.0 / 29.0)) {
return t * t * t;
} else {
return 3 * (6.0 / 29.0) * (6.0 / 29.0) * (t - 4.0 / 29.0);
}
}
private static double flab(double t) {
if (t > Math.pow(6.0 / 29.0, 3)) {
return Math.pow(t, 1.0 / 3.0);
} else {
return (1.0 / 3.0) * (29.0 / 6.0) * (29.0 / 6.0) * t + 4.0 / 29.0;
}
}
private static double correct1(double cl) {
double a = 0.055;
if (cl <= 0.0031308) {
return 12.92 * cl;
} else {
return (1 + a) * Math.pow(cl, 1.0 / 2.4) - a;
}
}
private static double correct2(double c) {
double a = 0.055;
if (c <= 0.04045) {
return c / 12.92;
} else {
return Math.pow((c + a) / (1.0 + a), 2.4);
}
}
}
@@ -1,214 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin.palette;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.openide.util.Exceptions;
/**
*
* @author mbastian
*/
public class PaletteManager {
private static PaletteManager instance;
public synchronized static PaletteManager getInstance() {
if (instance == null) {
instance = new PaletteManager();
}
return instance;
}
private final static int RECENT_PALETTE_SIZE = 5;
private final List<Preset> presets;
private final Collection<Palette> whiteBackgroundPalette;
private final Collection<Palette> blackBackgroundPalette;
private final LinkedList<Palette> recentPalette;
public PaletteManager() {
presets = loadPresets();
whiteBackgroundPalette = loadWhiteBackgroundPalettes();
blackBackgroundPalette = loadBlackBackgroundPalettes();
recentPalette = new LinkedList<Palette>();
}
public Palette generatePalette(int colorCount) {
return generatePalette(colorCount, null);
}
public Palette generatePalette(int colorCount, Preset preset) {
int quality = 50;
if (colorCount > 50) {
quality = 25;
} else if (colorCount > 100) {
quality = 10;
} else if (colorCount > 200) {
quality = 5;
} else if (colorCount > 300) {
quality = 2;
}
Color[] cls = PaletteGenerator.generatePalette(colorCount, quality, preset.toArray());
return new Palette(cls);
}
public Collection<Preset> getPresets() {
return presets;
}
public Collection<Palette> getWhiteBackgroudPalette(int colorCount) {
List<Palette> palettes = new ArrayList<Palette>();
for (Palette p : whiteBackgroundPalette) {
if (p.size() >= colorCount) {
palettes.add(p);
}
}
return palettes;
}
public Collection<Palette> getBlackBackgroudPalette(int colorCount) {
List<Palette> palettes = new ArrayList<Palette>();
for (Palette p : blackBackgroundPalette) {
if (p.size() >= colorCount) {
palettes.add(p);
}
}
return palettes;
}
public void addRecentPalette(Palette palette) {
if (recentPalette.size() == RECENT_PALETTE_SIZE) {
recentPalette.removeLast();
}
recentPalette.addFirst(palette);
}
public Collection<Palette> getRecentPalettes() {
return recentPalette;
}
private List<Preset> loadPresets() {
List<Preset> presetList = new ArrayList<Preset>();
try {
LineNumberReader reader = new LineNumberReader(new InputStreamReader(PaletteManager.class.getResourceAsStream("palette_presets.csv")));
reader.readLine();
String line;
while ((line = reader.readLine()) != null) {
String[] split = line.split(",");
//name,dark,hmin,hmax,cmin,cmax,lmin,lmax
String name = split[0];
boolean dark = Boolean.parseBoolean(split[1]);
int hMin = Integer.parseInt(split[2]);
int hMax = Integer.parseInt(split[3]);
float cMin = Float.parseFloat(split[4]);
float cMax = Float.parseFloat(split[5]);
float lMin = Float.parseFloat(split[6]);
float lMax = Float.parseFloat(split[7]);
presetList.add(new Preset(name, dark, hMin, hMax, cMin, cMax, lMin, lMax));
}
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return presetList;
}
private static Collection<Palette> loadWhiteBackgroundPalettes() {
try {
return loadPalettes("palette_white_background.csv");
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return Collections.EMPTY_LIST;
}
private static Collection<Palette> loadBlackBackgroundPalettes() {
try {
return loadPalettes("palette_black_background.csv");
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return Collections.EMPTY_LIST;
}
private static Collection<Palette> loadPalettes(String fileName) throws IOException {
List<List<Color>> palettes = new ArrayList<List<Color>>();
LineNumberReader reader = new LineNumberReader(new InputStreamReader(PaletteManager.class.getResourceAsStream(fileName)));
reader.readLine();
String line;
int maxPalette = 32;
while ((line = reader.readLine()) != null) {
String[] split = line.split(",");
for (int i = 0; i < split.length && i < maxPalette; i++) {
String colorStr = split[i];
if (!colorStr.isEmpty()) {
List<Color> palette;
if (palettes.size() <= i) {
palette = new ArrayList<Color>();
palettes.add(palette);
} else {
palette = palettes.get(i);
}
palette.add(parseHexColor(colorStr.trim()));
}
}
}
List<Palette> result = new ArrayList<Palette>();
for (List<Color> cls : palettes) {
Collections.reverse(cls);
Palette plt = new Palette(cls.toArray(new Color[0]));
result.add(plt);
}
return result;
}
private static Color parseHexColor(String hexColor) {
int rgb = Integer.parseInt(hexColor.replaceFirst("#", ""), 16);
return new Color(rgb);
}
}
@@ -1,110 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.appearance.plugin.palette;
/**
*
* @author mbastian
*/
public class Preset {
private final String name;
private final boolean dark;
private final int hMin;
private final int hMax;
private final float cMin;
private final float cMax;
private final float lMin;
private final float lMax;
public Preset(String name, boolean dark, int hMin, int hMax, float cMin, float cMax, float lMin, float lMax) {
this.name = name;
this.dark = dark;
this.hMin = hMin;
this.hMax = hMax;
this.cMin = cMin;
this.cMax = cMax;
this.lMin = lMin;
this.lMax = lMax;
}
public String getName() {
return name;
}
public boolean isDark() {
return dark;
}
public int gethMin() {
return hMin;
}
public int gethMax() {
return hMax;
}
public float getcMin() {
return cMin;
}
public float getcMax() {
return cMax;
}
public float getlMin() {
return lMin;
}
public float getlMax() {
return lMax;
}
public float[] toArray() {
return new float[]{hMin, hMax, cMin, cMax, lMin, lMax};
}
@Override
public String toString() {
return name;
}
}
@@ -1,101 +0,0 @@
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
#82635C ,#597568,#56737C,#8B6685,#557849,#9C5F75,#A06074,#7779A3,#9C7095,#70833B,#AD7AAE,#908B36,#7D444B,#405863,#415F49,#A19A68,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A,#B0959A
,#976253 ,#737339,#68753C,#8B6584,#678644,#518550,#A07434,#618B4A,#8D7199,#589A5A,#A37DAB,#6A9141,#BE7533,#AE81B9,#A890CC,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137,#98C137
,,#9E5E63 ,#9E5F48,#8C6835,#AB6C44,#554F39,#4B7F5C,#9F7536,#B3624F,#BA793E,#355E52,#528C9E,#569555,#CB8340,#C55B65,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C,#D57B3C
,,,#4C7473 ,#4F7480,#61718C,#6A7193,#BB645A,#C2666A,#475D5E,#565363,#D06B7C,#D26D54,#C46C96,#619EB2,#415E6B,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4,#52BDA4
,,,,#A55B5B ,#457768,#AB6247,#664F37,#5C849F,#488664,#5A9087,#C47846,#465A3E,#794638,#61A455,#5FAE62,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4,#CD88D4
,,,,,#5C5030 ,#867631,#925D73,#497E6F,#61532F,#764F38,#569959,#A18336,#8C8B2C,#704A58,#C69133,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A,#E3666A
,,,,,,#4F7B77 ,#4D7078,#55505E,#BC6780,#465F3D,#5E8EAD,#8C84B7,#4A542D,#D16E68,#734B31,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4,#7E98D4
,,,,,,,#697C36 ,#525832,#A47535,#6E8AB0,#515266,#C96D92,#D26763,#A59B3B,#61A3CA,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67,#B99B67
,,,,,,,,#804F43 ,#744C54,#8C8738,#785533,#504E64,#917EB4,#7F5637,#57A78F,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67,#58BD67
,,,,,,,,,#59859F ,#D46C63,#8A585E,#579473,#A08187,#5BA184,#95A736,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434,#CEA434
,,,,,,,,,,#B0697C ,#4B5E30,#744F27,#578FB3,#95908C,#DB7CAF,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C,#D6719C
,,,,,,,,,,,#6D9682 ,#AE7D68,#598D7E,#606729,#465F32,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF,#6FABBF
,,,,,,,,,,,,#987F8B ,#A08054,#486078,#75506C,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E,#8EA24E
,,,,,,,,,,,,,#6C4861 ,#7897D0,#C9908C,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574,#CC8574
,,,,,,,,,,,,,,#CB7599 ,#D17749,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484,#85A484
,,,,,,,,,,,,,,,#949EA4 ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE ,#BF97BE
,,,,,,,,,,,,,,,,#4E3532 ,#4D3745,#423B4D,#29404C,#30321D,#553819,#28433F,#523A19,#6B2E31,#42211A,#66374F,#362837,#713753,#334632,#613C5E,#4D491A,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642,#053642
,,,,,,,,,,,,,,,,,#444020 ,#2F4625,#603225,#593243,#34445A,#673620,#574163,#34491D,#414867,#3B4E17,#2A5120,#3A4C16,#773137,#30541F,#584569,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A,#763B0A
,,,,,,,,,,,,,,,,,,#5C3423 ,#374220,#65391E,#364B1D,#6A374A,#2A4D43,#2E4961,#375022,#2F4A4F,#6C391E,#73371C,#5F430B,#833722,#703235,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A,#91315A
,,,,,,,,,,,,,,,,,,,#56354F ,#2D414F,#233B31,#2A4E22,#384F1F,#664019,#713A57,#603E1A,#222913,#304A48,#573D5F,#1F2C2C,#182726,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14,#405A14
,,,,,,,,,,,,,,,,,,,,#364F23 ,#57324A,#3D435F,#562D38,#2C4C42,#634017,#2E2B15,#71374F,#332B16,#3C1E21,#3F241B,#6F3B18,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C,#2E130C
,,,,,,,,,,,,,,,,,,,,,#622E2F ,#372228,#713326,#222930,#7A2F34,#693030,#284347,#481A1F,#25313A,#4C4319,#5B4547,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42,#075A42
,,,,,,,,,,,,,,,,,,,,,,#403C18 ,#293947,#3C2C19,#273C42,#322536,#4B4A0C,#324A68,#73371C,#394669,#274D3E,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945,#482945
,,,,,,,,,,,,,,,,,,,,,,,#252E17 ,#533E5F,#3F2639,#2C4B31,#404766,#5C4115,#424913,#793139,#3B1B23,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C,#08210C
,,,,,,,,,,,,,,,,,,,,,,,,#5C3445 ,#2E361F,#284968,#482220,#294A2E,#2F4B64,#1E2E0F,#24263B,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441,#804441
,,,,,,,,,,,,,,,,,,,,,,,,,#64403D ,#55456A,#2D4E39,#202A35,#513A1F,#322536,#2B4D1F,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37,#514E37
,,,,,,,,,,,,,,,,,,,,,,,,,,#2C282A ,#594233,#533E5A,#633A45,#2B4D41,#693550,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905,#4C3905
,,,,,,,,,,,,,,,,,,,,,,,,,,,#46441F ,#713938,#212712,#663C19,#2E280F,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A,#4F515A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3B222B ,#2A4E23,#633944,#304A66,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18,#5C2B18
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#26544D ,#314B59,#284A51,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727,#1D1727
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#394C2D ,#573D25,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870,#6F4870
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3E3742 ,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A,#14370A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41,#5B3C41
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237,#732237
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59,#393C59
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13,#1B1A13
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731,#385731
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F,#2E2C0F
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C,#26585C
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53,#743C53
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66,#144C66
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127,#542127
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27,#833A27
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21,#0E3B21
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33,#892E33
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A,#3C202A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B,#00453B
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607,#404607
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24,#524E24
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C,#1B262C
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922,#142922
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B,#60493B
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509,#5E3509
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017,#665017
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68,#594B68
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32,#693E32
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52,#1D5E52
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48,#172D48
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10,#402D10
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543,#5E2543
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00,#1A2A00
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701,#351701
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058,#503058
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60,#843A60
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C,#78491C
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551,#4E5551
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66,#3B4E66
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D,#221A1D
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948,#853948
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212,#3D1212
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706,#2E4706
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C,#1B4F2C
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101,#1A2101
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256,#6A3256
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C,#52490C
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227,#093227
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633,#1C3633
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738,#7E4738
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07,#392F07
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D,#67203D
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409,#734409
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36,#6D2B36
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044,#8B3044
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531,#7B2531
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124,#6A3124
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040,#4C5040
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30,#803F30
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F,#351F2F
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37,#092B37
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D,#27564D
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009,#1D2009
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#6D4053,#6D4053,#6D4053,#6D4053,#6D4053,#6D4053,#6D4053,#6D4053,#6D4053
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#3A223F,#3A223F,#3A223F,#3A223F,#3A223F,#3A223F,#3A223F,#3A223F
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#2D5834,#2D5834,#2D5834,#2D5834,#2D5834,#2D5834,#2D5834
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#0F3E4D,#0F3E4D,#0F3E4D,#0F3E4D,#0F3E4D,#0F3E4D
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#68334D,#68334D,#68334D,#68334D,#68334D
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#2E4A5F,#2E4A5F,#2E4A5F,#2E4A5F
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#43570A,#43570A,#43570A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#2F1507,#2F1507
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#5D4913
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
2 #82635C #597568 #56737C #8B6685 #557849 #9C5F75 #A06074 #7779A3 #9C7095 #70833B #AD7AAE #908B36 #7D444B #405863 #415F49 #A19A68 #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A #B0959A
3 #976253 #737339 #68753C #8B6584 #678644 #518550 #A07434 #618B4A #8D7199 #589A5A #A37DAB #6A9141 #BE7533 #AE81B9 #A890CC #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137 #98C137
4 #9E5E63 #9E5F48 #8C6835 #AB6C44 #554F39 #4B7F5C #9F7536 #B3624F #BA793E #355E52 #528C9E #569555 #CB8340 #C55B65 #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C #D57B3C
5 #4C7473 #4F7480 #61718C #6A7193 #BB645A #C2666A #475D5E #565363 #D06B7C #D26D54 #C46C96 #619EB2 #415E6B #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4 #52BDA4
6 #A55B5B #457768 #AB6247 #664F37 #5C849F #488664 #5A9087 #C47846 #465A3E #794638 #61A455 #5FAE62 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4 #CD88D4
7 #5C5030 #867631 #925D73 #497E6F #61532F #764F38 #569959 #A18336 #8C8B2C #704A58 #C69133 #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A #E3666A
8 #4F7B77 #4D7078 #55505E #BC6780 #465F3D #5E8EAD #8C84B7 #4A542D #D16E68 #734B31 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4 #7E98D4
9 #697C36 #525832 #A47535 #6E8AB0 #515266 #C96D92 #D26763 #A59B3B #61A3CA #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67 #B99B67
10 #804F43 #744C54 #8C8738 #785533 #504E64 #917EB4 #7F5637 #57A78F #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67 #58BD67
11 #59859F #D46C63 #8A585E #579473 #A08187 #5BA184 #95A736 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434 #CEA434
12 #B0697C #4B5E30 #744F27 #578FB3 #95908C #DB7CAF #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C #D6719C
13 #6D9682 #AE7D68 #598D7E #606729 #465F32 #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF #6FABBF
14 #987F8B #A08054 #486078 #75506C #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E #8EA24E
15 #6C4861 #7897D0 #C9908C #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574 #CC8574
16 #CB7599 #D17749 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484 #85A484
17 #949EA4 #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE #BF97BE
18 #4E3532 #4D3745 #423B4D #29404C #30321D #553819 #28433F #523A19 #6B2E31 #42211A #66374F #362837 #713753 #334632 #613C5E #4D491A #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642 #053642
19 #444020 #2F4625 #603225 #593243 #34445A #673620 #574163 #34491D #414867 #3B4E17 #2A5120 #3A4C16 #773137 #30541F #584569 #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A #763B0A
20 #5C3423 #374220 #65391E #364B1D #6A374A #2A4D43 #2E4961 #375022 #2F4A4F #6C391E #73371C #5F430B #833722 #703235 #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A #91315A
21 #56354F #2D414F #233B31 #2A4E22 #384F1F #664019 #713A57 #603E1A #222913 #304A48 #573D5F #1F2C2C #182726 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14 #405A14
22 #364F23 #57324A #3D435F #562D38 #2C4C42 #634017 #2E2B15 #71374F #332B16 #3C1E21 #3F241B #6F3B18 #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C #2E130C
23 #622E2F #372228 #713326 #222930 #7A2F34 #693030 #284347 #481A1F #25313A #4C4319 #5B4547 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42 #075A42
24 #403C18 #293947 #3C2C19 #273C42 #322536 #4B4A0C #324A68 #73371C #394669 #274D3E #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945 #482945
25 #252E17 #533E5F #3F2639 #2C4B31 #404766 #5C4115 #424913 #793139 #3B1B23 #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C #08210C
26 #5C3445 #2E361F #284968 #482220 #294A2E #2F4B64 #1E2E0F #24263B #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441 #804441
27 #64403D #55456A #2D4E39 #202A35 #513A1F #322536 #2B4D1F #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37 #514E37
28 #2C282A #594233 #533E5A #633A45 #2B4D41 #693550 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905 #4C3905
29 #46441F #713938 #212712 #663C19 #2E280F #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A #4F515A
30 #3B222B #2A4E23 #633944 #304A66 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18 #5C2B18
31 #26544D #314B59 #284A51 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727 #1D1727
32 #394C2D #573D25 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870 #6F4870
33 #3E3742 #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A #14370A
34 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41 #5B3C41
35 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237 #732237
36 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59 #393C59
37 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13 #1B1A13
38 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731 #385731
39 #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F #2E2C0F
40 #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C #26585C
41 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53 #743C53
42 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66 #144C66
43 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127 #542127
44 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27 #833A27
45 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21 #0E3B21
46 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33 #892E33
47 #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A #3C202A
48 #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B #00453B
49 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607 #404607
50 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24 #524E24
51 #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C #1B262C
52 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922 #142922
53 #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B #60493B
54 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509 #5E3509
55 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017 #665017
56 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68 #594B68
57 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32 #693E32
58 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52 #1D5E52
59 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48 #172D48
60 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10 #402D10
61 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543 #5E2543
62 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00 #1A2A00
63 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701 #351701
64 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058 #503058
65 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60 #843A60
66 #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C #78491C
67 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551 #4E5551
68 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66 #3B4E66
69 #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D #221A1D
70 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948 #853948
71 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212 #3D1212
72 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706 #2E4706
73 #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C #1B4F2C
74 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101 #1A2101
75 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256 #6A3256
76 #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C #52490C
77 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227 #093227
78 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633 #1C3633
79 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738 #7E4738
80 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07 #392F07
81 #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D #67203D
82 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409 #734409
83 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36 #6D2B36
84 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044 #8B3044
85 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531 #7B2531
86 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124 #6A3124
87 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040 #4C5040
88 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30 #803F30
89 #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F #351F2F
90 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37 #092B37
91 #27564D #27564D #27564D #27564D #27564D #27564D #27564D #27564D #27564D #27564D #27564D
92 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009 #1D2009
93 #6D4053 #6D4053 #6D4053 #6D4053 #6D4053 #6D4053 #6D4053 #6D4053 #6D4053
94 #3A223F #3A223F #3A223F #3A223F #3A223F #3A223F #3A223F #3A223F
95 #2D5834 #2D5834 #2D5834 #2D5834 #2D5834 #2D5834 #2D5834
96 #0F3E4D #0F3E4D #0F3E4D #0F3E4D #0F3E4D #0F3E4D
97 #68334D #68334D #68334D #68334D #68334D
98 #2E4A5F #2E4A5F #2E4A5F #2E4A5F
99 #43570A #43570A #43570A
100 #2F1507 #2F1507
101 #5D4913
@@ -1,18 +0,0 @@
name,dark,hmin,hmax,cmin,cmax,lmin,lmax
Default,FALSE,0,360,0,3,0,1.5
Fancy (light background),FALSE,0,360,0.4,1.2,1,1.5
Fancy (dark background),TRUE,0,360,0.2,1.2,0.1,0.6
Shades,FALSE,0,240,0,0.4,0,1.5
Tarnish,FALSE,0,360,0,0.4,0.4,1.1
Pastel,FALSE,0,360,0,0.9,1,1.5
Pimp,FALSE,0,360,0.9,3,0.4,1
Intense,FALSE,0,360,0.6,3,0.2,1.1
Fluo,TRUE,0,300,1,3,1.1,1.5
Red Roses,TRUE,330,20,0.3,3,0.5,1.5
Ochre Sand,TRUE,20,60,0.3,1.6,0.5,1.5
Yellow Lime,TRUE,60,90,0.3,3,0.5,1.5
Green Mint,TRUE,90,150,0.3,3,0.5,1.5
Ice Cube,TRUE,150,200,0,3,0.5,1.5
Blue Ocean,TRUE,220,260,0.2,2.5,0,0.8
Indigo Night,TRUE,260,290,1.2,3,0.5,1.5
Purple Wine,TRUE,290,330,0,3,0,0.6
1 name dark hmin hmax cmin cmax lmin lmax
2 Default FALSE 0 360 0 3 0 1.5
3 Fancy (light background) FALSE 0 360 0.4 1.2 1 1.5
4 Fancy (dark background) TRUE 0 360 0.2 1.2 0.1 0.6
5 Shades FALSE 0 240 0 0.4 0 1.5
6 Tarnish FALSE 0 360 0 0.4 0.4 1.1
7 Pastel FALSE 0 360 0 0.9 1 1.5
8 Pimp FALSE 0 360 0.9 3 0.4 1
9 Intense FALSE 0 360 0.6 3 0.2 1.1
10 Fluo TRUE 0 300 1 3 1.1 1.5
11 Red Roses TRUE 330 20 0.3 3 0.5 1.5
12 Ochre Sand TRUE 20 60 0.3 1.6 0.5 1.5
13 Yellow Lime TRUE 60 90 0.3 3 0.5 1.5
14 Green Mint TRUE 90 150 0.3 3 0.5 1.5
15 Ice Cube TRUE 150 200 0 3 0.5 1.5
16 Blue Ocean TRUE 220 260 0.2 2.5 0 0.8
17 Indigo Night TRUE 260 290 1.2 3 0.5 1.5
18 Purple Wine TRUE 290 330 0 3 0 0.6
@@ -1,101 +0,0 @@
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100
#AECFAB ,#B8C7D5,#CFD172,#80DCCB,#F0A399,#8CE0A2,#C9C6A3,#D9B965,#9CD580,#88DC95,#CE9D54,#D58876,#C4AB52,#D7A2CF,#D18664,#D3DBA3,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632,#AA8632
,#BCD684 ,#D4B8D3,#DEC96A,#A4E18C,#ECACC6,#D1D062,#9ABCDA,#C1AED2,#D18C9D,#94B8D6,#6DDFC2,#A2ACD3,#D1DA60,#69D8E0,#D484B3,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC,#6593BC
,,#83DEC0 ,#D6B6D3,#C5C0E1,#E2B86E,#DEA6C0,#90D897,#DA9762,#7EBFD2,#95DB8A,#D4DD68,#78E3AD,#64A797,#AEDE7C,#699BAB,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B,#D2708B
,,,#A4E18C ,#7CDDC9,#7DDCD6,#76D9C1,#E59B81,#AECDB9,#D5D96A,#66E0C9,#B6ABD6,#D8897C,#DA8769,#D094BD,#D1953B,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766,#54A766
,,,,#DDCD69 ,#B1C5E4,#9CC2DA,#6DD7CD,#5BDBB3,#D4D1B1,#D296BC,#D6D8A9,#D5D4A5,#D7D5B5,#CBD7C8,#A6DC5C,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A,#7B7C6A
,,,,,#CBDE70 ,#E19F6B,#C7CAB3,#DC939D,#D79064,#D6D864,#78C2D5,#81D6DA,#82A564,#709B65,#DC7468,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC,#BB82BC
,,,,,,#98D988 ,#DCA7C7,#D0C75E,#BAABCF,#CEDFC1,#D6A257,#AFE07C,#74E4AF,#7DE2AB,#5EDEA1,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C,#915E3C
,,,,,,,#C1DA6A ,#73C2D2,#729F88,#D88473,#8DD98A,#D693B4,#C9A457,#8390A9,#899A49,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D,#93A53D
,,,,,,,,#C3B98D ,#6AE0CF,#A3A96C,#71A188,#81A365,#89A2C9,#A1917F,#6D9E7C,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61,#DA6F61
,,,,,,,,,#A0A05B ,#69A390,#9B9E5A,#BFB0AE,#74D6DE,#D6CF93,#BA9092,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593,#539593
,,,,,,,,,,#C2A39F ,#C4BDBA,#6CA493,#D48897,#BC984B,#989DD2,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95,#8A7B95
,,,,,,,,,,,#CE8EAA ,#E0DE61,#A59687,#DBD55C,#D1CED8,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40,#D37F40
,,,,,,,,,,,,#CD925B ,#BDE290,#D2838A,#7ADAD5,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E,#97636E
,,,,,,,,,,,,,#C9C9D9 ,#54A29C,#C19366,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71,#B98F71
,,,,,,,,,,,,,,#BAC1E5 ,#DCD44D,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F,#76823F
,,,,,,,,,,,,,,,#88D379 ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E ,#55865E
,,,,,,,,,,,,,,,,#D0E6BE ,#D3E99E,#E0DBDE,#E1E881,#E0E981,#E4E2B6,#E6E688,#BFEEB8,#F3D5AD,#EAE08A,#E8E589,#DFE4DE,#F0DB7A,#EAE37E,#6AF7F6,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB,#BBDBDB
,,,,,,,,,,,,,,,,,#C9E2E0 ,#DCE896,#DADBE6,#DFDBE6,#E2F07B,#EECEE8,#E7D6E7,#A1EBE3,#DFD2F5,#EDCEEC,#E0EB81,#DFD2F5,#E9CEF5,#ECE379,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A,#FFE57A
,,,,,,,,,,,,,,,,,,#A3EED2 ,#9DEFD1,#9CECE0,#D9DBEA,#9EEFD6,#EAE37E,#C2F192,#89F0D3,#89F1CA,#85F3C4,#85F2C7,#8DF3BA,#E5D1EF,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9,#A9F2A9
,,,,,,,,,,,,,,,,,,,#DAE6AD ,#EDDDAD,#9EEFD6,#F6D4A8,#B8E8E5,#DCD4F0,#A3E4F3,#F3D4B0,#8CECE9,#E0E3C8,#E8E1C9,#A9F0A9,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5,#FBCBF5
,,,,,,,,,,,,,,,,,,,,#BAEFB0 ,#BCEFA0,#B6F0A0,#EDDEB0,#9FF1BC,#EDDCB3,#D0E7E6,#EDCEEC,#B7F09A,#98ECE8,#C1E8EA,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9,#F1C7A9
,,,,,,,,,,,,,,,,,,,,,#EBDF80 ,#C6E1EF,#87F1CE,#EAE37E,#BCEF9C,#91EAEE,#D9E8BA,#B8E6ED,#C2F192,#DEE7B8,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9,#9AF5D9
,,,,,,,,,,,,,,,,,,,,,,#DEE5C3 ,#CAF289,#D5E9BD,#EDDADC,#C2F192,#B4EFA3,#EAE1A5,#C9EDB7,#E8DED2,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499,#C9D499
,,,,,,,,,,,,,,,,,,,,,,,#C5ED9E ,#E0E2DC,#C9EADD,#BFEEB8,#F2D3B6,#C4EEBA,#BDDCF5,#85F2C7,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC,#FDD8DC
,,,,,,,,,,,,,,,,,,,,,,,,#E4E7A6 ,#C4EEBA,#C4DCF5,#BDDCF5,#84EEE7,#F6D4A8,#D0EF93,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B,#E1FB9B
,,,,,,,,,,,,,,,,,,,,,,,,,#E5EE79 ,#E3E6BB,#EAE095,#EED8D9,#ECD2DB,#BCEDCA,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B,#F2CE8B
,,,,,,,,,,,,,,,,,,,,,,,,,,#D8E6D5 ,#BEECDD,#DBEE84,#B6EBD2,#F2DA9F,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF,#D6F9CF
,,,,,,,,,,,,,,,,,,,,,,,,,,,#ADEEC7 ,#B6EBD2,#E4E7A6,#9DDEF6,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB,#FAFAEB
,,,,,,,,,,,,,,,,,,,,,,,,,,,,#96F2AC ,#D9E8E0,#97EBDF,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8,#C7DBF8
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#A3F0C7 ,#87EBF0,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7,#D0D4B7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#76EFDF ,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4,#AEF5F4
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483,#D9D483
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9,#B1DFC9
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1,#92E2B1
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA,#E1E0EA
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE,#D8F6AE
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7,#F5F3B7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0,#DDCDA0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2,#FAF4A2
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0,#FCCBC0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3,#DFD0C3
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6,#A7D4E6
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC,#8AF6EC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B,#B2DC9B
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975,#D8D975
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC,#96DBBC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC,#E8E1FC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3,#E6EFD3
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED,#E0FBED
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A,#F3C99A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092,#DDD092
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E,#BEF09E
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE,#94DECE
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE,#C7FCEE
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986,#C9D986
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED,#FCD2ED
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB,#F0C2CB
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686,#C7E686
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6,#F1D6B6
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B,#98DD9B
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1,#C1D5B1
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0,#A6D6D0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB,#95E8AB
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE,#C5E7EE
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385,#E7D385
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E,#C9D48E
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9,#D1D5D9
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384,#FDE384
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0,#CBFED0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD,#8FEFDD
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7,#DCCAC7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A,#E8EE9A
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC,#D9D7CC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6,#D8FAC6
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7,#E4ECC7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF,#B0FBDF
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0,#F0C3E0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8,#9BE0B8
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0,#BCD8D0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC,#EAD4AC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499,#D5D499
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0,#DEF1E0
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD,#A1ECBD
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8,#DCEFA8
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7,#A5D6D7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9,#F6F2E9
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3,#B0EFF3
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD,#92ECCD
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7,#BCF5A7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789,#CCD789
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B,#F7E37B
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#99E3A7,#99E3A7,#99E3A7,#99E3A7,#99E3A7,#99E3A7,#99E3A7,#99E3A7,#99E3A7
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DECDA5,#DECDA5,#DECDA5,#DECDA5,#DECDA5,#DECDA5,#DECDA5,#DECDA5
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#EAD1AF,#EAD1AF,#EAD1AF,#EAD1AF,#EAD1AF,#EAD1AF,#EAD1AF
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F6F7EF,#F6F7EF,#F6F7EF,#F6F7EF,#F6F7EF,#F6F7EF
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#C7D596,#C7D596,#C7D596,#C7D596,#C7D596
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DFCF81,#DFCF81,#DFCF81,#DFCF81
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DEDA77,#DEDA77,#DEDA77
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#DEDACC,#DEDACC
,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#F5C8F4
1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
2 #AECFAB #B8C7D5 #CFD172 #80DCCB #F0A399 #8CE0A2 #C9C6A3 #D9B965 #9CD580 #88DC95 #CE9D54 #D58876 #C4AB52 #D7A2CF #D18664 #D3DBA3 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632 #AA8632
3 #BCD684 #D4B8D3 #DEC96A #A4E18C #ECACC6 #D1D062 #9ABCDA #C1AED2 #D18C9D #94B8D6 #6DDFC2 #A2ACD3 #D1DA60 #69D8E0 #D484B3 #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC #6593BC
4 #83DEC0 #D6B6D3 #C5C0E1 #E2B86E #DEA6C0 #90D897 #DA9762 #7EBFD2 #95DB8A #D4DD68 #78E3AD #64A797 #AEDE7C #699BAB #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B #D2708B
5 #A4E18C #7CDDC9 #7DDCD6 #76D9C1 #E59B81 #AECDB9 #D5D96A #66E0C9 #B6ABD6 #D8897C #DA8769 #D094BD #D1953B #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766 #54A766
6 #DDCD69 #B1C5E4 #9CC2DA #6DD7CD #5BDBB3 #D4D1B1 #D296BC #D6D8A9 #D5D4A5 #D7D5B5 #CBD7C8 #A6DC5C #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A #7B7C6A
7 #CBDE70 #E19F6B #C7CAB3 #DC939D #D79064 #D6D864 #78C2D5 #81D6DA #82A564 #709B65 #DC7468 #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC #BB82BC
8 #98D988 #DCA7C7 #D0C75E #BAABCF #CEDFC1 #D6A257 #AFE07C #74E4AF #7DE2AB #5EDEA1 #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C #915E3C
9 #C1DA6A #73C2D2 #729F88 #D88473 #8DD98A #D693B4 #C9A457 #8390A9 #899A49 #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D #93A53D
10 #C3B98D #6AE0CF #A3A96C #71A188 #81A365 #89A2C9 #A1917F #6D9E7C #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61 #DA6F61
11 #A0A05B #69A390 #9B9E5A #BFB0AE #74D6DE #D6CF93 #BA9092 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593 #539593
12 #C2A39F #C4BDBA #6CA493 #D48897 #BC984B #989DD2 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95 #8A7B95
13 #CE8EAA #E0DE61 #A59687 #DBD55C #D1CED8 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40 #D37F40
14 #CD925B #BDE290 #D2838A #7ADAD5 #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E #97636E
15 #C9C9D9 #54A29C #C19366 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71 #B98F71
16 #BAC1E5 #DCD44D #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F #76823F
17 #88D379 #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E #55865E
18 #D0E6BE #D3E99E #E0DBDE #E1E881 #E0E981 #E4E2B6 #E6E688 #BFEEB8 #F3D5AD #EAE08A #E8E589 #DFE4DE #F0DB7A #EAE37E #6AF7F6 #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB #BBDBDB
19 #C9E2E0 #DCE896 #DADBE6 #DFDBE6 #E2F07B #EECEE8 #E7D6E7 #A1EBE3 #DFD2F5 #EDCEEC #E0EB81 #DFD2F5 #E9CEF5 #ECE379 #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A #FFE57A
20 #A3EED2 #9DEFD1 #9CECE0 #D9DBEA #9EEFD6 #EAE37E #C2F192 #89F0D3 #89F1CA #85F3C4 #85F2C7 #8DF3BA #E5D1EF #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9 #A9F2A9
21 #DAE6AD #EDDDAD #9EEFD6 #F6D4A8 #B8E8E5 #DCD4F0 #A3E4F3 #F3D4B0 #8CECE9 #E0E3C8 #E8E1C9 #A9F0A9 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5 #FBCBF5
22 #BAEFB0 #BCEFA0 #B6F0A0 #EDDEB0 #9FF1BC #EDDCB3 #D0E7E6 #EDCEEC #B7F09A #98ECE8 #C1E8EA #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9 #F1C7A9
23 #EBDF80 #C6E1EF #87F1CE #EAE37E #BCEF9C #91EAEE #D9E8BA #B8E6ED #C2F192 #DEE7B8 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9 #9AF5D9
24 #DEE5C3 #CAF289 #D5E9BD #EDDADC #C2F192 #B4EFA3 #EAE1A5 #C9EDB7 #E8DED2 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499 #C9D499
25 #C5ED9E #E0E2DC #C9EADD #BFEEB8 #F2D3B6 #C4EEBA #BDDCF5 #85F2C7 #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC #FDD8DC
26 #E4E7A6 #C4EEBA #C4DCF5 #BDDCF5 #84EEE7 #F6D4A8 #D0EF93 #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B #E1FB9B
27 #E5EE79 #E3E6BB #EAE095 #EED8D9 #ECD2DB #BCEDCA #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B #F2CE8B
28 #D8E6D5 #BEECDD #DBEE84 #B6EBD2 #F2DA9F #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF #D6F9CF
29 #ADEEC7 #B6EBD2 #E4E7A6 #9DDEF6 #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB #FAFAEB
30 #96F2AC #D9E8E0 #97EBDF #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8 #C7DBF8
31 #A3F0C7 #87EBF0 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7 #D0D4B7
32 #76EFDF #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4 #AEF5F4
33 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483 #D9D483
34 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9 #B1DFC9
35 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1 #92E2B1
36 #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA #E1E0EA
37 #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE #D8F6AE
38 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7 #F5F3B7
39 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0 #DDCDA0
40 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2 #FAF4A2
41 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0 #FCCBC0
42 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3 #DFD0C3
43 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6 #A7D4E6
44 #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC #8AF6EC
45 #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B #B2DC9B
46 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975 #D8D975
47 #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC #96DBBC
48 #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC #E8E1FC
49 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3 #E6EFD3
50 #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED #E0FBED
51 #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A #F3C99A
52 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092 #DDD092
53 #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E #BEF09E
54 #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE #94DECE
55 #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE #C7FCEE
56 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986 #C9D986
57 #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED #FCD2ED
58 #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB #F0C2CB
59 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686 #C7E686
60 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6 #F1D6B6
61 #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B #98DD9B
62 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1 #C1D5B1
63 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0 #A6D6D0
64 #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB #95E8AB
65 #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE #C5E7EE
66 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385 #E7D385
67 #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E #C9D48E
68 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9 #D1D5D9
69 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384 #FDE384
70 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0 #CBFED0
71 #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD #8FEFDD
72 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7 #DCCAC7
73 #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A #E8EE9A
74 #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC #D9D7CC
75 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6 #D8FAC6
76 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7 #E4ECC7
77 #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF #B0FBDF
78 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0 #F0C3E0
79 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8 #9BE0B8
80 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0 #BCD8D0
81 #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC #EAD4AC
82 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499 #D5D499
83 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0 #DEF1E0
84 #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD #A1ECBD
85 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8 #DCEFA8
86 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7 #A5D6D7
87 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9 #F6F2E9
88 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3 #B0EFF3
89 #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD #92ECCD
90 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7 #BCF5A7
91 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789 #CCD789
92 #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B #F7E37B
93 #99E3A7 #99E3A7 #99E3A7 #99E3A7 #99E3A7 #99E3A7 #99E3A7 #99E3A7 #99E3A7
94 #DECDA5 #DECDA5 #DECDA5 #DECDA5 #DECDA5 #DECDA5 #DECDA5 #DECDA5
95 #EAD1AF #EAD1AF #EAD1AF #EAD1AF #EAD1AF #EAD1AF #EAD1AF
96 #F6F7EF #F6F7EF #F6F7EF #F6F7EF #F6F7EF #F6F7EF
97 #C7D596 #C7D596 #C7D596 #C7D596 #C7D596
98 #DFCF81 #DFCF81 #DFCF81 #DFCF81
99 #DEDA77 #DEDA77 #DEDA77
100 #DEDACC #DEDACC
101 #F5C8F4
@@ -1,72 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-52,0,0,1,28"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="centerScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="viewportView" type="java.awt.Component" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="null"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="backPanel">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="table">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="0" rowCount="0"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="rowHeight" type="int" value="18"/>
<Property name="rowMargin" type="int" value="4"/>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>
@@ -1,428 +0,0 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import net.java.dev.colorchooser.ColorChooser;
import org.gephi.appearance.api.PartitionFunction;
import org.gephi.appearance.plugin.palette.Palette;
import org.gephi.appearance.plugin.palette.PaletteManager;
import org.gephi.ui.appearance.plugin.palette.PaletteGeneratorPanel;
import org.gephi.ui.components.PaletteIcon;
import org.gephi.ui.utils.UIUtils;
import org.jdesktop.swingx.JXHyperlink;
import org.jdesktop.swingx.JXTitledSeparator;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.NbBundle;
/**
*
* @author Mathieu Bastian
*/
public class PartitionColorTransformerPanel extends javax.swing.JPanel {
private PalettePopupButton palettePopupButton;
private PartitionFunction function;
private List<Object> values;
public PartitionColorTransformerPanel() {
initComponents();
palettePopupButton = new PalettePopupButton();
if (UIUtils.isAquaLookAndFeel()) {
backPanel.setBackground(UIManager.getColor("NbExplorerView.background"));
}
}
public JButton getPaletteButton() {
return palettePopupButton;
}
public void setup(PartitionFunction function) {
this.function = function;
NumberFormat formatter = NumberFormat.getPercentInstance();
formatter.setMaximumFractionDigits(2);
values = new ArrayList();
for (Object value : function.getPartition().getValues()) {
values.add(value);
}
Collections.sort(values, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
float p1 = PartitionColorTransformerPanel.this.function.getPartition().percentage(o1);
float p2 = PartitionColorTransformerPanel.this.function.getPartition().percentage(o2);
return p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
}
});
//Model
String[] columnNames = new String[]{"Color", "Partition", "Percentage"};
DefaultTableModel model = new DefaultTableModel(columnNames, values.size()) {
@Override
public boolean isCellEditable(int row, int column) {
return column == 0;
}
};
table.setModel(model);
TableColumn partCol = table.getColumnModel().getColumn(1);
partCol.setCellRenderer(new TextRenderer());
TableColumn percCol = table.getColumnModel().getColumn(2);
percCol.setCellRenderer(new TextRenderer());
percCol.setPreferredWidth(60);
percCol.setMaxWidth(60);
TableColumn colorCol = table.getColumnModel().getColumn(0);
colorCol.setCellEditor(new ColorChooserEditor());
colorCol.setCellRenderer(new ColorChooserRenderer());
colorCol.setPreferredWidth(16);
colorCol.setMaxWidth(16);
for (int j = 0; j < values.size(); j++) {
Object value = values.get(j);
String displayName = value == null ? "null" : value.toString();
float percentage = function.getPartition().percentage(value);
model.setValueAt(value, j, 0);
model.setValueAt(displayName, j, 1);
String perc = "(" + formatter.format(percentage) + ")";
model.setValueAt(perc, j, 2);
}
}
private void applyPalette(Palette palette) {
PaletteManager.getInstance().addRecentPalette(palette);
Color[] colors = palette.getColors();
for (int i = 0; i < values.size(); i++) {
Object val = values.get(i);
Color col = colors[i];
function.getPartition().setColor(val, col);
}
table.revalidate();
table.repaint();
}
private void applyColor(Color col) {
for (int i = 0; i < values.size(); i++) {
Object val = values.get(i);
function.getPartition().setColor(val, col);
}
table.revalidate();
table.repaint();
}
class ColorChooserRenderer extends JLabel implements TableCellRenderer {
public ColorChooserRenderer() {
setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Color c = function.getPartition().getColor(value);
setBackground(c);
return this;
}
}
class TextRenderer extends JLabel implements TableCellRenderer {
private EmptyIcon emptyIcon;
public TextRenderer() {
setFont(table.getFont());
emptyIcon = new EmptyIcon();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setText((String) value);
if (column == 1) {
setIcon(emptyIcon);
} else {
setIcon(null);
}
return this;
}
}
class EmptyIcon implements Icon {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
}
@Override
public int getIconWidth() {
return 6;
}
@Override
public int getIconHeight() {
return 6;
}
}
class ColorChooserEditor extends AbstractCellEditor implements TableCellEditor {
private final ColorChooser delegate;
Object currentValue;
public ColorChooserEditor() {
delegate = new ColorChooser();
delegate.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals(ColorChooser.PROP_COLOR)) {
function.getPartition().setColor(currentValue, (Color) evt.getNewValue());
}
}
});
}
@Override
public Object getCellEditorValue() {
return currentValue;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
int row, int column) {
currentValue = value;
return delegate;
}
}
class PalettePopupButton extends JXHyperlink {
private final PaletteManager paletteManager;
public PalettePopupButton() {
setText(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PartitionColorTransformerPanel.paletteButton"));
setClickedColor(new Color(0, 51, 255));
setFocusPainted(false);
setFocusable(false);
paletteManager = PaletteManager.getInstance();
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int size = function.getPartition().size();
JPopupMenu menu = createPopup(size);
menu.show(PalettePopupButton.this, 0, getHeight());
}
});
}
private JPopupMenu createPopup(final int colorsCount) {
JPopupMenu menu = new JPopupMenu();
menu.add(new JXTitledSeparator(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.recent")));
Collection<Palette> recentPalettes = paletteManager.getRecentPalettes();
if (recentPalettes.isEmpty()) {
menu.add("<html><i>" + NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.norecent") + "</i></html>");
} else {
for (Palette pl : recentPalettes) {
menu.add(new PaletteMenuItem(pl, colorsCount));
}
}
menu.add(new JXTitledSeparator(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.standard")));
JMenu lightPalette = new JMenu(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.light"));
for (Palette pl : paletteManager.getWhiteBackgroudPalette(colorsCount)) {
lightPalette.add(new PaletteMenuItem(pl, colorsCount));
}
menu.add(lightPalette);
JMenu darkPalette = new JMenu(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.dark"));
for (Palette pl : paletteManager.getBlackBackgroudPalette(colorsCount)) {
darkPalette.add(new PaletteMenuItem(pl, colorsCount));
}
menu.add(darkPalette);
JMenuItem allBlack = new JMenuItem(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.allblack"));
allBlack.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyColor(Color.BLACK);
}
});
menu.add(allBlack);
JMenuItem allWhite = new JMenuItem(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.allwhite"));
allWhite.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyColor(Color.WHITE);
}
});
menu.add(allWhite);
JMenuItem generate = new JMenuItem(NbBundle.getMessage(PartitionColorTransformerPanel.class, "PalettePopup.generate"));
generate.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
PaletteGeneratorPanel pgn = new PaletteGeneratorPanel();
pgn.setup(colorsCount);
NotifyDescriptor nd = new NotifyDescriptor(pgn,
NbBundle.getMessage(PartitionColorTransformerPanel.class, "PartitionColorTransformerPanel.generatePalettePanel.title"),
NotifyDescriptor.OK_CANCEL_OPTION,
NotifyDescriptor.DEFAULT_OPTION, null, null);
if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.OK_OPTION) {
Palette pl = pgn.getSelectedPalette();
if (pl != null) {
applyPalette(pl);
}
}
}
});
menu.add(generate);
return menu;
}
}
class PaletteMenuItem extends JMenuItem implements ActionListener {
private final Palette palette;
public PaletteMenuItem(Palette palette, int max) {
super(new PaletteIcon(palette.getColors(), max));
this.palette = palette;
addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
applyPalette(palette);
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
centerScrollPane = new javax.swing.JScrollPane();
backPanel = new javax.swing.JPanel();
table = new javax.swing.JTable();
setOpaque(false);
setLayout(new java.awt.GridBagLayout());
centerScrollPane.setBorder(null);
centerScrollPane.setOpaque(false);
centerScrollPane.setViewportView(null);
backPanel.setLayout(new java.awt.GridBagLayout());
table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
table.setOpaque(false);
table.setRowHeight(18);
table.setRowMargin(4);
table.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
table.setShowHorizontalLines(false);
table.setShowVerticalLines(false);
table.setTableHeader(null);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
backPanel.add(table, gridBagConstraints);
centerScrollPane.setViewportView(backPanel);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(4, 10, 0, 0);
add(centerScrollPane, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel backPanel;
private javax.swing.JScrollPane centerScrollPane;
private javax.swing.JTable table;
// End of variables declaration//GEN-END:variables
}
@@ -1,107 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.PartitionFunction;
import org.gephi.appearance.plugin.PartitionElementColorTransformer;
import org.gephi.appearance.spi.PartitionTransformer;
import org.gephi.appearance.spi.TransformerCategory;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.ui.appearance.plugin.category.DefaultCategory;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = TransformerUI.class, position = 200)
public class PartitionElementColorTransformerUI implements TransformerUI {
private PartitionColorTransformerPanel panel;
@Override
public TransformerCategory getCategory() {
return DefaultCategory.COLOR;
}
@Override
public String getDisplayName() {
return NbBundle.getMessage(UniqueElementColorTransformerUI.class, "Attribute.name");
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String getDescription() {
return null;
}
@Override
public synchronized JPanel getPanel(Function function) {
if (panel == null) {
panel = new PartitionColorTransformerPanel();
}
panel.setup((PartitionFunction) function);
return panel;
}
@Override
public synchronized AbstractButton[] getControlButton() {
if (panel == null) {
panel = new PartitionColorTransformerPanel();
}
return new AbstractButton[]{panel.getPaletteButton()};
}
@Override
public Class<? extends PartitionTransformer> getTransformerClass() {
return PartitionElementColorTransformer.class;
}
}
@@ -1,93 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[225, 114]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="labelColor" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="gradientPanel" min="-2" pref="160" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="colorSwatchToolbar" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="colorSwatchToolbar" alignment="0" min="-2" pref="22" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Component id="labelColor" min="-2" pref="20" max="-2" attributes="1"/>
<Component id="gradientPanel" min="-2" pref="17" max="-2" attributes="1"/>
</Group>
</Group>
</Group>
<EmptySpace pref="88" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelColor">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/Bundle.properties" key="RankingColorTransformerPanel.labelColor.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JPanel" name="gradientPanel">
<Properties>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
</Container>
<Container class="javax.swing.JToolBar" name="colorSwatchToolbar">
<Properties>
<Property name="floatable" type="boolean" value="false"/>
<Property name="rollover" type="boolean" value="true"/>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<SubComponents>
<Component class="javax.swing.JButton" name="colorSwatchButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/gephi/ui/appearance/plugin/resources/color-swatch.png"/>
</Property>
<Property name="focusable" type="boolean" value="false"/>
<Property name="horizontalTextPosition" type="int" value="0"/>
<Property name="iconTextGap" type="int" value="0"/>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 0, 0, 0]"/>
</Property>
<Property name="verticalTextPosition" type="int" value="3"/>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>
@@ -1,340 +0,0 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.appearance.api.RankingFunction;
import org.gephi.appearance.plugin.RankingElementColorTransformer;
import org.gephi.ui.components.PaletteIcon;
import org.gephi.ui.components.gradientslider.GradientSlider;
import org.gephi.utils.PaletteUtils;
import org.gephi.utils.PaletteUtils.Palette;
import org.openide.util.NbBundle;
import org.openide.util.NbPreferences;
/**
* @author Mathieu Bastian
*/
public class RankingColorTransformerPanel extends javax.swing.JPanel {
private RankingElementColorTransformer colorTransformer;
private GradientSlider gradientSlider;
private final RecentPalettes recentPalettes;
public RankingColorTransformerPanel() {
initComponents();
this.recentPalettes = new RecentPalettes();
}
public void setup(RankingFunction function) {
colorTransformer = (RankingElementColorTransformer) function.getTransformer();
final String POSITIONS = "RankingColorTransformerPanel_" + colorTransformer.getClass().getSimpleName() + "_positions";
final String COLORS = "RankingColorTransformerPanel_" + colorTransformer.getClass().getSimpleName() + "_colors";
float[] positionsStart = colorTransformer.getColorPositions();
Color[] colorsStart = colorTransformer.getColors();
try {
positionsStart = deserializePositions(NbPreferences.forModule(RankingColorTransformerPanel.class).getByteArray(POSITIONS, serializePositions(positionsStart)));
colorsStart = deserializeColors(NbPreferences.forModule(RankingColorTransformerPanel.class).getByteArray(COLORS, serializeColors(colorsStart)));
colorTransformer.setColorPositions(positionsStart);
colorTransformer.setColors(colorsStart);
} catch (Exception e) {
e.printStackTrace();
}
//Gradient
gradientSlider = new GradientSlider(GradientSlider.HORIZONTAL, positionsStart, colorsStart);
gradientSlider.putClientProperty("GradientSlider.includeOpacity", "false");
gradientSlider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
Color[] colors = gradientSlider.getColors();
float[] positions = gradientSlider.getThumbPositions();
colorTransformer.setColors(Arrays.copyOf(colors, colors.length));
colorTransformer.setColorPositions(Arrays.copyOf(positions, positions.length));
try {
NbPreferences.forModule(RankingColorTransformerPanel.class).putByteArray(POSITIONS, serializePositions(positions));
NbPreferences.forModule(RankingColorTransformerPanel.class).putByteArray(COLORS, serializeColors(colors));
} catch (Exception ex) {
ex.printStackTrace();
}
// prepareGradientTooltip();
}
});
gradientPanel.add(gradientSlider, BorderLayout.CENTER);
// prepareGradientTooltip();
//Context
// setComponentPopupMenu(getPalettePopupMenu());
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent evt) {
if (evt.isPopupTrigger()) {
JPopupMenu popupMenu = getPalettePopupMenu();
popupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
@Override
public void mouseReleased(MouseEvent evt) {
if (evt.isPopupTrigger()) {
JPopupMenu popupMenu = getPalettePopupMenu();
popupMenu.show(evt.getComponent(), evt.getX(), evt.getY());
}
}
});
//Color Swatch
colorSwatchButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JPopupMenu popupMenu = getPalettePopupMenu();
popupMenu.show(colorSwatchToolbar, -popupMenu.getPreferredSize().width, 0);
}
});
}
// private void prepareGradientTooltip() {
// StringBuilder sb = new StringBuilder();
// final double min = ((Number) ranking.unNormalize(colorTransformer.getLowerBound())).doubleValue();
// final double max = ((Number) ranking.unNormalize(colorTransformer.getUpperBound())).doubleValue();
// final double range = max - min;
// float[] positions = gradientSlider.getThumbPositions();
// for (int i = 0; i < positions.length - 1; i++) {
// sb.append(min + range * positions[i]);
// sb.append(", ");
// }
// sb.append(min + range * positions[positions.length - 1]);
// gradientSlider.setToolTipText(sb.toString());
// }
private JPopupMenu getPalettePopupMenu() {
JPopupMenu popupMenu = new JPopupMenu();
JMenu defaultMenu = new JMenu(NbBundle.getMessage(RankingColorTransformerPanel.class, "PalettePopup.default"));
for (Palette p : PaletteUtils.getSequencialPalettes()) {
final Palette p3 = PaletteUtils.get3ClassPalette(p);
JMenuItem item = new JMenuItem(new PaletteIcon(p3.getColors()));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gradientSlider.setValues(p3.getPositions(), p3.getColors());
}
});
defaultMenu.add(item);
}
for (Palette p : PaletteUtils.getDivergingPalettes()) {
final Palette p3 = PaletteUtils.get3ClassPalette(p);
JMenuItem item = new JMenuItem(new PaletteIcon(p3.getColors()));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gradientSlider.setValues(p3.getPositions(), p3.getColors());
}
});
defaultMenu.add(item);
}
popupMenu.add(defaultMenu);
//Invert
JMenuItem invertItem = new JMenuItem(NbBundle.getMessage(RankingColorTransformerPanel.class, "PalettePopup.invert"));
invertItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gradientSlider.setValues(invert(gradientSlider.getThumbPositions()), invert(gradientSlider.getColors()));
}
});
popupMenu.add(invertItem);
//Recent
JMenu recentMenu = new JMenu(NbBundle.getMessage(RankingColorTransformerPanel.class, "PalettePopup.recent"));
for (final RankingElementColorTransformer.LinearGradient gradient : recentPalettes.getPalettes()) {
JMenuItem item = new JMenuItem(new PaletteIcon(gradient.getColors()));
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
gradientSlider.setValues(gradient.getPositions(), gradient.getColors());
}
});
recentMenu.add(item);
}
popupMenu.add(recentMenu);
return popupMenu;
}
private void addRecentPalette() {
RankingElementColorTransformer.LinearGradient gradient = colorTransformer.getLinearGradient();
recentPalettes.add(gradient);
}
private Color[] invert(Color[] source) {
int len = source.length;
Color[] res = new Color[len];
for (int i = 0; i < len; i++) {
res[i] = source[len - 1 - i];
}
return res;
}
private float[] invert(float[] source) {
int len = source.length;
float[] res = new float[len];
for (int i = 0; i < len; i++) {
res[i] = 1 - source[len - 1 - i];
}
return res;
}
private byte[] serializePositions(float[] positions) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(positions);
out.close();
return bos.toByteArray();
}
private float[] deserializePositions(byte[] positions) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(positions);
ObjectInputStream in = new ObjectInputStream(bis);
float[] array = (float[]) in.readObject();
in.close();
return array;
}
private byte[] serializeColors(Color[] colors) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(colors);
out.close();
return bos.toByteArray();
}
private Color[] deserializeColors(byte[] colors) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(colors);
ObjectInputStream in = new ObjectInputStream(bis);
Color[] array = (Color[]) in.readObject();
in.close();
return array;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
labelColor = new javax.swing.JLabel();
gradientPanel = new javax.swing.JPanel();
colorSwatchToolbar = new javax.swing.JToolBar();
colorSwatchButton = new javax.swing.JButton();
setPreferredSize(new java.awt.Dimension(225, 114));
labelColor.setText(org.openide.util.NbBundle.getMessage(RankingColorTransformerPanel.class, "RankingColorTransformerPanel.labelColor.text")); // NOI18N
gradientPanel.setOpaque(false);
gradientPanel.setLayout(new java.awt.BorderLayout());
colorSwatchToolbar.setFloatable(false);
colorSwatchToolbar.setRollover(true);
colorSwatchToolbar.setOpaque(false);
colorSwatchButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/gephi/ui/appearance/plugin/resources/color-swatch.png"))); // NOI18N
colorSwatchButton.setFocusable(false);
colorSwatchButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
colorSwatchButton.setIconTextGap(0);
colorSwatchButton.setMargin(new java.awt.Insets(0, 0, 0, 0));
colorSwatchButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
colorSwatchToolbar.add(colorSwatchButton);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(labelColor)
.addGap(18, 18, 18)
.addComponent(gradientPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 160, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(colorSwatchToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(colorSwatchToolbar, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(labelColor, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(gradientPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE))))
.addContainerGap(88, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton colorSwatchButton;
private javax.swing.JToolBar colorSwatchToolbar;
private javax.swing.JPanel gradientPanel;
private javax.swing.JLabel labelColor;
// End of variables declaration//GEN-END:variables
}
@@ -1,104 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.RankingFunction;
import org.gephi.appearance.plugin.RankingElementColorTransformer;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.TransformerCategory;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.ui.appearance.plugin.category.DefaultCategory;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = TransformerUI.class, position = 200)
public class RankingElementColorTransformerUI implements TransformerUI {
private RankingColorTransformerPanel panel;
@Override
public TransformerCategory getCategory() {
return DefaultCategory.COLOR;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String getDisplayName() {
return NbBundle.getMessage(UniqueElementColorTransformerUI.class, "Attribute.name");
}
@Override
public String getDescription() {
return null;
}
@Override
public synchronized JPanel getPanel(Function function) {
if (panel == null) {
panel = new RankingColorTransformerPanel();
}
panel.setup((RankingFunction) function);
return panel;
}
@Override
public synchronized AbstractButton[] getControlButton() {
return null;
}
@Override
public Class<? extends RankingTransformer> getTransformerClass() {
return RankingElementColorTransformer.class;
}
}
@@ -1,104 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.RankingFunction;
import org.gephi.appearance.plugin.RankingNodeSizeTransformer;
import org.gephi.appearance.spi.RankingTransformer;
import org.gephi.appearance.spi.TransformerCategory;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.ui.appearance.plugin.category.DefaultCategory;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = TransformerUI.class, position = 300)
public class RankingElementSizeTransformerUI implements TransformerUI {
private RankingSizeTransformerPanel panel;
@Override
public TransformerCategory getCategory() {
return DefaultCategory.SIZE;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String getDisplayName() {
return NbBundle.getMessage(UniqueElementColorTransformerUI.class, "Attribute.name");
}
@Override
public String getDescription() {
return null;
}
@Override
public synchronized JPanel getPanel(Function function) {
if (panel == null) {
panel = new RankingSizeTransformerPanel();
}
panel.setup((RankingFunction) function);
return panel;
}
@Override
public synchronized AbstractButton[] getControlButton() {
return null;
}
@Override
public Class<? extends RankingTransformer> getTransformerClass() {
return RankingNodeSizeTransformer.class;
}
}
@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[225, 114]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="labelMinSize" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="minSize" min="-2" pref="55" max="-2" attributes="1"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="labelMaxSize" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="maxSize" min="-2" pref="55" max="-2" attributes="1"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="minSize" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="maxSize" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelMaxSize" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="labelMinSize" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="80" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelMinSize">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/Bundle.properties" key="RankingSizeTransformerPanel.labelMinSize.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="minSize">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="1.0" minimum="0.1" numberType="java.lang.Float" stepSize="0.5" type="number"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="labelMaxSize">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/Bundle.properties" key="RankingSizeTransformerPanel.labelMaxSize.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="maxSize">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="4.0" minimum="0.5" numberType="java.lang.Float" stepSize="0.5" type="number"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -1,148 +0,0 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.appearance.api.RankingFunction;
import org.gephi.appearance.plugin.RankingNodeSizeTransformer;
import org.openide.util.NbPreferences;
/**
*
* @author Mathieu Bastian
*/
public class RankingSizeTransformerPanel extends javax.swing.JPanel {
private RankingNodeSizeTransformer sizeTransformer;
public RankingSizeTransformerPanel() {
initComponents();
}
public void setup(RankingFunction function) {
sizeTransformer = (RankingNodeSizeTransformer) function.getTransformer();
final String MIN_SIZE = "RankingSizeTransformerPanel_" + sizeTransformer.getClass().getSimpleName() + "_min";
final String MAX_SIZE = "RankingSizeTransformerPanel_" + sizeTransformer.getClass().getSimpleName() + "_max";
float minSizeStart = NbPreferences.forModule(RankingSizeTransformerPanel.class).getFloat(MIN_SIZE, sizeTransformer.getMinSize());
float maxSizeStart = NbPreferences.forModule(RankingSizeTransformerPanel.class).getFloat(MAX_SIZE, sizeTransformer.getMaxSize());
sizeTransformer.setMinSize(minSizeStart);
sizeTransformer.setMaxSize(maxSizeStart);
minSize.setValue(minSizeStart);
maxSize.setValue(maxSizeStart);
minSize.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
sizeTransformer.setMinSize((Float) minSize.getValue());
NbPreferences.forModule(RankingSizeTransformerPanel.class).putFloat(MIN_SIZE, (Float) minSize.getValue());
}
});
maxSize.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
sizeTransformer.setMaxSize((Float) maxSize.getValue());
NbPreferences.forModule(RankingSizeTransformerPanel.class).putFloat(MAX_SIZE, (Float) maxSize.getValue());
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
labelMinSize = new javax.swing.JLabel();
minSize = new javax.swing.JSpinner();
labelMaxSize = new javax.swing.JLabel();
maxSize = new javax.swing.JSpinner();
setPreferredSize(new java.awt.Dimension(225, 114));
labelMinSize.setText(org.openide.util.NbBundle.getMessage(RankingSizeTransformerPanel.class, "RankingSizeTransformerPanel.labelMinSize.text")); // NOI18N
minSize.setModel(new javax.swing.SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), null, Float.valueOf(0.5f)));
labelMaxSize.setText(org.openide.util.NbBundle.getMessage(RankingSizeTransformerPanel.class, "RankingSizeTransformerPanel.labelMaxSize.text")); // NOI18N
maxSize.setModel(new javax.swing.SpinnerNumberModel(Float.valueOf(4.0f), Float.valueOf(0.5f), null, Float.valueOf(0.5f)));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(labelMinSize)
.addGap(8, 8, 8)
.addComponent(minSize, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(labelMaxSize)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(maxSize, javax.swing.GroupLayout.PREFERRED_SIZE, 55, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(minSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(maxSize, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(labelMaxSize)
.addComponent(labelMinSize))
.addContainerGap(80, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel labelMaxSize;
private javax.swing.JLabel labelMinSize;
private javax.swing.JSpinner maxSize;
private javax.swing.JSpinner minSize;
// End of variables declaration//GEN-END:variables
}
@@ -1,182 +0,0 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import java.awt.Color;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import org.gephi.appearance.plugin.RankingElementColorTransformer.LinearGradient;
import org.openide.util.NbPreferences;
/**
*
* @author Mathieu Bastian
*/
public class RecentPalettes {
protected static String DEFAULT_NODE_NAME = "prefs";
public static final String COLORS = "PaletteColors";
public static final String POSITIONS = "PalettePositions";
private List<LinearGradient> gradients;
private int maxSize;
protected String nodeName = null;
public RecentPalettes() {
nodeName = "recentpalettes";
maxSize = 14;
gradients = new ArrayList<LinearGradient>(maxSize);
retrieve();
}
public void add(LinearGradient gradient) {
//Remove the old
gradients.remove(gradient);
// add to the top
gradients.add(0, gradient);
while (gradients.size() > maxSize) {
gradients.remove(gradients.size() - 1);
}
store();
}
public LinearGradient[] getPalettes() {
return gradients.toArray(new LinearGradient[0]);
}
protected void store() {
Preferences prefs = getPreferences();
// clear the backing store
try {
prefs.clear();
} catch (BackingStoreException ex) {
}
for (int i = 0; i < gradients.size(); i++) {
LinearGradient gradient = gradients.get(i);
try {
prefs.putByteArray(COLORS + i, serializeColors(gradient.getColors()));
prefs.putByteArray(POSITIONS + i, serializePositions(gradient.getPositions()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void retrieve() {
gradients.clear();
Preferences prefs = getPreferences();
for (int i = 0; i < maxSize; i++) {
byte[] cols = prefs.getByteArray(COLORS + i, null);
byte[] poss = prefs.getByteArray(POSITIONS + i, null);
if (cols != null && poss != null) {
try {
Color[] colors = deserializeColors(cols);
float[] posisitons = deserializePositions(poss);
LinearGradient linearGradient = new LinearGradient(colors, posisitons);
gradients.add(linearGradient);
} catch (Exception e) {
e.printStackTrace();
}
} else {
break;
}
}
}
/**
* Return the backing store Preferences
*
* @return Preferences
*/
protected final Preferences getPreferences() {
String name = DEFAULT_NODE_NAME;
if (nodeName != null) {
name = nodeName;
}
Preferences prefs = NbPreferences.forModule(this.getClass()).node("options").node(name);
return prefs;
}
private byte[] serializePositions(float[] positions) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(positions);
out.close();
return bos.toByteArray();
}
private float[] deserializePositions(byte[] positions) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(positions);
ObjectInputStream in = new ObjectInputStream(bis);
float[] array = (float[]) in.readObject();
in.close();
return array;
}
private byte[] serializeColors(Color[] colors) throws Exception {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(colors);
out.close();
return bos.toByteArray();
}
private Color[] deserializeColors(byte[] colors) throws Exception {
ByteArrayInputStream bis = new ByteArrayInputStream(colors);
ObjectInputStream in = new ObjectInputStream(bis);
Color[] array = (Color[]) in.readObject();
in.close();
return array;
}
}
@@ -1,71 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="colorChooser" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="colorLabel" min="-2" pref="380" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="colorLabel" min="-2" max="-2" attributes="0"/>
<Component id="colorChooser" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="278" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="net.java.dev.colorchooser.ColorChooser" name="colorChooser">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[14, 14]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[14, 14]"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/Bundle.properties" key="UniqueColorTransformerPanel.colorChooser.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="12" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="12" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Container>
<Component class="javax.swing.JLabel" name="colorLabel">
</Component>
</SubComponents>
</Form>
@@ -1,136 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.gephi.appearance.api.SimpleFunction;
import org.gephi.appearance.plugin.UniqueElementColorTransformer;
/**
*
* @author mbastian
*/
public class UniqueColorTransformerPanel extends javax.swing.JPanel {
private UniqueElementColorTransformer transformer;
/**
* Creates new form UniqueNodeColorTransformerPanel
*/
public UniqueColorTransformerPanel() {
initComponents();
colorChooser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
transformer.setColor(colorChooser.getColor());
colorLabel.setText(getHex(colorChooser.getColor()));
}
});
}
public void setup(SimpleFunction function) {
transformer = (UniqueElementColorTransformer) function.getTransformer();
colorChooser.setColor(transformer.getColor());
colorLabel.setText(getHex(transformer.getColor()));
}
private String getHex(Color color) {
return "#" + String.format("%06x", color.getRGB() & 0x00FFFFFF);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
colorChooser = new net.java.dev.colorchooser.ColorChooser();
colorLabel = new javax.swing.JLabel();
colorChooser.setMinimumSize(new java.awt.Dimension(14, 14));
colorChooser.setPreferredSize(new java.awt.Dimension(14, 14));
colorChooser.setToolTipText(org.openide.util.NbBundle.getMessage(UniqueColorTransformerPanel.class, "UniqueColorTransformerPanel.colorChooser.toolTipText")); // NOI18N
javax.swing.GroupLayout colorChooserLayout = new javax.swing.GroupLayout(colorChooser);
colorChooser.setLayout(colorChooserLayout);
colorChooserLayout.setHorizontalGroup(
colorChooserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 12, Short.MAX_VALUE)
);
colorChooserLayout.setVerticalGroup(
colorChooserLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 12, Short.MAX_VALUE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(colorLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 380, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(colorLabel)
.addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(278, 278, 278))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private net.java.dev.colorchooser.ColorChooser colorChooser;
private javax.swing.JLabel colorLabel;
// End of variables declaration//GEN-END:variables
}
@@ -1,104 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.SimpleFunction;
import org.gephi.appearance.plugin.UniqueElementColorTransformer;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.TransformerCategory;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.ui.appearance.plugin.category.DefaultCategory;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = TransformerUI.class, position = 100)
public class UniqueElementColorTransformerUI implements TransformerUI {
private UniqueColorTransformerPanel panel;
@Override
public String getDisplayName() {
return NbBundle.getMessage(UniqueElementColorTransformerUI.class, "Unique.name");
}
@Override
public TransformerCategory getCategory() {
return DefaultCategory.COLOR;
}
@Override
public String getDescription() {
return null;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public synchronized JPanel getPanel(Function function) {
if (panel == null) {
panel = new UniqueColorTransformerPanel();
}
panel.setup((SimpleFunction) function);
return panel;
}
@Override
public synchronized AbstractButton[] getControlButton() {
return null;
}
@Override
public Class<? extends SimpleTransformer> getTransformerClass() {
return UniqueElementColorTransformer.class;
}
}
@@ -1,104 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.AbstractButton;
import javax.swing.Icon;
import javax.swing.JPanel;
import org.gephi.appearance.api.Function;
import org.gephi.appearance.api.SimpleFunction;
import org.gephi.appearance.plugin.UniqueNodeSizeTransformer;
import org.gephi.appearance.spi.SimpleTransformer;
import org.gephi.appearance.spi.TransformerCategory;
import org.gephi.appearance.spi.TransformerUI;
import org.gephi.ui.appearance.plugin.category.DefaultCategory;
import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author mbastian
*/
@ServiceProvider(service = TransformerUI.class, position = 100)
public class UniqueNodeSizeTransformerUI implements TransformerUI {
private UniqueSizeTransformerPanel panel;
@Override
public String getDisplayName() {
return NbBundle.getMessage(UniqueElementColorTransformerUI.class, "Unique.name");
}
@Override
public TransformerCategory getCategory() {
return DefaultCategory.SIZE;
}
@Override
public String getDescription() {
return null;
}
@Override
public Icon getIcon() {
return null;
}
@Override
public synchronized JPanel getPanel(Function function) {
if (panel == null) {
panel = new UniqueSizeTransformerPanel();
}
panel.setup((SimpleFunction) function);
return panel;
}
@Override
public synchronized AbstractButton[] getControlButton() {
return null;
}
@Override
public Class<? extends SimpleTransformer> getTransformerClass() {
return UniqueNodeSizeTransformer.class;
}
}
@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jLabel1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="sizeSpinner" min="-2" max="-2" attributes="1"/>
<EmptySpace pref="294" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="sizeSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="266" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/Bundle.properties" key="UniqueSizeTransformerPanel.jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JSpinner" name="sizeSpinner">
<Properties>
<Property name="model" type="javax.swing.SpinnerModel" editor="org.netbeans.modules.form.editors2.SpinnerModelEditor">
<SpinnerModel initial="1.0" minimum="0.1" numberType="java.lang.Float" stepSize="0.5" type="number"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>
@@ -1,114 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.appearance.api.SimpleFunction;
import org.gephi.appearance.plugin.UniqueNodeSizeTransformer;
/**
*
* @author mbastian
*/
public class UniqueSizeTransformerPanel extends javax.swing.JPanel {
private UniqueNodeSizeTransformer transformer;
public UniqueSizeTransformerPanel() {
initComponents();
sizeSpinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
transformer.setSize((Float) sizeSpinner.getValue());
}
});
}
public void setup(SimpleFunction function) {
transformer = (UniqueNodeSizeTransformer) function.getTransformer();
sizeSpinner.setValue(transformer.getSize());
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
jLabel1 = new javax.swing.JLabel();
sizeSpinner = new javax.swing.JSpinner();
jLabel1.setText(org.openide.util.NbBundle.getMessage(UniqueSizeTransformerPanel.class, "UniqueSizeTransformerPanel.jLabel1.text")); // NOI18N
sizeSpinner.setModel(new javax.swing.SpinnerNumberModel(Float.valueOf(1.0f), Float.valueOf(0.1f), null, Float.valueOf(0.5f)));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(sizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(294, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jLabel1)
.addComponent(sizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(266, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel jLabel1;
private javax.swing.JSpinner sizeSpinner;
// End of variables declaration//GEN-END:variables
}
@@ -1,87 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin.category;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import org.gephi.appearance.spi.TransformerCategory;
import org.openide.util.NbBundle;
/**
*
* @author mbastian
*/
public class DefaultCategory {
public static TransformerCategory SIZE = new TransformerCategory() {
@Override
public String getDisplayName() {
return NbBundle.getMessage(DefaultCategory.class, "Category.Size.name");
}
@Override
public Icon getIcon() {
return new ImageIcon(getClass().getResource("/org/gephi/ui/appearance/plugin/resources/size.png"));
}
@Override
public String toString() {
return "SIZE";
}
};
public static TransformerCategory COLOR = new TransformerCategory() {
@Override
public String getDisplayName() {
return NbBundle.getMessage(DefaultCategory.class, "Category.Color.name");
}
@Override
public Icon getIcon() {
return new ImageIcon(getClass().getResource("/org/gephi/ui/appearance/plugin/resources/color.png"));
}
@Override
public String toString() {
return "COLOR";
}
};
}
@@ -1,138 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="centerScrollPanel" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="presetCombo" min="-2" pref="216" max="-2" attributes="0"/>
<EmptySpace pref="73" max="32767" attributes="0"/>
<Component id="generateButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="labelColorCount" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="colorCountLabel" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="labelPreset" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="labelColorCount" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="colorCountLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="labelPreset" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="presetCombo" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="generateButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="centerScrollPanel" pref="208" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="labelColorCount">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/palette/Bundle.properties" key="PaletteGeneratorPanel.labelColorCount.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="colorCountLabel">
</Component>
<Component class="javax.swing.JLabel" name="labelPreset">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/palette/Bundle.properties" key="PaletteGeneratorPanel.labelPreset.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="presetCombo">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="0"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="generateButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/gephi/ui/appearance/plugin/palette/Bundle.properties" key="PaletteGeneratorPanel.generateButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="centerScrollPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="centerPanel">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="colorTable">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="0" rowCount="0"/>
</Property>
<Property name="opaque" type="boolean" value="false"/>
<Property name="rowHeight" type="int" value="22"/>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="0"/>
</Property>
<Property name="showHorizontalLines" type="boolean" value="false"/>
<Property name="showVerticalLines" type="boolean" value="false"/>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="null" type="code"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>
@@ -1,246 +0,0 @@
/*
Copyright 2008-2013 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2013 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2013 Gephi Consortium.
*/
package org.gephi.ui.appearance.plugin.palette;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.gephi.appearance.plugin.palette.Palette;
import org.gephi.appearance.plugin.palette.PaletteManager;
import org.gephi.appearance.plugin.palette.Preset;
/**
*
* @author mbastian
*/
public class PaletteGeneratorPanel extends javax.swing.JPanel {
private Preset selectedPreset;
private Palette selectedPalette;
public PaletteGeneratorPanel() {
initComponents();
//Preset Model
DefaultComboBoxModel model = new DefaultComboBoxModel();
for (Preset preset : PaletteManager.getInstance().getPresets()) {
model.addElement(preset);
}
selectedPreset = (Preset) model.getElementAt(0);
presetCombo.setModel(model);
presetCombo.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (presetCombo.getSelectedItem() != selectedPreset) {
selectedPreset = (Preset) presetCombo.getSelectedItem();
}
}
});
//Generate
generateButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
generate();
}
});
}
private void generate() {
int colorCount = Integer.parseInt(colorCountLabel.getText());
selectedPalette = PaletteManager.getInstance().generatePalette(colorCount, selectedPreset);
String[] columnNames = new String[]{"Color"};
DefaultTableModel model = new DefaultTableModel(columnNames, colorCount) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
colorTable.setModel(model);
TableColumn colorCol = colorTable.getColumnModel().getColumn(0);
colorCol.setCellRenderer(new ColorCellRenderer());
int row = 0;
for (Color c : selectedPalette.getColors()) {
model.setValueAt(c, row++, 0);
}
}
public void setup(int colorsCount) {
colorCountLabel.setText(String.valueOf(colorsCount));
}
public Palette getSelectedPalette() {
return selectedPalette;
}
class ColorCellRenderer extends JLabel implements TableCellRenderer {
public ColorCellRenderer() {
setOpaque(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Color c = (Color) value;
setBackground(c);
return this;
}
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
labelColorCount = new javax.swing.JLabel();
colorCountLabel = new javax.swing.JLabel();
labelPreset = new javax.swing.JLabel();
presetCombo = new javax.swing.JComboBox();
generateButton = new javax.swing.JButton();
centerScrollPanel = new javax.swing.JScrollPane();
centerPanel = new javax.swing.JPanel();
colorTable = new javax.swing.JTable();
labelColorCount.setText(org.openide.util.NbBundle.getMessage(PaletteGeneratorPanel.class, "PaletteGeneratorPanel.labelColorCount.text")); // NOI18N
labelPreset.setText(org.openide.util.NbBundle.getMessage(PaletteGeneratorPanel.class, "PaletteGeneratorPanel.labelPreset.text")); // NOI18N
generateButton.setText(org.openide.util.NbBundle.getMessage(PaletteGeneratorPanel.class, "PaletteGeneratorPanel.generateButton.text")); // NOI18N
centerScrollPanel.setBorder(null);
centerScrollPanel.setOpaque(false);
centerPanel.setLayout(new java.awt.GridBagLayout());
colorTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
}
));
colorTable.setOpaque(false);
colorTable.setRowHeight(22);
colorTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
colorTable.setShowHorizontalLines(false);
colorTable.setShowVerticalLines(false);
colorTable.setTableHeader(null);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
centerPanel.add(colorTable, gridBagConstraints);
centerScrollPanel.setViewportView(centerPanel);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(centerScrollPanel)
.addGroup(layout.createSequentialGroup()
.addComponent(presetCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 216, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 73, Short.MAX_VALUE)
.addComponent(generateButton))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(labelColorCount)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(colorCountLabel))
.addComponent(labelPreset))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(labelColorCount)
.addComponent(colorCountLabel))
.addGap(18, 18, 18)
.addComponent(labelPreset)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(presetCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(generateButton))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(centerScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel centerPanel;
private javax.swing.JScrollPane centerScrollPanel;
private javax.swing.JLabel colorCountLabel;
private javax.swing.JTable colorTable;
private javax.swing.JButton generateButton;
private javax.swing.JLabel labelColorCount;
private javax.swing.JLabel labelPreset;
private javax.swing.JComboBox presetCombo;
// End of variables declaration//GEN-END:variables
}
@@ -1,28 +0,0 @@
Unique.name = Unique
Attribute.name = Attribute
ColorTransformerUI.name = Color
SizeTransformerUI.name = Size
LabelColorTransformerUI.name = Label Color
LabelSizeTransformerUI.name = Label Size
RankingColorTransformerPanel.labelColor.text=Color:
RankingSizeTransformerPanel.labelMaxSize.text=Max size:
RankingSizeTransformerPanel.labelMinSize.text=Min size:
PalettePopup.light=Light
PalettePopup.dark=Dark
PalettePopup.default=Default
PalettePopup.generate=Generate...
PalettePopup.invert=Invert
PalettePopup.standard=Standard
PalettePopup.recent=Recent
PalettePopup.norecent=No recent palette
PalettePopup.allblack=All black
PalettePopup.allwhite=All white
UniqueColorTransformerPanel.colorChooser.toolTipText=Set Color
UniqueSizeTransformerPanel.jLabel1.text=Size:
PartitionColorTransformerPanel.paletteButton=Palette...
PartitionColorTransformerPanel.generatePalettePanel.title=Generate Palette
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=Hrana dovnit\u0159<- Barva
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=Color de arista Entrante <-
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=Couleur de lien ENTRANT<-
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=\u6d41\u5165\u8fba<-\u8272
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=Cor da aresta de entrada <-
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=\u0426\u0432\u0435\u0442 \u0432\u0445\u043e\u0434. \u0440\u0451\u0431\u0435\u0440
@@ -1,2 +0,0 @@
UniqueColorTransformerPanel.colorChooser.toolTipText=\u8fb9 IN<- \u989c\u8272
@@ -1,2 +0,0 @@
Category.Size.name = Size
Category.Color.name = Color
@@ -1,3 +0,0 @@
PaletteGeneratorPanel.labelColorCount.text=Colors count:
PaletteGeneratorPanel.generateButton.text=Generate
PaletteGeneratorPanel.labelPreset.text=Presets
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 359 B

+3 -9
Ver Arquivo
@@ -94,14 +94,9 @@
</exclusions>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil</artifactId>
<version>6.5.9</version>
</dependency>
<dependency>
<groupId>colt</groupId>
<artifactId>colt</artifactId>
<version>1.2.0</version>
<groupId>org.processing</groupId>
<artifactId>core</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
@@ -129,7 +124,6 @@
<publicPackage>org.apache.xml.*</publicPackage>
<publicPackage>org.xml.sax.*</publicPackage>
<publicPackage>javanet.staxutils.*</publicPackage>
<publicPackage>it.unimi.dsi.fastutil.*</publicPackage>
</publicPackages>
</configuration>
</plugin>
@@ -9,21 +9,25 @@
</parent>
<groupId>org.gephi</groupId>
<artifactId>appearance-api</artifactId>
<artifactId>graph-dhns</artifactId>
<version>0.9-SNAPSHOT</version>
<packaging>nbm</packaging>
<name>AppearanceAPI</name>
<name>DHNSGraph</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>dynamic-api</artifactId>
<artifactId>utils-collection</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>graph-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>data-attributes-api</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>project-api</artifactId>
@@ -47,10 +51,9 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>nbm-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<publicPackages>
<publicPackage>org.gephi.appearance.api</publicPackage>
<publicPackage>org.gephi.appearance.spi</publicPackage>
</publicPackages>
</configuration>
</plugin>
@@ -0,0 +1,83 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.gephi.graph.dhns.core.Dhns;
import org.gephi.graph.dhns.utils.DataSerializer;
import org.gephi.project.api.Workspace;
import org.gephi.project.spi.WorkspacePersistenceProvider;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author Mathieu Bastian
*/
@ServiceProvider(service = WorkspacePersistenceProvider.class, position = 12000)
public class DataPersistenceProvider implements WorkspacePersistenceProvider {
public void writeXML(XMLStreamWriter writer, Workspace workspace) {
Dhns dhns = workspace.getLookup().lookup(Dhns.class);
DataSerializer serializer = new DataSerializer();
try {
serializer.writeData(writer, dhns);
} catch (XMLStreamException ex) {
throw new RuntimeException(ex);
}
}
public void readXML(XMLStreamReader reader, Workspace workspace) {
Dhns dhns = workspace.getLookup().lookup(Dhns.class);
DataSerializer serializer = new DataSerializer();
try {
serializer.readData(reader, dhns);
} catch (XMLStreamException ex) {
throw new RuntimeException(ex);
}
}
public String getIdentifier() {
return "Data";
}
}
@@ -0,0 +1,66 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns;
import org.gephi.graph.api.GraphController;
import org.gephi.graph.dhns.core.Dhns;
import org.gephi.project.api.Workspace;
import org.gephi.project.spi.WorkspaceDuplicateProvider;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author Mathieu Bastian
*/
@ServiceProvider(service = WorkspaceDuplicateProvider.class, position = 1000)
public class DhnsDuplicateProvider implements WorkspaceDuplicateProvider {
public void duplicate(Workspace source, Workspace destination) {
GraphController controller = Lookup.getDefault().lookup(GraphController.class);
Dhns sourceModel = (Dhns) controller.getModel(source);
Dhns destModel = (Dhns) controller.getModel(destination);
if (sourceModel != null && destModel != null) {
sourceModel.getDuplicateManager().duplicate(destModel);
}
}
}
@@ -0,0 +1,107 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.gephi.graph.api.GraphController;
import org.gephi.graph.api.GraphModel;
import org.gephi.graph.dhns.core.Dhns;
import org.gephi.graph.dhns.core.IDGen;
import org.gephi.project.api.ProjectController;
import org.gephi.project.api.Workspace;
import org.gephi.project.spi.WorkspaceDuplicateProvider;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
import org.openide.util.lookup.ServiceProviders;
/**
* Singleton which manages the graph access.
*
* @author Mathieu Bastian
*/
@ServiceProvider(service = GraphController.class)
public class DhnsGraphController implements GraphController {
protected IDGen iDGen;
public DhnsGraphController() {
iDGen = new IDGen();
}
public Dhns newDhns(Workspace workspace) {
Dhns dhns = new Dhns(this, workspace);
workspace.add(dhns);
return dhns;
}
public IDGen getIDGen() {
return iDGen;
}
private synchronized Dhns getCurrentDhns() {
Workspace currentWorkspace = Lookup.getDefault().lookup(ProjectController.class).getCurrentWorkspace();
if (currentWorkspace == null) {
return null;
}
Dhns dhns = currentWorkspace.getLookup().lookup(Dhns.class);
if (dhns == null) {
dhns = newDhns(currentWorkspace);
}
return dhns;
}
public GraphModel getModel(Workspace workspace) {
Dhns dhns = workspace.getLookup().lookup(Dhns.class);
if (dhns == null) {
dhns = newDhns(workspace);
}
return dhns;
}
public GraphModel getModel() {
return getCurrentDhns();
}
}
@@ -0,0 +1,86 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.gephi.graph.dhns.core.Dhns;
import org.gephi.graph.dhns.utils.DHNSSerializer;
import org.gephi.project.api.Workspace;
import org.gephi.project.spi.WorkspacePersistenceProvider;
import org.openide.util.Lookup;
import org.openide.util.lookup.ServiceProvider;
/**
*
* @author Mathieu Bastian
*/
@ServiceProvider(service = WorkspacePersistenceProvider.class, position = 10000)
public class DhnsPersistenceProvider implements WorkspacePersistenceProvider {
public void writeXML(XMLStreamWriter writer, Workspace workspace) {
DhnsGraphController graphController = Lookup.getDefault().lookup(DhnsGraphController.class);
Dhns dhns = (Dhns) graphController.getModel(workspace);
DHNSSerializer serializer = new DHNSSerializer();
try {
serializer.writeDhns(writer, dhns);
} catch (XMLStreamException ex) {
throw new RuntimeException(ex);
}
}
public void readXML(XMLStreamReader reader, Workspace workspace) {
DhnsGraphController graphController = Lookup.getDefault().lookup(DhnsGraphController.class);
Dhns dhns = (Dhns) graphController.getModel(workspace);
DHNSSerializer serializer = new DHNSSerializer();
try {
serializer.readDhns(reader, dhns);
} catch (XMLStreamException ex) {
throw new RuntimeException(ex);
}
}
public String getIdentifier() {
return "Dhns";
}
}
@@ -0,0 +1,525 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.gephi.data.attributes.api.AttributeController;
import org.gephi.data.attributes.api.AttributeModel;
import org.gephi.data.attributes.api.AttributeRowFactory;
import org.gephi.graph.api.DirectedGraph;
import org.gephi.graph.api.EdgeIterable;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.GraphListener;
import org.gephi.graph.api.GraphModel;
import org.gephi.graph.api.GraphSettings;
import org.gephi.graph.api.HierarchicalDirectedGraph;
import org.gephi.graph.api.HierarchicalGraph;
import org.gephi.graph.api.HierarchicalMixedGraph;
import org.gephi.graph.api.HierarchicalUndirectedGraph;
import org.gephi.graph.api.MixedGraph;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeIterable;
import org.gephi.graph.api.UndirectedGraph;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.dhns.DhnsGraphController;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.edge.iterators.AbstractEdgeIterator;
import org.gephi.graph.dhns.graph.HierarchicalDirectedGraphImpl;
import org.gephi.graph.dhns.graph.HierarchicalGraphImpl;
import org.gephi.graph.dhns.graph.HierarchicalMixedGraphImpl;
import org.gephi.graph.dhns.graph.HierarchicalUndirectedGraphImpl;
import org.gephi.graph.dhns.graph.iterators.EdgeIterableImpl;
import org.gephi.graph.dhns.graph.iterators.NodeIterableImpl;
import org.gephi.graph.dhns.node.iterators.AbstractNodeIterator;
import org.gephi.graph.dhns.predicate.Predicate;
import org.gephi.project.api.Workspace;
import org.openide.util.Lookup;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* Main class of the DHNS (Durable Hierarchical Network Structure) graph structure..
*
* @author Mathieu Bastian
*/
public class Dhns implements GraphModel {
//Core
private final Workspace workspace;
private final DhnsGraphController controller;
private GraphStructure graphStructure;
private GraphVersion graphVersion;
private final EventManager eventManager;
private final SettingsManager settingsManager;
private final GraphFactoryImpl factory;
private final DuplicateManager duplicateManager;
//Type
private boolean directed = false;
private boolean undirected = false;
private boolean mixed = false;
//Locking
private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public Dhns(DhnsGraphController controller, Workspace workspace) {
this.controller = controller;
this.workspace = workspace;
graphVersion = new GraphVersion();
eventManager = new EventManager(this);
settingsManager = new SettingsManager(this);
duplicateManager = new DuplicateManager(this);
eventManager.start();
//AttributeFactory
AttributeRowFactory attributeRowFactory = null;
if (workspace != null) {
AttributeModel attributeModel = Lookup.getDefault().lookup(AttributeController.class).getModel(workspace);
if (attributeModel != null) {
attributeRowFactory = attributeModel.rowFactory();
}
}
factory = new GraphFactoryImpl(controller.getIDGen(), attributeRowFactory);
graphStructure = new GraphStructure(this);
init();
}
public void init() {
}
public DhnsGraphController getController() {
return controller;
}
public GraphStructure getGraphStructure() {
return graphStructure;
}
public GraphVersion getGraphVersion() {
return graphVersion;
}
public EventManager getEventManager() {
return eventManager;
}
public IDGen getIdGen() {
return controller.getIDGen();
}
public SettingsManager getSettingsManager() {
return settingsManager;
}
public DuplicateManager getDuplicateManager() {
return duplicateManager;
}
public NodeIterable newNodeIterable(AbstractNodeIterator iterator) {
return new NodeIterableImpl(iterator, readWriteLock.readLock());
}
public EdgeIterable newEdgeIterable(AbstractEdgeIterator iterator) {
return new EdgeIterableImpl(iterator, readWriteLock.readLock());
}
public NodeIterable newNodeIterable(AbstractNodeIterator iterator, Predicate<Node> predicate) {
return new NodeIterableImpl(iterator, readWriteLock.readLock());
}
public EdgeIterable newEdgeIterable(AbstractEdgeIterator iterator, Predicate<AbstractEdge> predicate) {
return new EdgeIterableImpl(iterator, readWriteLock.readLock(), predicate);
}
//Locking
public void readLock() {
/*if (SwingUtilities.isEventDispatchThread()) {
Throwable r = new RuntimeException();
int i = 0;
for (i = 0; i < r.getStackTrace().length; i++) {
if (!r.getStackTrace()[i].toString().startsWith("org.gephi.graph.dhns")) {
break;
}
}
System.err.println("WARNING: readLock() on the EDT - " + r.getStackTrace()[i].toString());
}*/
//String t = Thread.currentThread().toString();
//Logger.getLogger("").log(Level.WARNING, "{0} read lock", Thread.currentThread());
readWriteLock.readLock().lock();
}
public void readUnlock() {
readWriteLock.readLock().unlock();
}
public void readUnlockAll() {
ReentrantReadWriteLock lock = readWriteLock;
final int nReadLocks = lock.getReadHoldCount();
for (int n = 0; n < nReadLocks; n++) {
lock.readLock().unlock();
}
}
public boolean conditionalWriteLock() {
if (readWriteLock.getReadHoldCount() > 0) {
throw new IllegalMonitorStateException("Impossible to acquire a write lock when currently holding a read lock. Use toArray() methods on NodeIterable and EdgeIterable to avoid holding a readLock.");
}
if (!readWriteLock.isWriteLockedByCurrentThread()) {
readWriteLock.writeLock().lock();
return true;
}
return false;
}
public void conditionalWriteUnlock(boolean locked) {
if (locked) {
readWriteLock.writeLock().unlock();
}
}
public void writeLock() {
if (readWriteLock.getReadHoldCount() > 0) {
throw new IllegalMonitorStateException("Impossible to acquire a write lock when currently holding a read lock. Use toArray() methods on NodeIterable and EdgeIterable to avoid holding a readLock.");
}
/*if (SwingUtilities.isEventDispatchThread()) {
Throwable r = new RuntimeException();
int i = 0;
for (i = 0; i < r.getStackTrace().length; i++) {
if (!r.getStackTrace()[i].toString().startsWith("org.gephi.graph.dhns")) {
break;
}
}
System.err.println("WARNING: writeLock() on the EDT - " + r.getStackTrace()[i].toString());
}*/
//Logger.getLogger("").log(Level.WARNING, "{0} write lock", Thread.currentThread());
readWriteLock.writeLock().lock();
}
public void writeUnlock() {
//Logger.getLogger("").log(Level.WARNING, "{0} write unlock", Thread.currentThread());
readWriteLock.writeLock().unlock();
}
public ReentrantReadWriteLock getReadWriteLock() {
return readWriteLock;
}
//Type
public void touchDirected() {
if (undirected || mixed) {
touchMixed();
} else {
directed = true;
}
}
public void touchUndirected() {
if (directed || mixed) {
touchMixed();
} else {
undirected = true;
}
}
public void touchMixed() {
directed = false;
undirected = false;
mixed = true;
}
//API
public GraphFactoryImpl factory() {
return factory;
}
public boolean isDirected() {
return directed;
}
public boolean isMixed() {
return mixed;
}
public boolean isUndirected() {
return undirected;
}
public void setDirected(boolean directed) {
this.directed = directed;
}
public void setUndirected(boolean undirected) {
this.undirected = undirected;
}
public void setMixed(boolean mixed) {
this.mixed = mixed;
}
public boolean isHierarchical() {
return graphStructure.getMainView().getStructure().getTreeHeight() - 1 > 0; //height>0
}
public void addGraphListener(GraphListener graphListener) {
eventManager.addGraphListener(graphListener);
}
public void removeGraphListener(GraphListener graphListener) {
eventManager.removeGraphListener(graphListener);
}
public Graph getGraph() {
if (directed) {
return getDirectedGraph();
} else if (undirected) {
return getUndirectedGraph();
} else if (mixed) {
return getMixedGraph();
} else {
return getDirectedGraph();
}
}
public DirectedGraph getDirectedGraph() {
return new HierarchicalDirectedGraphImpl(this, graphStructure.getMainView());
}
public UndirectedGraph getUndirectedGraph() {
return new HierarchicalUndirectedGraphImpl(this, graphStructure.getMainView());
}
public MixedGraph getMixedGraph() {
return new HierarchicalMixedGraphImpl(this, graphStructure.getMainView());
}
public HierarchicalGraph getHierarchicalGraph() {
if (directed) {
return getHierarchicalDirectedGraph();
} else if (undirected) {
return getHierarchicalUndirectedGraph();
} else if (mixed) {
return getHierarchicalMixedGraph();
} else {
return getHierarchicalDirectedGraph();
}
}
public HierarchicalDirectedGraph getHierarchicalDirectedGraph() {
return new HierarchicalDirectedGraphImpl(this, graphStructure.getMainView());
}
public HierarchicalMixedGraph getHierarchicalMixedGraph() {
return new HierarchicalMixedGraphImpl(this, graphStructure.getMainView());
}
public HierarchicalUndirectedGraph getHierarchicalUndirectedGraph() {
return new HierarchicalUndirectedGraphImpl(this, graphStructure.getMainView());
}
public DirectedGraph getDirectedGraph(GraphView view) {
return new HierarchicalDirectedGraphImpl(this, (GraphViewImpl) view);
}
public Graph getGraph(GraphView view) {
if (directed) {
return getDirectedGraph(view);
} else if (undirected) {
return getUndirectedGraph(view);
} else if (mixed) {
return getMixedGraph(view);
} else {
return getDirectedGraph(view);
}
}
public HierarchicalDirectedGraph getHierarchicalDirectedGraph(GraphView view) {
return new HierarchicalDirectedGraphImpl(this, (GraphViewImpl) view);
}
public HierarchicalGraph getHierarchicalGraph(GraphView view) {
if (directed) {
return getHierarchicalDirectedGraph(view);
} else if (undirected) {
return getHierarchicalUndirectedGraph(view);
} else if (mixed) {
return getHierarchicalMixedGraph(view);
} else {
return getHierarchicalDirectedGraph(view);
}
}
public HierarchicalMixedGraph getHierarchicalMixedGraph(GraphView view) {
return new HierarchicalMixedGraphImpl(this, (GraphViewImpl) view);
}
public HierarchicalUndirectedGraph getHierarchicalUndirectedGraph(GraphView view) {
return new HierarchicalUndirectedGraphImpl(this, (GraphViewImpl) view);
}
public MixedGraph getMixedGraph(GraphView view) {
return new HierarchicalMixedGraphImpl(this, (GraphViewImpl) view);
}
public UndirectedGraph getUndirectedGraph(GraphView view) {
return new HierarchicalUndirectedGraphImpl(this, (GraphViewImpl) view);
}
public Graph getGraphVisible() {
if (directed) {
return getDirectedGraph(graphStructure.getVisibleView());
} else if (undirected) {
return getUndirectedGraph(graphStructure.getVisibleView());
} else if (mixed) {
return getMixedGraph(graphStructure.getVisibleView());
} else {
return getDirectedGraph(graphStructure.getVisibleView());
}
}
public DirectedGraph getDirectedGraphVisible() {
return getDirectedGraph(graphStructure.getVisibleView());
}
public UndirectedGraph getUndirectedGraphVisible() {
return getUndirectedGraph(graphStructure.getVisibleView());
}
public MixedGraph getMixedGraphVisible() {
return getMixedGraph(graphStructure.getVisibleView());
}
public HierarchicalGraph getHierarchicalGraphVisible() {
if (directed) {
return getHierarchicalDirectedGraph(graphStructure.getVisibleView());
} else if (undirected) {
return getHierarchicalUndirectedGraph(graphStructure.getVisibleView());
} else if (mixed) {
return getHierarchicalMixedGraph(graphStructure.getVisibleView());
} else {
return getHierarchicalDirectedGraph(graphStructure.getVisibleView());
}
}
public HierarchicalDirectedGraph getHierarchicalDirectedGraphVisible() {
return getHierarchicalDirectedGraph(graphStructure.getVisibleView());
}
public HierarchicalMixedGraph getHierarchicalMixedGraphVisible() {
return getHierarchicalMixedGraph(graphStructure.getVisibleView());
}
public HierarchicalUndirectedGraph getHierarchicalUndirectedGraphVisible() {
return getHierarchicalUndirectedGraph(graphStructure.getVisibleView());
}
public GraphSettings settings() {
return settingsManager;
}
public void pushFrom(Graph graph) {
if (graph == null) {
throw new NullPointerException();
}
HierarchicalGraphImpl graphImpl = (HierarchicalGraphImpl) graph;
if (graphImpl.getGraphModel() == this) {
throw new IllegalArgumentException("The graph must be from a different Workspace");
}
Dhns source = (Dhns) graphImpl.getGraphModel();
source.getDuplicateManager().duplicate(this, (GraphViewImpl) graphImpl.getView());
graphVersion.incNodeAndEdgeVersion();
// eventManager.fireEvent(EventType.NODES_AND_EDGES_UPDATED);
}
public void pushNodes(Graph graph, Node[] nodes) {
if (graph == null) {
throw new NullPointerException();
}
HierarchicalGraphImpl graphImpl = (HierarchicalGraphImpl) graph;
if (graphImpl.getGraphModel() == this) {
throw new IllegalArgumentException("The graph must be from a different Workspace");
}
Dhns source = (Dhns) graphImpl.getGraphModel();
source.getDuplicateManager().duplicateNodes(this, nodes);
graphVersion.incNodeAndEdgeVersion();
}
public void clear() {
graphVersion = new GraphVersion();
graphStructure = new GraphStructure(this);
}
public void readXML(Element element) {
}
public Element writeXML(Document document) {
return null;
}
public GraphModel copy() {
return null;
}
public GraphView newView() {
return graphStructure.getNewView();
}
public GraphView copyView(GraphView view) {
return graphStructure.copyView((GraphViewImpl) view);
}
public void destroyView(GraphView view) {
graphStructure.destroyView((GraphViewImpl) view);
}
public void setVisibleView(GraphView view) {
graphStructure.setVisibleView(view != null ? (GraphViewImpl) view : null);
}
public GraphView getVisibleView() {
return graphStructure.getVisibleView();
}
public Workspace getWorkspace() {
return workspace;
}
}
@@ -0,0 +1,229 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.HashMap;
import java.util.Map;
import org.gephi.utils.collection.avl.ParamAVLIterator;
import org.gephi.graph.api.Attributes;
import org.gephi.graph.api.Graph;
import org.gephi.graph.api.Node;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.edge.EdgeDataImpl;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.NodeDataImpl;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
/**
*
* @author Mathieu Bastian
*/
public class DuplicateManager {
private final Dhns dhns;
public DuplicateManager(Dhns dhns) {
this.dhns = dhns;
}
public void duplicate(Dhns destination) {
duplicate(destination, dhns.getGraphStructure().getMainView());
}
public void duplicate(Dhns destination, GraphViewImpl view) {
GraphFactoryImpl factory = destination.factory();
dhns.readLock();
destination.writeLock();
TreeStructure treeStructure = view.getStructure();
GraphStructure newGraphStructure = destination.getGraphStructure();
TreeStructure newStructure = newGraphStructure.getMainView().getStructure();
//Nodes
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
AbstractNode nodeCopy = factory.newNode();
duplicateNodeData(node.getNodeData(), nodeCopy.getNodeData());
nodeCopy.setEnabled(node.isEnabled());
nodeCopy.setEnabledInDegree(node.getEnabledInDegree());
nodeCopy.setEnabledOutDegree(node.getEnabledOutDegree());
nodeCopy.setEnabledMutualDegree(node.getEnabledMutualDegree());
AbstractNode parentCopy = node.parent != null ? newStructure.getNodeAt(node.parent.getPre()) : null;
newStructure.insertAsChild(nodeCopy, parentCopy);
newGraphStructure.addToDictionnary(nodeCopy);
}
//Edges
ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>();
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
if (!node.getEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(node.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractEdge edgeCopy;
AbstractNode sourceCopy = newStructure.getNodeAt(edge.getSource(view.getViewId()).getPre());
AbstractNode targetCopy = newStructure.getNodeAt(edge.getTarget(view.getViewId()).getPre());
if (edge.isMixed()) {
edgeCopy = factory.newEdge(edge.getEdgeData().getId(), sourceCopy, targetCopy, edge.getWeight(), edge.isDirected());
if (edge.isDirected()) {
destination.touchDirected();
} else {
destination.touchUndirected();
}
} else {
edgeCopy = factory.newEdge(sourceCopy, targetCopy);
edgeCopy.setWeight(edge.getWeight());
destination.touchDirected();
}
duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData());
sourceCopy.getEdgesOutTree().add(edgeCopy);
targetCopy.getEdgesInTree().add(edgeCopy);
newGraphStructure.addToDictionnary(edgeCopy);
}
}
}
newGraphStructure.getMainView().setNodesEnabled(view.getNodesEnabled());
newGraphStructure.getMainView().setEdgesCountTotal(view.getEdgesCountTotal());
newGraphStructure.getMainView().setEdgesCountEnabled(view.getEdgesCountEnabled());
newGraphStructure.getMainView().setMutualEdgesTotal(view.getMutualEdgesTotal());
newGraphStructure.getMainView().setMutualEdgesEnabled(view.getMutualEdgesEnabled());
//Metaedges
newGraphStructure.getMainView().getStructureModifier().getEdgeProcessor().computeMetaEdges();
destination.writeUnlock();
dhns.readUnlock();
}
public void duplicateNodes(Dhns destination, Node[] nodes) {
Map<AbstractNode, AbstractNode> nodeMap = new HashMap<AbstractNode, AbstractNode>();
GraphFactoryImpl factory = destination.factory();
Graph destGraph = null;
if (dhns.isDirected()) {
destGraph = destination.getDirectedGraph();
} else if (dhns.isUndirected()) {
destGraph = destination.getUndirectedGraph();
} else {
destGraph = destination.getMixedGraph();
}
dhns.readLock();
destination.writeLock();
//Nodes
for (Node sourceNode : nodes) {
AbstractNode absSourceNode = (AbstractNode) sourceNode;
AbstractNode nodeCopy = factory.newNode(sourceNode.getNodeData().getId());
destGraph.addNode(nodeCopy);
duplicateNodeData((NodeDataImpl) sourceNode.getNodeData(), (NodeDataImpl) nodeCopy.getNodeData());
nodeMap.put(absSourceNode, nodeCopy);
}
//Edges
ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>();
for (Node sourceNode : nodes) {
AbstractNode absSourceNode = (AbstractNode) sourceNode;
AbstractNode nodeCopy = nodeMap.get(absSourceNode);
int sourceView = absSourceNode.getViewId();
if (!absSourceNode.getEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(absSourceNode.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode originalTargetNode = edge.getTarget(sourceView);
AbstractNode copyTargetNode = nodeMap.get(originalTargetNode);
if (copyTargetNode != null) {
AbstractEdge edgeCopy = factory.newEdge(edge.getEdgeData().getId(), nodeCopy, copyTargetNode, edge.getWeight(), edge.isDirected());
destGraph.addEdge(edgeCopy);
duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData());
}
}
}
if (!absSourceNode.getMetaEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(absSourceNode.getMetaEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode originalTargetNode = edge.getTarget(sourceView);
AbstractNode copyTargetNode = nodeMap.get(originalTargetNode);
if (copyTargetNode != null) {
AbstractEdge edgeCopy = factory.newEdge(edge.getEdgeData().getId(), nodeCopy, copyTargetNode, edge.getWeight(), edge.isDirected());
destGraph.addEdge(edgeCopy);
duplicateEdgeData(edge.getEdgeData(), edgeCopy.getEdgeData());
}
}
}
}
destination.writeUnlock();
dhns.readUnlock();
}
private void duplicateNodeData(NodeDataImpl source, NodeDataImpl dest) {
dest.setX(source.x());
dest.setY(source.y());
dest.setZ(source.z());
dest.setR(source.r());
dest.setG(source.g());
dest.setB(source.b());
dest.setAlpha(source.alpha());
dest.setSize(source.getSize());
dest.getTextData().setColor(source.getTextData().getR(), source.getTextData().getG(), source.getTextData().getB(), source.getTextData().getAlpha());
dest.getTextData().setSize(source.getTextData().getSize());
dest.getTextData().setVisible(source.getTextData().isVisible());
//Attributes
Attributes sourceAttributes = source.getAttributes();
for (int i = 0; i < sourceAttributes.countValues(); i++) {
dest.getAttributes().setValue(i, sourceAttributes.getValue(i));
}
}
private void duplicateEdgeData(EdgeDataImpl source, EdgeDataImpl dest) {
dest.setR(source.r());
dest.setG(source.g());
dest.setB(source.b());
dest.setAlpha(source.alpha());
dest.getTextData().setColor(source.getTextData().getR(), source.getTextData().getG(), source.getTextData().getB(), source.getTextData().getAlpha());
dest.getTextData().setSize(source.getTextData().getSize());
dest.getTextData().setVisible(source.getTextData().isVisible());
//Attributes
Attributes sourceAttributes = source.getAttributes();
for (int i = 0; i < sourceAttributes.countValues(); i++) {
dest.getAttributes().setValue(i, sourceAttributes.getValue(i));
}
}
}
@@ -0,0 +1,945 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class is a modification of the <b><code>TreeList</code></b> from Apache Commons Collections 3.1.
* <p>Basically
* the <code>TreeList</code> is a <code>List</code> implementation that is optimised for fast insertions and
* removals at any index in the list.
* <p>
* This list implementation uses a tree structure internally to ensure that
* all insertions and removals are O(ln(n)). This provides much faster performance
* than both an <code>ArrayList</code> and a <code>LinkedList</code> where elements
* are inserted and removed repeatedly from anywhere in the list.
* <p>
* The class has been modified in the way any modification avoid renumbering of the <b>pre</b> order.
* <ul><li>Tuned for only store {@link AbstractNode}. And <code>AbstractNode</code> knows his {@link DurableAVLNode}.</li>
* <li>The class know if the <b>pre</b> number of items is synchronized with indexes or not. See
* <code>preConsistent</code> integer.</li>
* <li>When index are not synchronized the real index of <code>DurableAVLNode</code> has to be retrieved.</li>
* <li>That's why the parent node has been added to <code>DurableAVLNode</code>. In that way retrieving a
* node index can be performed in O(H) where H is the height of the tree.</li></ul>
* @author Joerg Schmuecker
* @author Stephen Colebourne
* @author Mathieu Bastian
*/
public class DurableTreeList extends AbstractList<AbstractNode> implements Iterable<AbstractNode> {
// add; toArray; iterator; insert; get; indexOf; remove
// TreeList = 1260;7360;3080; 160; 170;3400; 170;
// ArrayList = 220;1480;1760; 6870; 50;1540; 7200;
// LinkedList = 270;7360;3350;55860;290720;2910;55200;
/** The root node in the AVL tree */
DurableAVLNode root;
/** The current size of the list */
int size = 0;
private int preConsistent = 0;
protected int[] levelsSize;
private final GraphViewImpl view;
//-----------------------------------------------------------------------
/**
* Constructs a new empty list.
*/
public DurableTreeList(GraphViewImpl view) {
super();
this.view = view;
levelsSize = new int[1];
}
public GraphViewImpl getView() {
return view;
}
/**
* Constructs a new empty list that copies the specified list.
*
* @param coll the collection to copy
* @throws NullPointerException if the collection is null
*/
/*public DurableTreeList(Collection<AbstractNode> coll) {
super();
addAll(coll);
}*/
public void incPreConsistent() {
preConsistent++;
}
//-----------------------------------------------------------------------
/**
* Gets the element at the specified index.
*
* @param index the index to retrieve
* @return the element at the specified index
*/
public AbstractNode get(int index) {
checkInterval(index, 0, size() - 1);
return root.get(index).getValue();
}
public DurableAVLNode getNode(int index) {
checkInterval(index, 0, size() - 1);
return root.get(index);
}
/**
* Gets the current size of the list.
*
* @return the current size
*/
public int size() {
return size;
}
/**
* Gets an iterator over the list.
*
* @return an iterator over the list
*/
@Override
public Iterator<AbstractNode> iterator() {
// override to go 75% faster
return new TreeListIterator(this);
}
public Iterator<AbstractNode> iterator(int fromIndex) {
// override to go 75% faster
return new TreeListIterator(this, fromIndex);
}
/**
* Searches for the index of an object in the list.
*
* @return the index of the object, -1 if not found
*/
public int indexOf(AbstractNode object) {
// override to go 75% faster
if (root == null) {
return -1;
}
return root.indexOf(object, root.relativePosition);
}
/**
* Searches for the presence of an object in the list.
*
* @return true if the object is found
*/
public boolean contains(AbstractNode object) {
return (indexOf(object) >= 0);
}
/**
* Converts the list into an array.
*
* @return the list as an array
*/
@Override
public AbstractNode[] toArray() {
// override to go 20% faster
AbstractNode[] array = new AbstractNode[size()];
if (root != null) {
root.toArray(array, root.relativePosition);
}
return array;
}
//-----------------------------------------------------------------------
/**
* Adds a new element to the list.
*
* @param index the index to add before
* @param obj the element to add
*/
@Override
public void add(int index, AbstractNode obj) {
modCount++;
checkInterval(index, 0, size());
incPreConsistent();
if (root == null) {
root = new DurableAVLNode(this, index, obj, null, null, null);
} else {
root = root.insert(index, obj);
root.parent = null;
}
if (obj.level >= levelsSize.length) {
levelsSize = Arrays.copyOf(levelsSize, levelsSize.length + 1);
}
levelsSize[obj.level]++;
size++;
}
@Override
public boolean add(AbstractNode e) {
add(size, e);
return true;
}
/**
* Sets the element at the specified index.
*
* @param index the index to set
* @param obj the object to store at the specified index
* @return the previous object at that index
* @throws IndexOutOfBoundsException if the index is invalid
*/
@Override
public AbstractNode set(int index, AbstractNode obj) {
checkInterval(index, 0, size() - 1);
DurableAVLNode node = root.get(index);
AbstractNode result = node.value;
node.setValue(obj);
return result;
}
/**
* Removes the element at the specified index.
*
* @param index the index to remove
* @return the previous object at that index
*/
@Override
public AbstractNode remove(int index) {
modCount++;
checkInterval(index, 0, size() - 1);
AbstractNode result = get(index);
levelsSize[result.level]--;
result.avlNode.setIndex(index);
root = root.remove(index);
result.avlNode = null;
result.parent = null;
size--;
incPreConsistent();
return result;
}
public AbstractNode removeAndKeepParent(int index) {
checkInterval(index, 0, size() - 1);
//Remove without setting null parent
AbstractNode result = get(index);
levelsSize[result.level]--;
root = root.remove(index);
result.avlNode = null;
result.size = 0;
size--;
incPreConsistent();
return result;
}
public void move(int index, int destination) {
checkInterval(index, 0, size() - 1);
AbstractNode node = get(index);
AbstractNode parent = get(destination);
int destinationPre = parent.pre + parent.size + 1;
int nodeLimit = node.pre + node.size;
boolean forward = destinationPre > node.pre;
int difflevel = 0;
//Move descendant & self
int count = 0;
for (int i = node.pre; i <= nodeLimit; i++) {
int sourcePre = i;
int destPre = destinationPre + count;
if (forward) {
sourcePre -= count;
destPre -= count + 1;
}
AbstractNode sourceNode = get(sourcePre);
levelsSize[sourceNode.level]--;
root = root.remove(sourcePre); //Remove
sourceNode.avlNode = null; //Remove
size--; //Remove
//System.out.println("add "+(destPre)+" remove "+sourceNode.getId());
if (count == 0) {
sourceNode.parent = parent;
difflevel = node.parent.level - node.level + 1;
}
sourceNode.level += difflevel;
add(destPre, sourceNode);
count++;
}
incPreConsistent();
}
/**
* Clears the list, removing all entries.
*/
@Override
public void clear() {
modCount++;
root = null;
size = 0;
levelsSize = new int[1];
}
//-----------------------------------------------------------------------
/**
* Checks whether the index is valid.
*
* @param index the index to check
* @param startIndex the first allowed index
* @param endIndex the last allowed index
* @throws IndexOutOfBoundsException if the index is invalid
*/
private void checkInterval(int index, int startIndex, int endIndex) {
if (index < startIndex || index > endIndex) {
throw new IndexOutOfBoundsException("Invalid index:" + index + ", size=" + size());
}
}
//-----------------------------------------------------------------------
/**
* Implements an DurableAVLNode which keeps the offset updated.
* <p>
* This node contains the real work.
* TreeList is just there to implement {@link java.util.List}.
* The nodes don't know the index of the object they are holding. They
* do know however their position relative to their parent node.
* This allows to calculate the index of a node while traversing the tree.
* <p>
* The Faedelung calculation stores a flag for both the left and right child
* to indicate if they are a child (false) or a link as in linked list (true).
*/
public static class DurableAVLNode {
/** The left child node or the predecessor if {@link #leftIsPrevious}.*/
private DurableAVLNode left;
/** Flag indicating that left reference is not a subtree but the predecessor. */
private boolean leftIsPrevious;
/** The right child node or the successor if {@link #rightIsNext}. */
private DurableAVLNode right;
/** Flag indicating that right reference is not a subtree but the successor. */
private boolean rightIsNext;
/** How many levels of left/right are below this one. */
private int height;
/** The relative position, root holds absolute position. */
private int relativePosition;
/** The stored element. */
AbstractNode value;
private DurableAVLNode parent;
private int preConsistent;
private DurableTreeList tree;
/**
* Constructs a new node with a relative position.
*
* @param relativePosition the relative position of the node
* @param obj the value for the node
* @param rightFollower the node with the value following this one
* @param leftFollower the node with the value leading this one
*/
private DurableAVLNode(DurableTreeList treeParent, int relativePosition, AbstractNode obj, DurableAVLNode rightFollower, DurableAVLNode leftFollower, DurableAVLNode parentNode) {
this.relativePosition = relativePosition;
value = obj;
obj.avlNode = this;
tree = treeParent;
rightIsNext = true;
leftIsPrevious = true;
right = rightFollower;
left = leftFollower;
parent = parentNode;
preConsistent = tree.preConsistent;
}
public DurableTreeList getList() {
return tree;
}
public int getIndex() {
if (preConsistent != tree.preConsistent) {
//The Pre is not consistent
DurableAVLNode currentParent = parent;
int index = relativePosition;
while (currentParent != null) {
index += currentParent.relativePosition;
currentParent = currentParent.parent;
}
value.pre = index;
value.getPost();
preConsistent = tree.preConsistent;
}
return value.pre;
}
public void setIndex(int index) {
value.pre = index;
value.getPost();
preConsistent = tree.preConsistent;
}
public boolean isConsistent() {
return preConsistent == tree.preConsistent;
}
/**
* Gets the value.
*
* @return the value of this node
*/
public AbstractNode getValue() {
return value;
}
/**
* Sets the value.
*
* @param obj the value to store
*/
void setValue(AbstractNode obj) {
this.value = obj;
obj.avlNode = this;
}
/**
* Locate the element with the given index relative to the
* offset of the parent of this node.
*/
DurableAVLNode get(int index) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe == 0) {
//value.setPre(index);
return this;
}
DurableAVLNode nextNode = ((indexRelativeToMe < 0) ? getLeftSubTree() : getRightSubTree());
if (nextNode == null) {
return null;
}
return nextNode.get(indexRelativeToMe);
}
/**
* Locate the index that contains the specified object.
*/
int indexOf(AbstractNode object, int index) {
//value.setPre(index);
if (getLeftSubTree() != null) {
int result = left.indexOf(object, index + left.relativePosition);
if (result != -1) {
return result;
}
}
if (value == null ? value == object : value.equals(object)) {
return index;
}
if (getRightSubTree() != null) {
return right.indexOf(object, index + right.relativePosition);
}
return -1;
}
/**
* Stores the node and its children into the array specified.
*
* @param array the array to be filled
* @param index the index of this node
*/
void toArray(AbstractNode[] array, int index) {
array[index] = value;
if (getLeftSubTree() != null) {
left.toArray(array, index + left.relativePosition);
}
if (getRightSubTree() != null) {
right.toArray(array, index + right.relativePosition);
}
}
/**
* Gets the next node in the list after this one.
*
* @return the next node
*/
public DurableAVLNode next() {
if (rightIsNext || right == null) {
return right;
}
return right.min();
}
/**
* Gets the node in the list before this one.
*
* @return the previous node
*/
DurableAVLNode previous() {
if (leftIsPrevious || left == null) {
return left;
}
return left.max();
}
/**
* Inserts a node at the position index.
*
* @param index is the index of the position relative to the position of
* the parent node.
* @param obj is the object to be stored in the position.
*/
DurableAVLNode insert(int index, AbstractNode obj) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe <= 0) {
return insertOnLeft(indexRelativeToMe, obj);
} else {
return insertOnRight(indexRelativeToMe, obj);
}
}
private DurableAVLNode insertOnLeft(int indexRelativeToMe, AbstractNode obj) {
DurableAVLNode ret = this;
if (getLeftSubTree() == null) {
setLeft(new DurableAVLNode(tree, -1, obj, this, left, this), null);
} else {
setLeft(left.insert(indexRelativeToMe, obj), null);
}
if (relativePosition >= 0) {
relativePosition++;
}
ret = balance();
recalcHeight();
return ret;
}
private DurableAVLNode insertOnRight(int indexRelativeToMe, AbstractNode obj) {
DurableAVLNode ret = this;
if (getRightSubTree() == null) {
setRight(new DurableAVLNode(tree, +1, obj, right, this, this), null);
} else {
setRight(right.insert(indexRelativeToMe, obj), null);
}
if (relativePosition < 0) {
relativePosition--;
}
ret = balance();
recalcHeight();
return ret;
}
//-----------------------------------------------------------------------
/**
* Gets the left node, returning null if its a faedelung.
*/
private DurableAVLNode getLeftSubTree() {
return (leftIsPrevious ? null : left);
}
/**
* Gets the right node, returning null if its a faedelung.
*/
private DurableAVLNode getRightSubTree() {
return (rightIsNext ? null : right);
}
/**
* Gets the rightmost child of this node.
*
* @return the rightmost child (greatest index)
*/
private DurableAVLNode max() {
return (getRightSubTree() == null) ? this : right.max();
}
/**
* Gets the leftmost child of this node.
*
* @return the leftmost child (smallest index)
*/
private DurableAVLNode min() {
return (getLeftSubTree() == null) ? this : left.min();
}
/**
* Removes the node at a given position.
*
* @param index is the index of the element to be removed relative to the position of
* the parent node of the current node.
*/
DurableAVLNode remove(int index) {
int indexRelativeToMe = index - relativePosition;
if (indexRelativeToMe == 0) {
return removeSelf();
}
if (indexRelativeToMe > 0) {
setRight(right.remove(indexRelativeToMe), right.right);
if (relativePosition < 0) {
relativePosition++;
}
} else {
setLeft(left.remove(indexRelativeToMe), left.left);
if (relativePosition > 0) {
relativePosition--;
}
}
recalcHeight();
return balance();
}
private DurableAVLNode removeMax() {
if (getRightSubTree() == null) {
return removeSelf();
}
setRight(right.removeMax(), right.right);
if (relativePosition < 0) {
relativePosition++;
}
recalcHeight();
return balance();
}
private DurableAVLNode removeMin() {
if (getLeftSubTree() == null) {
return removeSelf();
}
setLeft(left.removeMin(), left.left);
if (relativePosition > 0) {
relativePosition--;
}
recalcHeight();
return balance();
}
/**
* Removes this node from the tree.
*
* @return the node that replaces this one in the parent
*/
private DurableAVLNode removeSelf() {
if (getRightSubTree() == null && getLeftSubTree() == null) {
return null;
}
if (getRightSubTree() == null) {
if (relativePosition > 0) {
left.relativePosition += relativePosition + (relativePosition > 0 ? 0 : 1);
}
left.max().setRight(null, right);
return left;
}
if (getLeftSubTree() == null) {
right.relativePosition += relativePosition - (relativePosition < 0 ? 0 : 1);
right.min().setLeft(null, left);
return right;
}
if (heightRightMinusLeft() > 0) {
// more on the right, so delete from the right
DurableAVLNode rightMin = right.min();
value = rightMin.value;
value.avlNode = this;
if (leftIsPrevious) {
left = rightMin.left;
}
right = right.removeMin();
right.parent = this;
if (relativePosition < 0) {
relativePosition++;
}
} else {
// more on the left or equal, so delete from the left
DurableAVLNode leftMax = left.max();
value = leftMax.value;
value.avlNode = this;
if (rightIsNext) {
right = leftMax.right;
}
DurableAVLNode leftPrevious = left.left;
left = left.removeMax();
if (left == null) {
// special case where left that was deleted was a double link
// only occurs when height difference is equal
left = leftPrevious;
leftIsPrevious = true;
} else {
left.parent = this;
}
if (relativePosition > 0) {
relativePosition--;
}
}
recalcHeight();
return this;
}
//-----------------------------------------------------------------------
/**
* Balances according to the AVL algorithm.
*/
private DurableAVLNode balance() {
switch (heightRightMinusLeft()) {
case 1:
case 0:
case -1:
return this;
case -2:
if (left.heightRightMinusLeft() > 0) {
setLeft(left.rotateLeft(), null);
}
return rotateRight();
case 2:
if (right.heightRightMinusLeft() < 0) {
setRight(right.rotateRight(), null);
}
return rotateLeft();
default:
throw new RuntimeException("tree inconsistent!");
}
}
/**
* Gets the relative position.
*/
private int getOffset(DurableAVLNode node) {
if (node == null) {
return 0;
}
return node.relativePosition;
}
/**
* Sets the relative position.
*/
private int setOffset(DurableAVLNode node, int newOffest) {
if (node == null) {
return 0;
}
int oldOffset = getOffset(node);
node.relativePosition = newOffest;
return oldOffset;
}
/**
* Sets the height by calculation.
*/
private void recalcHeight() {
height = Math.max(
getLeftSubTree() == null ? -1 : getLeftSubTree().height,
getRightSubTree() == null ? -1 : getRightSubTree().height) + 1;
}
/**
* Returns the height of the node or -1 if the node is null.
*/
private int getHeight(DurableAVLNode node) {
return (node == null ? -1 : node.height);
}
/**
* Returns the height difference right - left
*/
private int heightRightMinusLeft() {
return getHeight(getRightSubTree()) - getHeight(getLeftSubTree());
}
private DurableAVLNode rotateLeft() {
DurableAVLNode newTop = right; // can't be faedelung!
DurableAVLNode movedNode = getRightSubTree().getLeftSubTree();
int newTopPosition = relativePosition + getOffset(newTop);
int myNewPosition = -newTop.relativePosition;
int movedPosition = getOffset(newTop) + getOffset(movedNode);
setRight(movedNode, newTop);
newTop.parent = parent;
newTop.setLeft(this, null);
setOffset(newTop, newTopPosition);
setOffset(this, myNewPosition);
setOffset(movedNode, movedPosition);
return newTop;
}
private DurableAVLNode rotateRight() {
DurableAVLNode newTop = left; // can't be faedelung
DurableAVLNode movedNode = getLeftSubTree().getRightSubTree();
int newTopPosition = relativePosition + getOffset(newTop);
int myNewPosition = -newTop.relativePosition;
int movedPosition = getOffset(newTop) + getOffset(movedNode);
setLeft(movedNode, newTop);
newTop.parent = parent;
newTop.setRight(this, null);
setOffset(newTop, newTopPosition);
setOffset(this, myNewPosition);
setOffset(movedNode, movedPosition);
return newTop;
}
/**
* Sets the left field to the node, or the previous node if that is null
*
* @param node the new left subtree node
* @param previous the previous node in the linked list
*/
private void setLeft(DurableAVLNode node, DurableAVLNode previous) {
leftIsPrevious = (node == null);
if (leftIsPrevious) {
left = previous;
} else {
left = node;
left.parent = this;
}
//left = (leftIsPrevious ? previous : node);
recalcHeight();
}
/**
* Sets the right field to the node, or the next node if that is null
*
* @param node the new left subtree node
* @param next the next node in the linked list
*/
private void setRight(DurableAVLNode node, DurableAVLNode next) {
rightIsNext = (node == null);
if (rightIsNext) {
right = next;
} else {
right = node;
right.parent = this;
}
//right = (rightIsNext ? next : node);
recalcHeight();
}
// private void checkFaedelung() {
// DurableAVLNode maxNode = left.max();
// if (!maxNode.rightIsFaedelung || maxNode.right != this) {
// throw new RuntimeException(maxNode + " should right-faedel to " + this);
// }
// DurableAVLNode minNode = right.min();
// if (!minNode.leftIsFaedelung || minNode.left != this) {
// throw new RuntimeException(maxNode + " should left-faedel to " + this);
// }
// }
//
// private int checkTreeDepth() {
// int hright = (getRightSubTree() == null ? -1 : getRightSubTree().checkTreeDepth());
// // System.out.print("checkTreeDepth");
// // System.out.print(this);
// // System.out.print(" left: ");
// // System.out.print(_left);
// // System.out.print(" right: ");
// // System.out.println(_right);
//
// int hleft = (left == null ? -1 : left.checkTreeDepth());
// if (height != Math.max(hright, hleft) + 1) {
// throw new RuntimeException(
// "height should be max" + hleft + "," + hright + " but is " + height);
// }
// return height;
// }
//
// private int checkLeftSubNode() {
// if (getLeftSubTree() == null) {
// return 0;
// }
// int count = 1 + left.checkRightSubNode();
// if (left.relativePosition != -count) {
// throw new RuntimeException();
// }
// return count + left.checkLeftSubNode();
// }
//
// private int checkRightSubNode() {
// DurableAVLNode right = getRightSubTree();
// if (right == null) {
// return 0;
// }
// int count = 1;
// count += right.checkLeftSubNode();
// if (right.relativePosition != count) {
// throw new RuntimeException();
// }
// return count + right.checkRightSubNode();
// }
/**
* Used for debugging.
*/
public String toString() {
return "AVLNode(" + relativePosition + "," + (left != null) + "," + value
+ "," + (getRightSubTree() != null) + ", faedelung " + rightIsNext + " )";
}
}
public DurableAVLNode getRoot() {
return root;
}
}
@@ -0,0 +1,594 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import org.gephi.utils.collection.avl.ParamAVLIterator;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.edge.MetaEdgeImpl;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.iterators.TreeIterator;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
import org.gephi.graph.dhns.predicate.Tautology;
/**
* Business class for managing Edges and MetaEdges.
*
* @author Mathieu Bastian
*/
public class EdgeProcessor {
//Architecture
private final TreeStructure treeStructure;
private final Dhns dhns;
private final GraphViewImpl view;
private final int viewId;
//Cache
private ParamAVLIterator<AbstractEdge> edgeIterator;
public EdgeProcessor(Dhns dhns, GraphViewImpl view) {
this.dhns = dhns;
this.treeStructure = view.getStructure();
this.view = view;
this.viewId = view.getViewId();
this.edgeIterator = new ParamAVLIterator<AbstractEdge>();
}
public AbstractEdge[] clearEdges(AbstractNode node) {
int edgesCount = node.getEdgesInTree().getCount() + node.getEdgesOutTree().getCount();
if (edgesCount == 0) {
return null;
}
AbstractEdge[] clearedEdges = new AbstractEdge[edgesCount];
int i = 0;
if (node.getEdgesInTree().getCount() > 0) {
edgeIterator.setNode(node.getEdgesInTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
removeEdgeFromMetaEdge(edge);
AbstractNode source = edge.getSource(viewId);
view.decEdgesCountTotal(1);
boolean mutual = !edge.isSelfLoop() && node.getEdgesOutTree().hasNeighbour(source);
if (node.isEnabled() && source.isEnabled()) {
view.decEdgesCountEnabled(1);
node.decEnabledInDegree();
source.decEnabledOutDegree();
if (mutual) {
source.decEnabledMutualDegree();
node.decEnabledMutualDegree();
view.decMutualEdgesEnabled(1);
}
}
if (mutual) {
view.decMutualEdgesTotal(1);
}
source.getEdgesOutTree().remove(edge);
clearedEdges[i] = edge;
i++;
}
node.getEdgesInTree().clear();
}
if (node.getEdgesOutTree().getCount() > 0) {
edgeIterator.setNode(node.getEdgesOutTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
removeEdgeFromMetaEdge(edge);
AbstractNode target = edge.getTarget(viewId);
if (!edge.isSelfLoop()) {
view.decEdgesCountTotal(1);
if (node.isEnabled()) {
node.decEnabledOutDegree();
target.decEnabledInDegree();
view.decEdgesCountEnabled(1);
}
}
edge.getTarget(viewId).getEdgesInTree().remove(edge);
clearedEdges[i] = edge;
i++;
}
node.getEdgesOutTree().clear();
}
return clearedEdges;
}
public void clearEdgesWithoutRemove(AbstractNode node) {
if (node.getEdgesInTree().getCount() > 0) {
edgeIterator.setNode(node.getEdgesInTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
removeEdgeFromMetaEdge(edge);
}
}
if (node.getEdgesOutTree().getCount() > 0) {
edgeIterator.setNode(node.getEdgesOutTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
removeEdgeFromMetaEdge(edge);
}
}
}
public void clearMetaEdges(AbstractNode node) {
if (node.getMetaEdgesInTree().getCount() > 0) {
edgeIterator.setNode(node.getMetaEdgesInTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
AbstractNode source = edge.getSource(viewId);
if (!edge.isSelfLoop() && node.getMetaEdgesOutTree().hasNeighbour(source)) {
node.decMutualMetaEdgeDegree();
source.decMutualMetaEdgeDegree();
view.decMutualMetaEdgesTotal(1);
}
source.getMetaEdgesOutTree().remove((MetaEdgeImpl) edge);
view.decMetaEdgesCount(1);
}
node.getMetaEdgesInTree().clear();
}
if (node.getMetaEdgesOutTree().getCount() > 0) {
edgeIterator.setNode(node.getMetaEdgesOutTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
edge.getTarget(viewId).getMetaEdgesInTree().remove((MetaEdgeImpl) edge);
view.decMetaEdgesCount(1);
}
node.getMetaEdgesOutTree().clear();
}
}
public void clearMetaEdgesOutOfRange(AbstractNode enabledNode, AbstractNode rangeNode) {
int rangeStart = rangeNode.getPre();
int rangeLimit = rangeStart + rangeNode.size;
if (enabledNode.getMetaEdgesOutTree().getCount() > 0) {
edgeIterator.setNode(enabledNode.getMetaEdgesOutTree());
while (edgeIterator.hasNext()) {
MetaEdgeImpl metaEdge = (MetaEdgeImpl) edgeIterator.next();
AbstractNode target = metaEdge.getTarget(viewId);
int targetPre = target.getPre();
if (targetPre >= rangeStart && targetPre <= rangeLimit) {
//The meta edge has to be removed because it's in the range
if (!metaEdge.isSelfLoop() && target.getMetaEdgesOutTree().hasNeighbour(enabledNode)) {
enabledNode.decMutualMetaEdgeDegree();
target.decMutualMetaEdgeDegree();
view.decMutualMetaEdgesTotal(1);
}
edgeIterator.remove();
target.getMetaEdgesInTree().remove(metaEdge);
view.decMetaEdgesCount(1);
}
}
}
if (enabledNode.getMetaEdgesInTree().getCount() > 0) {
edgeIterator.setNode(enabledNode.getMetaEdgesInTree());
while (edgeIterator.hasNext()) {
MetaEdgeImpl metaEdge = (MetaEdgeImpl) edgeIterator.next();
int sourcePre = metaEdge.getSource(viewId).getPre();
if (sourcePre >= rangeStart && sourcePre <= rangeLimit) {
//The meta edge has to be removed because it's in the range
edgeIterator.remove();
metaEdge.getSource(viewId).getMetaEdgesOutTree().remove(metaEdge);
view.decMetaEdgesCount(1);
}
}
}
}
public AbstractEdge[] clearAllEdges() {
AbstractEdge[] edges = new AbstractEdge[view.getEdgesCountTotal()];
int i = 0;
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree()); itr.hasNext();) {
AbstractNode node = itr.next();
edgeIterator.setNode(node.getEdgesOutTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
dhns.getGraphStructure().removeFromDictionnary(edge);
edges[i++] = edge;
}
node.getEdgesInTree().clear();
node.getEdgesOutTree().clear();
node.setEnabledInDegree(0);
node.setEnabledOutDegree(0);
node.setEnabledMutualDegree(0);
node.clearMetaEdges();
}
view.setEdgesCountTotal(0);
view.setEdgesCountEnabled(0);
view.setMutualEdgesEnabled(0);
view.setMutualEdgesTotal(0);
return edges;
}
public void clearAllMetaEdges() {
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree()); itr.hasNext();) {
AbstractNode node = itr.next();
node.clearMetaEdges();
node.setMutualMetaEdgeDegree(0);
}
view.setMetaEdgesCountTotal(0);
view.setMutualMetaEdgesTotal(0);
}
public void computeMetaEdges(AbstractNode node, AbstractNode enabledAncestor) {
if (!dhns.getSettingsManager().isAutoMetaEdgeCreation()) {
return;
}
if (enabledAncestor == null) {
enabledAncestor = node;
}
int clusterEnd = node.getPre() + node.size;
for (int i = node.pre; i <= clusterEnd; i++) {
AbstractNode desc = treeStructure.getNodeAt(i);
if (desc.getEdgesOutTree().getCount() > 0) {
edgeIterator.setNode(desc.getEdgesOutTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
AbstractNode[] enabledAncestors = treeStructure.getEnabledAncestorsOrSelf(edge.getTarget(viewId));
if (enabledAncestors != null) {
for (int j = 0; j < enabledAncestors.length; j++) {
AbstractNode targetNode = enabledAncestors[j];
if (!(targetNode == edge.getTarget(viewId) && enabledAncestor == edge.getSource(viewId))) {
createMetaEdge(enabledAncestor, targetNode, edge);
}
}
}
// AbstractNode targetNode = treeStructure.getEnabledAncestorOrSelf(edge.getTarget(viewId));
// if (targetNode != null && !(targetNode == edge.getTarget(viewId) && enabledAncestor == edge.getSource(viewId))) {
// //Create Meta Edge if not exist
// createMetaEdge(enabledAncestor, targetNode, edge);
// }
}
}
if (desc.getEdgesInTree().getCount() > 0) {
edgeIterator.setNode(desc.getEdgesInTree());
while (edgeIterator.hasNext()) {
AbstractEdge edge = edgeIterator.next();
AbstractNode[] enabledAncestors = treeStructure.getEnabledAncestorsOrSelf(edge.getSource(viewId));
if (enabledAncestors != null) {
for (int j = 0; j < enabledAncestors.length; j++) {
AbstractNode sourceNode = enabledAncestors[j];
if (!(sourceNode == edge.getSource(viewId) && enabledAncestor == edge.getTarget(viewId))) {
createMetaEdge(sourceNode, enabledAncestor, edge);
}
}
}
// AbstractNode sourceNode = treeStructure.getEnabledAncestorOrSelf(edge.getSource(viewId));
// if (sourceNode != null && !(sourceNode == edge.getSource(viewId) && enabledAncestor == edge.getTarget(viewId))) {
// //Create Meta Edge if not exist
// createMetaEdge(sourceNode, enabledAncestor, edge);
// }
}
}
}
}
public void computeMetaEdges() {
for (TreeIterator itr = new TreeIterator(treeStructure, true, Tautology.instance); itr.hasNext();) {
AbstractNode node = itr.next();
computeMetaEdges(node, node);
}
}
private void createMetaEdge(AbstractNode source, AbstractNode target, AbstractEdge edge) {
AbstractNode edgeSource = edge.getSource(viewId);
AbstractNode edgeTarget = edge.getTarget(viewId);
if (edgeSource == source && edgeTarget == target) {
return;
}
if (source == target) {
return;
}
MetaEdgeImpl metaEdge = getMetaEdge(source, target);
if (metaEdge == null) {
metaEdge = createMetaEdge(source, target);
}
if (metaEdge != null) {
if (metaEdge.addEdge(edge)) {
dhns.getSettingsManager().getMetaEdgeBuilder().pushEdge(edge, edgeSource, edgeTarget, metaEdge);
}
}
}
private MetaEdgeImpl createMetaEdge(AbstractNode source, AbstractNode target) {
if (source == target) {
return null;
}
MetaEdgeImpl newEdge = dhns.factory().newMetaEdge(source, target);
source.getMetaEdgesOutTree().add(newEdge);
target.getMetaEdgesInTree().add(newEdge);
if (!newEdge.isSelfLoop() && target.getMetaEdgesOutTree().hasNeighbour(source)) {
source.incMutualMetaEdgeDegree();
target.incMutualMetaEdgeDegree();
view.incMutualMetaEdgesTotal(1);
}
view.incMetaEdgesCount(1);
return newEdge;
}
public void createMetaEdge(AbstractEdge edge) {
if (!dhns.getSettingsManager().isAutoMetaEdgeCreation()) {
return;
}
if (edge.isSelfLoop()) {
return;
}
AbstractNode[] sourceAncestors = treeStructure.getEnabledAncestorsOrSelf(edge.getSource(viewId));
AbstractNode[] targetAncestors = treeStructure.getEnabledAncestorsOrSelf(edge.getTarget(viewId));
if (sourceAncestors != null && targetAncestors != null) {
for (int i = 0; i < sourceAncestors.length; i++) {
for (int j = 0; j < targetAncestors.length; j++) {
AbstractNode sourceParent = sourceAncestors[i];
AbstractNode targetParent = targetAncestors[j];
if (sourceParent != targetParent) {
createMetaEdge(sourceParent, targetParent, edge);
}
}
}
}
// AbstractNode sourceParent = treeStructure.getEnabledAncestorOrSelf(edge.getSource(viewId));
// AbstractNode targetParent = treeStructure.getEnabledAncestorOrSelf(edge.getTarget(viewId));
//
// if (sourceParent != null && targetParent != null && sourceParent != targetParent) {
// createMetaEdge(sourceParent, targetParent, edge);
// }
}
public void removeEdgeFromMetaEdge(AbstractEdge edge) {
if (!dhns.getSettingsManager().isAutoMetaEdgeCreation()) {
return;
}
if (edge.isSelfLoop()) {
return;
}
MetaEdgeImpl metaEdge = getMetaEdge(edge);
if (metaEdge != null) {
if (metaEdge.removeEdge(edge)) {
AbstractNode edgeSource = edge.getSource(viewId);
AbstractNode edgeTarget = edge.getTarget(viewId);
dhns.getSettingsManager().getMetaEdgeBuilder().pullEdge(edge, edgeSource, edgeTarget, metaEdge);
}
if (metaEdge.isEmpty()) {
AbstractNode source = metaEdge.getSource(viewId);
AbstractNode target = metaEdge.getTarget(viewId);
if(!metaEdge.isSelfLoop() && source.getMetaEdgesInTree().hasNeighbour(target)) {
source.decMutualMetaEdgeDegree();
target.decMutualMetaEdgeDegree();
view.decMutualMetaEdgesTotal(1);
}
source.getMetaEdgesOutTree().remove(metaEdge);
target.getMetaEdgesInTree().remove(metaEdge);
view.decMetaEdgesCount(1);
}
}
}
private MetaEdgeImpl getMetaEdge(AbstractNode source, AbstractNode target) {
if (source == target) {
return null;
}
return source.getMetaEdgesOutTree().getItem(target.getNumber());
}
private MetaEdgeImpl getMetaEdge(AbstractEdge edge) {
if (edge.isSelfLoop()) {
return null;
}
AbstractNode sourceParent = treeStructure.getEnabledAncestorOrSelf(edge.getSource(viewId));
AbstractNode targetParent = treeStructure.getEnabledAncestorOrSelf(edge.getTarget(viewId));
if (sourceParent != null && targetParent != null && sourceParent != targetParent) {
return getMetaEdge(sourceParent, targetParent);
}
return null;
}
public AbstractEdge[] flattenNode(AbstractNode node) {
AbstractEdge[] newEdges = null;
if (!node.getMetaEdgesInTree().isEmpty() || !node.getMetaEdgesOutTree().isEmpty()) {
newEdges = new AbstractEdge[node.getMetaEdgesInTree().getCount() + node.getMetaEdgesOutTree().getCount()];
}
int i = 0;
if (!node.getMetaEdgesInTree().isEmpty()) {
for (edgeIterator.setNode(node.getMetaEdgesInTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode source = edge.getSource(viewId);
edgeIterator.remove();
source.getMetaEdgesOutTree().remove((MetaEdgeImpl) edge);
view.decMetaEdgesCount(1);
if(node.getMetaEdgesOutTree().hasNeighbour(source)) {
source.decMutualMetaEdgeDegree();
}
if (!node.getEdgesInTree().hasNeighbour(source)) {
AbstractEdge realEdge = dhns.factory().newEdge(source, node, edge.getWeight(), edge.isDirected());
realEdge.getEdgeData().moveFrom(edge.getEdgeData());
realEdge.setWeight(edge.getWeight());
newEdges[i] = realEdge;
source.getEdgesOutTree().add(realEdge);
node.getEdgesInTree().add(realEdge);
source.incEnabledOutDegree();
node.incEnabledInDegree();
view.incEdgesCountEnabled(1);
view.incEdgesCountTotal(1);
if (source.getEdgesInTree().hasNeighbour(node)) {
//Mutual
source.incEnabledMutualDegree();
node.incEnabledMutualDegree();
view.incMutualEdgesEnabled(1);
view.incMutualEdgesTotal(1);
}
}
i++;
}
}
if (!node.getMetaEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(node.getMetaEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode target = edge.getTarget(viewId);
edgeIterator.remove();
target.getMetaEdgesInTree().remove((MetaEdgeImpl) edge);
view.decMetaEdgesCount(1);
if (!node.getEdgesOutTree().hasNeighbour(target)) {
AbstractEdge realEdge = dhns.factory().newEdge(node, target, edge.getWeight(), edge.isDirected());
realEdge.getEdgeData().moveFrom(edge.getEdgeData());
realEdge.setWeight(edge.getWeight());
newEdges[i] = realEdge;
node.getEdgesOutTree().add(realEdge);
target.getEdgesInTree().add(realEdge);
node.incEnabledOutDegree();
target.incEnabledInDegree();
view.incEdgesCountEnabled(1);
view.incEdgesCountTotal(1);
if (target.getEdgesOutTree().hasNeighbour(node)) {
//Mutual
node.incEnabledMutualDegree();
target.incEnabledMutualDegree();
view.incMutualEdgesEnabled(1);
view.incMutualEdgesTotal(1);
}
}
i++;
}
}
view.decMutualMetaEdgesTotal(node.getMutualMetaEdgeDegree());
node.setMutualMetaEdgeDegree(0);
return newEdges;
}
public void incrementEdgesCounting(AbstractNode enabledNode, AbstractNode parent) {
for (edgeIterator.setNode(enabledNode.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode target = edge.getTarget(view.getViewId());
if (target.isEnabled()) {
view.incEdgesCountEnabled(1);
enabledNode.incEnabledOutDegree();
target.incEnabledInDegree();
if (target.getEdgesOutTree().hasNeighbour(enabledNode)) {
if (parent == null || (parent != null && target.parent != parent) || (parent != null && target.parent == parent && target.getId() < enabledNode.getId())) {
view.incMutualEdgesEnabled(1);
enabledNode.incEnabledMutualDegree();
target.incEnabledMutualDegree();
}
}
}
}
for (edgeIterator.setNode(enabledNode.getEdgesInTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode source = edge.getSource(view.getViewId());
if (source.isEnabled() && (parent == null || source.parent != parent)) {
view.incEdgesCountEnabled(1);
enabledNode.incEnabledInDegree();
source.incEnabledOutDegree();
}
}
}
public void decrementEdgesCouting(AbstractNode disabledNode, AbstractNode parent) {
for (edgeIterator.setNode(disabledNode.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode target = edge.getTarget(view.getViewId());
if (target.isEnabled() || (parent != null && target.parent == parent) || edge.isSelfLoop()) {
target.decEnabledInDegree();
disabledNode.decEnabledOutDegree();
view.decEdgesCountEnabled(1);
if (target.getEdgesOutTree().hasNeighbour(disabledNode) && (parent == null || (parent != null && target.parent == parent && target.getId() < disabledNode.getId())) && !edge.isSelfLoop()) {
target.decEnabledMutualDegree();
disabledNode.decEnabledMutualDegree();
view.decMutualEdgesEnabled(1);
}
}
}
for (edgeIterator.setNode(disabledNode.getEdgesInTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode source = edge.getSource(view.getViewId());
if (source.isEnabled()) {
view.decEdgesCountEnabled(1);
disabledNode.decEnabledInDegree();
source.decEnabledOutDegree();
}
}
}
public void resetEdgesCounting(AbstractNode node) {
node.setEnabledInDegree(0);
node.setEnabledOutDegree(0);
node.setEnabledMutualDegree(0);
}
public void computeEdgesCounting(AbstractNode node) {
for (edgeIterator.setNode(node.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode target = edge.getTarget(view.getViewId());
if (target.isEnabled()) {
target.incEnabledInDegree();
node.incEnabledOutDegree();
view.incEdgesCountEnabled(1);
if (target.getEdgesOutTree().hasNeighbour(node) && target.getId() < node.getId()) {
target.incEnabledMutualDegree();
node.incEnabledMutualDegree();
view.incMutualEdgesEnabled(1);
}
}
}
}
}
@@ -0,0 +1,266 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.GraphEvent;
import org.gephi.graph.api.GraphListener;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.api.Node;
import org.gephi.graph.dhns.event.AbstractEvent;
import org.gephi.graph.dhns.event.EdgeEvent;
import org.gephi.graph.dhns.event.GeneralEvent;
import org.gephi.graph.dhns.event.GraphEventDataImpl;
import org.gephi.graph.dhns.event.GraphEventImpl;
import org.gephi.graph.dhns.event.NodeEvent;
import org.gephi.graph.dhns.event.ViewEvent;
/**
*
* @author Mathieu Bastian
*/
public class EventManager implements Runnable {
//Const
private final static long DELAY = 100;
//Architecture
private final List<GraphListener> listeners;
private final AtomicReference<Thread> thread = new AtomicReference<Thread>();
private final LinkedBlockingQueue<AbstractEvent> eventQueue;
private final Object lock = new Object();
private final LinkedList<Integer> rateList = new LinkedList<Integer>();
private double avgRate = 1.0;
//Flag
private boolean stop;
public EventManager(Dhns dhns) {
this.eventQueue = new LinkedBlockingQueue<AbstractEvent>();
this.listeners = Collections.synchronizedList(new ArrayList<GraphListener>());
rateList.add(1);
}
@Override
public void run() {
int rate = 0;
while (!stop) {
if (rate == (int) avgRate) {
try {
Thread.sleep(DELAY);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
int w = (int) (eventQueue.size() * 0.1f);
w = Math.max(1, w);
updateRate(w);
rate++;
}
List<Object> eventCompress = null;
AbstractEvent precEvt = null;
AbstractEvent evt = null;
while ((evt = eventQueue.peek()) != null) {
if (precEvt != null) {
if ((evt instanceof NodeEvent || evt instanceof EdgeEvent) && precEvt.getEventType().equals(evt.getEventType()) && precEvt.getView() == evt.getView()) { //Same type
if (eventCompress == null) {
eventCompress = new ArrayList<Object>();
eventCompress.add(precEvt.getData());
}
eventCompress.add(evt.getData());
} else {
break;
}
}
eventQueue.poll();
precEvt = evt;
}
if (precEvt != null) {
GraphEvent event = createEvent(precEvt, eventCompress);
for (GraphListener l : listeners.toArray(new GraphListener[0])) {
l.graphChanged(event);
}
}
rate++;
while (eventQueue.isEmpty()) {
rate = (int) avgRate;
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e) {
}
}
}
}
private GraphEvent createEvent(AbstractEvent event, List<Object> compress) {
final GraphEventDataImpl eventData = (event instanceof GeneralEvent) ? null : new GraphEventDataImpl();
final GraphEventImpl graphEventImpl = new GraphEventImpl(event.getView(), event.getEventType(), eventData);
if (event instanceof NodeEvent || event instanceof EdgeEvent) {
List<Node> nodes = null;
List<Edge> edges = null;
if (compress != null) {
for (Object o : compress) {
if (o instanceof Node) {
if (nodes == null) {
nodes = new ArrayList<Node>();
}
nodes.add((Node) o);
} else {
if (edges == null) {
edges = new ArrayList<Edge>();
}
edges.add((Edge) o);
}
}
switch (event.getEventType()) {
case ADD_NODES_AND_EDGES:
if (nodes != null) {
eventData.setAddedNodes(nodes.toArray(new Node[0]));
}
if (edges != null) {
eventData.setAddedEdges(edges.toArray(new Edge[0]));
}
break;
case REMOVE_NODES_AND_EDGES:
if (nodes != null) {
eventData.setRemovedNodes(nodes.toArray(new Node[0]));
}
if (edges != null) {
eventData.setRemovedEdges(edges.toArray(new Edge[0]));
}
break;
case EXPAND:
eventData.setExpandedNodes(nodes.toArray(new Node[0]));
break;
case RETRACT:
eventData.setRetractedNodes(nodes.toArray(new Node[0]));
break;
case MOVE_NODES:
eventData.setMovedNodes(nodes.toArray(new Node[0]));
break;
}
} else {
switch (event.getEventType()) {
case ADD_NODES_AND_EDGES:
if (event instanceof NodeEvent) {
eventData.setAddedNodes(new Node[]{(Node) event.getData()});
} else {
eventData.setAddedEdges(new Edge[]{(Edge) event.getData()});
}
break;
case REMOVE_NODES_AND_EDGES:
if (event instanceof NodeEvent) {
eventData.setRemovedNodes(new Node[]{(Node) event.getData()});
} else {
eventData.setRemovedEdges(new Edge[]{(Edge) event.getData()});
}
break;
case EXPAND:
eventData.setExpandedNodes(new Node[]{(Node) event.getData()});
break;
case RETRACT:
eventData.setRetractedNodes(new Node[]{(Node) event.getData()});
break;
case MOVE_NODES:
eventData.setMovedNodes(new Node[]{(Node) event.getData()});
break;
}
}
} else if (event instanceof ViewEvent) {
eventData.setView((GraphView) event.getData());
}
return graphEventImpl;
}
private double updateRate(int n) {
int windowLength = 10;
if (rateList.size() == windowLength) {
Integer oldest = rateList.poll();
avgRate = ((avgRate * windowLength) - oldest) / (windowLength - 1);
}
avgRate = ((avgRate * rateList.size()) + n) / (rateList.size() + 1);
rateList.add(n);
return avgRate;
}
public void stop(boolean stop) {
this.stop = stop;
}
public void fireEvent(AbstractEvent event) {
eventQueue.add(event);
synchronized (lock) {
lock.notifyAll();
}
}
public void start() {
Thread t = new Thread(this);
t.setDaemon(true);
t.setName("graph-event-bus");
if (this.thread.compareAndSet(null, t)) {
t.start();
}
}
public boolean isRunning() {
return thread.get() != null;
}
public void addGraphListener(GraphListener listener) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
public void removeGraphListener(GraphListener listener) {
listeners.remove(listener);
}
}
@@ -0,0 +1,191 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import org.gephi.data.attributes.api.AttributeRow;
import org.gephi.data.attributes.api.AttributeRowFactory;
import org.gephi.graph.api.Attributes;
import org.gephi.graph.api.EdgeData;
import org.gephi.graph.api.GraphFactory;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.api.Node;
import org.gephi.graph.api.NodeData;
import org.gephi.graph.api.TextData;
import org.gephi.graph.spi.TextDataFactory;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.edge.MetaEdgeImpl;
import org.gephi.graph.dhns.edge.ProperEdgeImpl;
import org.gephi.graph.dhns.edge.SelfLoopImpl;
import org.gephi.graph.dhns.edge.MixedEdgeImpl;
import org.gephi.graph.dhns.node.AbstractNode;
import org.openide.util.Lookup;
/**
* Implementation of a basic node and edge factory. If possible set {@link Attributes} to objets.
* <p>
* Return {@link AbstractNode} or {@link AbstractEdge}.
*
* @author Mathieu Bastian
*/
public class GraphFactoryImpl implements GraphFactory {
private IDGen idGen;
private AttributeRowFactory attributesFactory;
private TextDataFactory textDataFactory;
public GraphFactoryImpl(IDGen idGen, AttributeRowFactory attributesFactory) {
this.idGen = idGen;
this.attributesFactory = attributesFactory;
this.textDataFactory = Lookup.getDefault().lookup(TextDataFactory.class);
}
public AttributeRow newNodeAttributes(NodeData nodeData) {
if (attributesFactory == null) {
return null;
}
return attributesFactory.newNodeRow(nodeData);
}
public AttributeRow newEdgeAttributes(EdgeData edgeData) {
if (attributesFactory == null) {
return null;
}
return attributesFactory.newEdgeRow(edgeData);
}
public AttributeRow newGraphAttributes(GraphView graphView) {
if (attributesFactory == null) {
return null;
}
return attributesFactory.newGraphRow(graphView);
}
public TextData newTextData() {
if (textDataFactory == null) {
return null;
}
return textDataFactory.newTextData();
}
public AbstractNode newNode() {
return newNode(null, 0);
}
public AbstractNode newNode(int viewId) {
return newNode(null, viewId);
}
public AbstractNode newNode(String id, int viewId) {
AbstractNode node = new AbstractNode(idGen.newNodeId(), viewId, 0, 0, 0, null); //with wiew = 0
node.getNodeData().setAttributes(newNodeAttributes(node.getNodeData()));
node.getNodeData().setTextData(newTextData());
if (id != null) {
node.getNodeData().setId(id);
} else {
node.getNodeData().setId("" + node.getId());
}
return node;
}
public AbstractNode newNode(String id) {
return newNode(id, 0);
}
public AbstractEdge newEdge(Node source, Node target) {
if (source == null || target == null) {
throw new NullPointerException();
}
AbstractNode nodeSource = (AbstractNode) source;
AbstractNode nodeTarget = (AbstractNode) target;
AbstractEdge edge;
if (source == target) {
edge = new SelfLoopImpl(idGen.newEdgeId(), nodeSource);
} else {
edge = new ProperEdgeImpl(idGen.newEdgeId(), nodeSource, nodeTarget);
}
edge.setAttributes(newEdgeAttributes(edge.getEdgeData()));
edge.getEdgeData().setTextData(newTextData());
edge.getEdgeData().setId("" + edge.getId());
return edge;
}
public AbstractEdge newEdge(Node source, Node target, float weight, boolean directed) {
return newEdge(null, source, target, weight, directed);
}
public AbstractEdge newEdge(String id, Node source, Node target, float weight, boolean directed) {
if (source == null || target == null) {
throw new NullPointerException();
}
AbstractNode nodeSource = (AbstractNode) source;
AbstractNode nodeTarget = (AbstractNode) target;
AbstractEdge edge;
if (source == target) {
edge = new SelfLoopImpl(idGen.newEdgeId(), nodeSource);
} else {
edge = new MixedEdgeImpl(idGen.newEdgeId(), nodeSource, nodeTarget, directed);
}
edge.setAttributes(newEdgeAttributes(edge.getEdgeData()));
edge.setWeight(weight);
edge.getEdgeData().setTextData(newTextData());
if (id != null) {
edge.getEdgeData().setId(id);
} else {
edge.getEdgeData().setId("" + edge.getId());
}
return edge;
}
public MetaEdgeImpl newMetaEdge(Node source, Node target) {
if (source == null || target == null) {
throw new NullPointerException();
}
AbstractNode nodeSource = (AbstractNode) source;
AbstractNode nodeTarget = (AbstractNode) target;
MetaEdgeImpl edge = new MetaEdgeImpl(idGen.newEdgeId(), nodeSource, nodeTarget);
edge.setAttributes(newEdgeAttributes(edge.getEdgeData()));
edge.getEdgeData().setTextData(newTextData());
edge.getEdgeData().setId("" + edge.getId());
return edge;
}
}
@@ -0,0 +1,434 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import gnu.trove.TIntObjectHashMap;
import gnu.trove.TObjectIntHashMap;
import java.lang.ref.WeakReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;
import org.gephi.utils.collection.avl.ParamAVLIterator;
import org.gephi.graph.api.GraphEvent.EventType;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.event.ViewEvent;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.NodeDataImpl;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
/**
*
* @author Mathieu Bastian
*/
public class GraphStructure {
private final AtomicInteger viewId = new AtomicInteger(1);
private final Dhns dhns;
private final GraphViewImpl mainView;
private final Queue<GraphViewImpl> views;
private final GraphDictionnary dictionnary;
private GraphViewImpl visibleView;
//Destroy
private final Object lock = new Object();
private final ConcurrentLinkedQueue<GraphViewImpl> destroyQueue;
public GraphStructure(Dhns dhns) {
this.dhns = dhns;
views = new ConcurrentLinkedQueue<GraphViewImpl>();
dictionnary = new GraphDictionnary();
//Main view
mainView = new GraphViewImpl(dhns, 0);
views.add(mainView);
visibleView = mainView;
//Destructor
destroyQueue = new ConcurrentLinkedQueue<GraphViewImpl>();
ViewDestructorThread viewDestructorThread = new ViewDestructorThread(this);
viewDestructorThread.start();
}
public GraphViewImpl[] getViews() {
return views.toArray(new GraphViewImpl[0]);
}
public GraphViewImpl getMainView() {
return mainView;
}
public GraphViewImpl createView(int viewId) { //used by deserializer
this.viewId.set(Math.max(viewId + 1, this.viewId.get()));
return new GraphViewImpl(dhns, viewId);
}
public GraphViewImpl getNewView() {
return copyView(mainView);
}
public GraphViewImpl copyView(GraphViewImpl view) {
GraphViewImpl viewCopy = new GraphViewImpl(dhns, viewId.getAndIncrement());
TreeStructure newStructure = viewCopy.getStructure();
dhns.writeLock();
for (TreeListIterator itr = new TreeListIterator(view.getStructure().getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
AbstractNode nodeCopy = new AbstractNode(node.getNodeData(), viewCopy.getViewId());
nodeCopy.setEnabled(node.isEnabled());
nodeCopy.setEnabledInDegree(node.getEnabledInDegree());
nodeCopy.setEnabledOutDegree(node.getEnabledOutDegree());
nodeCopy.setEnabledMutualDegree(node.getEnabledMutualDegree());
AbstractNode parentCopy = node.parent != null ? newStructure.getNodeAt(node.parent.getPre()) : null;
newStructure.insertAsChild(nodeCopy, parentCopy);
}
//Edges
ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>();
for (TreeListIterator itr = new TreeListIterator(view.getStructure().getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
if (!node.getEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(node.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
AbstractNode sourceCopy = newStructure.getNodeAt(node.getPre());
AbstractNode targetCopy = newStructure.getNodeAt(((AbstractNode) edge.getTarget().getNodeData().getNode(view.getViewId())).getPre());
sourceCopy.getEdgesOutTree().add(edge);
targetCopy.getEdgesInTree().add(edge);
addToDictionnary(edge);
}
}
}
viewCopy.setNodesEnabled(view.getNodesEnabled());
viewCopy.setEdgesCountTotal(view.getEdgesCountTotal());
viewCopy.setEdgesCountEnabled(view.getEdgesCountEnabled());
viewCopy.setMutualEdgesTotal(view.getMutualEdgesTotal());
viewCopy.setMutualEdgesEnabled(view.getMutualEdgesEnabled());
//Metaedges
viewCopy.getStructureModifier().getEdgeProcessor().computeMetaEdges();
views.add(viewCopy);
dhns.writeUnlock();
dhns.getEventManager().fireEvent(new ViewEvent(EventType.NEW_VIEW, viewCopy));
return viewCopy;
}
public void destroyView(final GraphViewImpl view) {
if (views.contains(view)) {
destroyQueue.add(view);
synchronized (this.lock) {
lock.notify();
}
}
}
public void addToDictionnary(AbstractNode node) {
dictionnary.addNode(node);
}
public void removeFromDictionnary(AbstractNode node) {
dictionnary.removeNode(node);
}
public void addToDictionnary(AbstractEdge edge) {
dictionnary.addEdge(edge);
}
public void removeFromDictionnary(AbstractEdge edge) {
dictionnary.removeEdge(edge);
}
public AbstractEdge getEdgeFromDictionnary(int id) {
return dictionnary.getEdge(id);
}
public AbstractEdge getEdgeFromDictionnary(String id) {
return dictionnary.getEdge(id);
}
public AbstractNode getNodeFromDictionnary(int id, int viewId) {
return dictionnary.getNode(id, viewId);
}
public AbstractNode getNodeFromDictionnary(String id, int viewId) {
return dictionnary.getNode(id, viewId);
}
public void setNodeId(NodeDataImpl node, String id) {
String oldId = node.setId(id);
dictionnary.setNodeId(oldId, id, node);
}
public void setEdgeId(AbstractEdge edge, String id) {
String oldId = edge.getEdgeData().setId(id);
dictionnary.setEdgeId(oldId, id, edge);
}
public GraphViewImpl getVisibleView() {
return visibleView;
}
public void setVisibleView(GraphViewImpl visibleView) {
if (this.visibleView == visibleView) {
return;
}
if (visibleView == null) {
this.visibleView = mainView;
} else {
this.visibleView = visibleView;
}
dhns.getEventManager().fireEvent(new ViewEvent(EventType.VISIBLE_VIEW, this.visibleView));
}
private static class ViewDestructorThread extends Thread {
private final WeakReference<GraphStructure> structureReference;
private final int STD_TIMER = 300;
private final int UNDESTRO_TIMER = 2000;
private boolean running = true;
public ViewDestructorThread(GraphStructure graphStructure) {
super("DHNS View Destructor");
setDaemon(true);
structureReference = new WeakReference<GraphStructure>(graphStructure);
}
@Override
public void run() {
GraphStructure structure = null;
while (running && (structure = structureReference.get()) != null) {
while (structure.destroyQueue.isEmpty()) {
try {
synchronized (structure.lock) {
structure.lock.wait();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
boolean undestroyableViews = false;
for (GraphViewImpl v : structure.destroyQueue.toArray(new GraphViewImpl[0])) {
if (!v.hasGraphReference()) {
destroyView(structure, v);
structure.destroyQueue.remove(v);
} else {
undestroyableViews = true;
}
}
try {
synchronized (structure.lock) {
structure.lock.wait(undestroyableViews ? UNDESTRO_TIMER : STD_TIMER);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
private void destroyView(GraphStructure structure, GraphViewImpl view) {
//Logger.getLogger("").log(Level.WARNING, "Destroy view {0}", view.getViewId());
structure.dhns.writeLock();
ParamAVLIterator<AbstractEdge> edgeIterator = new ParamAVLIterator<AbstractEdge>();
for (TreeListIterator itr = new TreeListIterator(structure.mainView.getStructure().getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
AbstractNode nodeInView = node.getNodeData().getNodes().get(view.getViewId());
if (nodeInView != null) {
node.getNodeData().getNodes().remove(view.getViewId());
if (!nodeInView.getEdgesOutTree().isEmpty()) {
for (edgeIterator.setNode(nodeInView.getEdgesOutTree()); edgeIterator.hasNext();) {
AbstractEdge edge = edgeIterator.next();
structure.removeFromDictionnary(edge);
}
}
}
}
structure.views.remove(view);
//System.out.println("Destroy view finished");
structure.dhns.writeUnlock();
structure.dhns.getEventManager().fireEvent(new ViewEvent(EventType.DESTROY_VIEW, view));
if (structure.visibleView == view) {
structure.visibleView = structure.mainView;
structure.dhns.getEventManager().fireEvent(new ViewEvent(EventType.VISIBLE_VIEW, structure.mainView));
}
}
}
private static class GraphDictionnary {
private final TObjectIntHashMap<String> nodesMap;
private final TIntObjectHashMap<NodeDataImpl> nodesIntMap;
private final TIntObjectHashMap<EdgeCounter> edgesRefCount;
private final TObjectIntHashMap<String> edgesMap;
public GraphDictionnary() {
nodesMap = new TObjectIntHashMap<String>();
nodesIntMap = new TIntObjectHashMap<NodeDataImpl>();
edgesRefCount = new TIntObjectHashMap<EdgeCounter>();
edgesMap = new TObjectIntHashMap<String>();
}
public synchronized void addNode(AbstractNode node) {
if (node.getNodeData().getId() != null) {
nodesMap.put(node.getNodeData().getId(), node.getId());
}
nodesIntMap.put(node.getId(), node.getNodeData());
}
public synchronized void removeNode(AbstractNode node) {
if (node.getNodeData().getNodes().getCount() == 1) {
if (node.getNodeData().getId() != null) {
nodesMap.remove(node.getNodeData().getId());
}
nodesIntMap.remove(node.getId());
}
}
public synchronized void addEdge(AbstractEdge edge) {
EdgeCounter edgeCounter = edgesRefCount.get(edge.getId());
if (edgeCounter != null) {
edgeCounter.inc();
} else {
edgeCounter = new EdgeCounter(edge);
edgesRefCount.put(edge.getId(), edgeCounter);
String id = edge.getEdgeData().getId();
if (id != null) {
edgesMap.put(id, edge.getId());
}
}
}
public synchronized void removeEdge(AbstractEdge edge) {
EdgeCounter edgeCounter = edgesRefCount.get(edge.getId());
int count = edgeCounter.decAndGet();
if (count == 0) {
edgesRefCount.remove(edge.getId());
String id = edge.getEdgeData().getId();
if (id != null) {
edgesMap.remove(id);
}
}
}
public synchronized AbstractNode getNode(int id, int viewId) {
NodeDataImpl nodeDataImpl = nodesIntMap.get(id);
if (nodeDataImpl != null) {
return (AbstractNode) nodeDataImpl.getNode(viewId);
}
return null;
}
public synchronized AbstractNode getNode(String id, int viewId) {
int natId = nodesMap.get(id);
if (natId != 0) {
return getNode(natId, viewId);
}
return null;
}
public synchronized AbstractEdge getEdge(int id) {
EdgeCounter edgeCounter = edgesRefCount.get(id);
if (edgeCounter != null) {
return edgeCounter.edge;
}
return null;
}
public synchronized AbstractEdge getEdge(String id) {
int natId = edgesMap.get(id);
if (natId != 0) {
return getEdge(natId);
}
return null;
}
public synchronized void setNodeId(String oldId, String newId, NodeDataImpl node) {
if (oldId != null) {
int val = nodesMap.remove(oldId);
nodesMap.put(newId, val);
} else {
nodesMap.put(newId, node.getID());
}
}
public synchronized void setEdgeId(String oldId, String newId, AbstractEdge edge) {
if (oldId != null) {
int val = edgesMap.remove(oldId);
edgesMap.put(newId, val);
} else {
edgesMap.put(newId, edge.getId());
}
}
private static class EdgeCounter {
protected final AbstractEdge edge;
private int counter = 1;
public EdgeCounter(AbstractEdge edge) {
this.edge = edge;
}
private void inc() {
counter++;
}
private int decAndGet() {
return --counter;
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj instanceof EdgeCounter) {
EdgeCounter e = (EdgeCounter) obj;
return e.edge.equals(edge);
} else if (obj != null && obj instanceof AbstractEdge) {
return obj.equals(edge);
}
return false;
}
@Override
public int hashCode() {
return edge.hashCode();
}
}
}
}
@@ -0,0 +1,95 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Trace system to log node and edge modification. External modules can compare to their local integer
* to know if they need to update the graph.
*
* @author Mathieu Bastian
*/
public class GraphVersion {
// private int nodeVersion;
// private int edgeVersion;
private AtomicInteger nodeVersion = new AtomicInteger();
private AtomicInteger edgeVersion = new AtomicInteger();
public GraphVersion() {
// nodeVersion = 0;
// edgeVersion = 0;
}
public int getNodeVersion() {
// return nodeVersion;
return nodeVersion.get();
}
public int getEdgeVersion() {
// return edgeVersion;
return edgeVersion.get();
}
public void incNodeVersion() {
// nodeVersion++;
nodeVersion.incrementAndGet();
}
public void incEdgeVersion() {
// edgeVersion++;
edgeVersion.incrementAndGet();
}
public void incNodeAndEdgeVersion() {
// nodeVersion++;
// edgeVersion++;
nodeVersion.incrementAndGet();
edgeVersion.incrementAndGet();
}
public void setVersion(int nodeVersion, int edgeVersion) {
this.nodeVersion.set(nodeVersion);
this.edgeVersion.set(edgeVersion);
}
}
@@ -0,0 +1,231 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.WeakHashMap;
import org.gephi.data.attributes.api.AttributeRow;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.dhns.graph.AbstractGraphImpl;
/**
*
* @author Mathieu Bastian
*/
public class GraphViewImpl implements GraphView {
private final Dhns dhns;
private final int viewId;
private final TreeStructure structure;
private final StructureModifier structureModifier;
private final AttributeRow attributeRow;
private int nodesEnabled;
private int edgesCountTotal;
private int mutualEdgesTotal;
private int edgesCountEnabled;
private int mutualEdgesEnabled;
private int metaEdgesCountTotal;
private int mutualMetaEdgesTotal;
//RefCounting
private final WeakHashMap<AbstractGraphImpl, Boolean> graphsMap = new WeakHashMap<AbstractGraphImpl, Boolean>();
public GraphViewImpl(Dhns dhns, int viewId) {
this.dhns = dhns;
this.viewId = viewId;
this.structure = new TreeStructure(this);
this.structureModifier = new StructureModifier(dhns, this);
this.attributeRow = dhns.factory().newGraphAttributes(this);
}
public void addGraphReference(AbstractGraphImpl graph) {
graphsMap.put(graph, Boolean.TRUE);
//Track graph references
/*StackTraceElement[] elm = Thread.currentThread().getStackTrace();
int i;
for (i = 1; i < elm.length; i++) {
if (!elm[i].getClassName().startsWith("org.gephi.graph")) {
break;
}
}
System.out.println("View " + viewId + " : " + elm[i].toString());*/
}
public boolean hasGraphReference() {
return !graphsMap.isEmpty();
}
public int getViewId() {
return viewId;
}
public TreeStructure getStructure() {
return structure;
}
public StructureModifier getStructureModifier() {
return structureModifier;
}
public boolean isMainView() {
return viewId == 0;
}
public void incNodesEnabled(int shift) {
nodesEnabled += shift;
}
public void decNodesEnabled(int shift) {
nodesEnabled -= shift;
}
public void incEdgesCountTotal(int shift) {
edgesCountTotal += shift;
}
public void incEdgesCountEnabled(int shift) {
edgesCountEnabled += shift;
}
public void incMutualEdgesTotal(int shift) {
mutualEdgesTotal += shift;
}
public void incMutualEdgesEnabled(int shift) {
mutualEdgesEnabled += shift;
}
public void decEdgesCountTotal(int shift) {
edgesCountTotal -= shift;
}
public void decEdgesCountEnabled(int shift) {
edgesCountEnabled -= shift;
}
public void decMutualEdgesTotal(int shift) {
mutualEdgesTotal -= shift;
}
public void decMutualEdgesEnabled(int shift) {
mutualEdgesEnabled -= shift;
}
public void incMetaEdgesCount(int shift) {
metaEdgesCountTotal += shift;
}
public void decMetaEdgesCount(int shift) {
metaEdgesCountTotal -= shift;
}
public void incMutualMetaEdgesTotal(int shift) {
mutualMetaEdgesTotal += shift;
}
public void decMutualMetaEdgesTotal(int shift) {
mutualMetaEdgesTotal -= shift;
}
public int getEdgesCountEnabled() {
return edgesCountEnabled;
}
public void setEdgesCountEnabled(int edgesCountEnabled) {
this.edgesCountEnabled = edgesCountEnabled;
}
public int getEdgesCountTotal() {
return edgesCountTotal;
}
public void setEdgesCountTotal(int edgesCountTotal) {
this.edgesCountTotal = edgesCountTotal;
}
public int getMutualEdgesEnabled() {
return mutualEdgesEnabled;
}
public void setMutualEdgesEnabled(int mutualEdgesEnabled) {
this.mutualEdgesEnabled = mutualEdgesEnabled;
}
public int getMutualEdgesTotal() {
return mutualEdgesTotal;
}
public void setMutualEdgesTotal(int mutualEdgesTotal) {
this.mutualEdgesTotal = mutualEdgesTotal;
}
public int getNodesEnabled() {
return nodesEnabled;
}
public void setNodesEnabled(int nodesEnabled) {
this.nodesEnabled = nodesEnabled;
}
public int getMetaEdgesCountTotal() {
return metaEdgesCountTotal;
}
public void setMetaEdgesCountTotal(int metaEdgesCountTotal) {
this.metaEdgesCountTotal = metaEdgesCountTotal;
}
public int getMutualMetaEdgesTotal() {
return mutualMetaEdgesTotal;
}
public void setMutualMetaEdgesTotal(int mutualMetaEdgesTotal) {
this.mutualMetaEdgesTotal = mutualMetaEdgesTotal;
}
public Dhns getGraphModel() {
return dhns;
}
public AttributeRow getAttributes() {
return attributeRow;
}
}
@@ -0,0 +1,79 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Generates incremental IDs for node and edges;
*
* @author Mathieu Bastian
*/
public class IDGen {
private AtomicInteger nodeGen = new AtomicInteger(1);
private AtomicInteger edgeGen = new AtomicInteger(1);
public int newNodeId() {
return nodeGen.getAndIncrement();
}
public int newEdgeId() {
return edgeGen.getAndIncrement();
}
public void setNodeGen(int nodeGen) {
this.nodeGen.set(nodeGen);
}
public void setEdgeGen(int edgeGen) {
this.edgeGen.set(edgeGen);
}
public int getNodeGen() {
return nodeGen.get();
}
public int getEdgeGen() {
return edgeGen.get();
}
}
@@ -0,0 +1,158 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.HashMap;
import java.util.Map;
import org.gephi.data.attributes.api.Estimator;
import org.gephi.graph.api.GraphEvent.EventType;
import org.gephi.graph.api.GraphSettings;
import org.gephi.graph.api.GraphView;
import org.gephi.graph.dhns.edge.AverageMetaEdgeBuilder;
import org.gephi.graph.dhns.edge.SumMetaEdgeBuilder;
import org.gephi.graph.dhns.event.GeneralEvent;
import org.gephi.graph.spi.MetaEdgeBuilder;
/**
*
* @author Mathieu Bastian
*/
public class SettingsManager implements GraphSettings {
private Dhns dhns;
//Settings
private Boolean autoMetaEdgeCreation;
private MetaEdgeBuilder metaEdgeBuilder;
private Float metaEdgeBuilderNonDeepDivisor;
private Estimator defaultWeightEstimator;
public SettingsManager(Dhns dhns) {
this.dhns = dhns;
defaultSettings();
}
private void defaultSettings() {
autoMetaEdgeCreation = Boolean.TRUE;
metaEdgeBuilderNonDeepDivisor = Float.valueOf(10f);
metaEdgeBuilder = new SumMetaEdgeBuilder(metaEdgeBuilderNonDeepDivisor);
defaultWeightEstimator = Estimator.AVERAGE;
}
public boolean isAutoMetaEdgeCreation() {
return autoMetaEdgeCreation;
}
public MetaEdgeBuilder getMetaEdgeBuilder() {
return metaEdgeBuilder;
}
public Estimator getDefaultWeightEstimator() {
return defaultWeightEstimator;
}
public void setMetaEdgeBuilder(MetaEdgeBuilder metaEdgeBuilder) {
putClientProperty(GraphSettings.METAEDGE_BUILDER, metaEdgeBuilder);
}
public void putClientProperty(String key, Object value) {
if (key.equals(GraphSettings.AUTO_META_EDGES)) {
autoMetaEdgeCreation = (Boolean) value;
fireUpdate();
} else if (key.equals(GraphSettings.METAEDGE_BUILDER)) {
if (value instanceof MetaEdgeBuilder) {
metaEdgeBuilder = (MetaEdgeBuilder) value;
}
if (value.equals("average")) {
metaEdgeBuilder = new AverageMetaEdgeBuilder(metaEdgeBuilderNonDeepDivisor);
} else if (value.equals("sum")) {
metaEdgeBuilder = new SumMetaEdgeBuilder(metaEdgeBuilderNonDeepDivisor);
}
fireUpdate();
} else if (key.equals(GraphSettings.METAEDGE_BUILDER_NONDEEP_DIVISOR)) {
metaEdgeBuilderNonDeepDivisor = (Float) value;
if (metaEdgeBuilder instanceof SumMetaEdgeBuilder) {
metaEdgeBuilder = new SumMetaEdgeBuilder(metaEdgeBuilderNonDeepDivisor);
} else if (metaEdgeBuilder instanceof AverageMetaEdgeBuilder) {
metaEdgeBuilder = new AverageMetaEdgeBuilder(metaEdgeBuilderNonDeepDivisor);
}
fireUpdate();
} else if(key.equals(GraphSettings.DEFAULT_WEIGHT_ESTIMATOR)) {
defaultWeightEstimator = (Estimator)value;
fireUpdate();
}
}
public Object getClientProperty(String key) {
if (key.equals(GraphSettings.AUTO_META_EDGES)) {
return autoMetaEdgeCreation;
} else if (key.equals(GraphSettings.METAEDGE_BUILDER)) {
if (metaEdgeBuilder instanceof SumMetaEdgeBuilder) {
return "sum";
} else if (metaEdgeBuilder instanceof AverageMetaEdgeBuilder) {
return "average";
} else {
return metaEdgeBuilder.getClass().getName();
}
} else if (key.equals(GraphSettings.METAEDGE_BUILDER_NONDEEP_DIVISOR)) {
return metaEdgeBuilderNonDeepDivisor;
} else if (key.equals(GraphSettings.DEFAULT_WEIGHT_ESTIMATOR)) {
return defaultWeightEstimator;
}
return null;
}
private void fireUpdate() {
dhns.getGraphVersion().incEdgeVersion();
for (GraphView view : dhns.getGraphStructure().getViews()) {
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
}
public Map<String, Object> getClientProperties() {
Map<String, Object> map = new HashMap<String, Object>();
map.put(GraphSettings.AUTO_META_EDGES, getClientProperty(GraphSettings.AUTO_META_EDGES));
map.put(GraphSettings.METAEDGE_BUILDER, getClientProperty(GraphSettings.METAEDGE_BUILDER));
map.put(GraphSettings.METAEDGE_BUILDER_NONDEEP_DIVISOR, getClientProperty(GraphSettings.METAEDGE_BUILDER_NONDEEP_DIVISOR));
map.put(GraphSettings.DEFAULT_WEIGHT_ESTIMATOR, getClientProperty(GraphSettings.DEFAULT_WEIGHT_ESTIMATOR));
return map;
}
}
@@ -0,0 +1,750 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import java.util.ArrayList;
import java.util.List;
import org.gephi.graph.api.GraphEvent.EventType;
import org.gephi.graph.api.Node;
import org.gephi.graph.dhns.edge.AbstractEdge;
import org.gephi.graph.dhns.edge.MetaEdgeImpl;
import org.gephi.graph.dhns.event.EdgeEvent;
import org.gephi.graph.dhns.event.GeneralEvent;
import org.gephi.graph.dhns.event.NodeEvent;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.iterators.AbstractNodeIterator;
import org.gephi.graph.dhns.node.iterators.ChildrenIterator;
import org.gephi.graph.dhns.node.iterators.DescendantAndSelfIterator;
import org.gephi.graph.dhns.node.iterators.DescendantIterator;
import org.gephi.graph.dhns.node.iterators.TreeIterator;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
import org.gephi.graph.dhns.predicate.Tautology;
/**
* Business class for external operations on the data structure. Propose blocking mechanism.
*
* @author Mathieu Bastian
*/
public class StructureModifier {
private final Dhns dhns;
private final GraphVersion graphVersion;
private final TreeStructure treeStructure;
private final GraphViewImpl view;
private final EdgeProcessor edgeProcessor;
//Business
private final Business business;
public StructureModifier(Dhns dhns, GraphViewImpl view) {
this.dhns = dhns;
this.view = view;
this.treeStructure = view.getStructure();
this.graphVersion = dhns.getGraphVersion();
edgeProcessor = new EdgeProcessor(dhns, view);
business = new Business();
}
public EdgeProcessor getEdgeProcessor() {
return edgeProcessor;
}
public void expand(AbstractNode node) {
boolean locked = dhns.conditionalWriteLock();
if (node.level < treeStructure.getTreeHeight()) {
business.expand(node);
}
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.EXPAND, node, view));
}
public void retract(AbstractNode node) {
boolean locked = dhns.conditionalWriteLock();
if (node.level < treeStructure.getTreeHeight()) {
business.retract(node);
}
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.RETRACT, node, view));
}
public void addNode(AbstractNode node, AbstractNode parent) {
boolean locked = dhns.conditionalWriteLock();
AbstractNode parentNode;
if (parent == null) {
parentNode = treeStructure.getRoot();
} else {
parentNode = (parent);
}
node.parent = parentNode;
business.addNode(node);
dhns.getGraphStructure().addToDictionnary(node);
graphVersion.incNodeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.ADD_NODES_AND_EDGES, node, view));
}
public void deleteNode(AbstractNode node) {
if (view.isMainView() && node.getNodeData().getNodes().getCount() > 1) {
boolean locked = dhns.conditionalWriteLock();
for (AbstractNodeIterator itr = node.getNodeData().getNodes().iterator(); itr.hasNext();) {
AbstractNode nodeInOtherView = itr.next();
if (nodeInOtherView.getViewId() != view.getViewId()) {
GraphViewImpl otherView = nodeInOtherView.avlNode.getList().getView();
business.deleteNode(nodeInOtherView, otherView);
}
}
AbstractNode[] deletesNodes = business.deleteNode(node, view);
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
for (int i = 0; i < deletesNodes.length; i++) {
dhns.getEventManager().fireEvent(new NodeEvent(EventType.REMOVE_NODES_AND_EDGES, deletesNodes[i], view));
}
} else {
boolean locked = dhns.conditionalWriteLock();
AbstractNode[] deletesNodes = business.deleteNode(node, view);
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
for (int i = 0; i < deletesNodes.length; i++) {
dhns.getEventManager().fireEvent(new NodeEvent(EventType.REMOVE_NODES_AND_EDGES, deletesNodes[i], view));
}
}
}
public void addEdge(AbstractEdge edge) {
boolean locked = dhns.conditionalWriteLock();
business.addEdge(edge);
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.ADD_NODES_AND_EDGES, edge, view));
}
public boolean deleteEdge(AbstractEdge edge) {
boolean locked = dhns.conditionalWriteLock();
boolean res = business.delEdge(edge);
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
if (res) {
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, edge, view));
}
return res;
}
public boolean deleteMetaEdge(AbstractEdge edge) {
boolean locked = dhns.conditionalWriteLock();
boolean res = business.delMetaEdge((MetaEdgeImpl) edge);
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
return res;
}
public void clear() {
boolean locked = dhns.conditionalWriteLock();
AbstractEdge[] clearedEdges = business.clearAllEdges();
AbstractNode[] clearedNodes = business.clearAllNodes();
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
if (clearedEdges != null) {
for (int i = 0; i < clearedEdges.length; i++) {
if (clearedEdges[i] != null) {
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, clearedEdges[i], view));
}
}
}
if (clearedNodes != null) {
for (int i = 0; i < clearedNodes.length; i++) {
if (clearedNodes[i] != null) {
dhns.getEventManager().fireEvent(new NodeEvent(EventType.REMOVE_NODES_AND_EDGES, clearedNodes[i], view));
}
}
}
}
public void clearEdges() {
boolean locked = dhns.conditionalWriteLock();
AbstractEdge[] clearedEdges = business.clearAllEdges();
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
if (clearedEdges != null) {
for (int i = 0; i < clearedEdges.length; i++) {
if (clearedEdges[i] != null) {
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, clearedEdges[i], view));
}
}
}
}
public void clearEdges(AbstractNode node) {
boolean locked = dhns.conditionalWriteLock();
AbstractEdge[] clearedEdges = business.clearEdges(node);
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
if (clearedEdges != null) {
for (int i = 0; i < clearedEdges.length; i++) {
if (clearedEdges[i] != null) {
dhns.getGraphStructure().removeFromDictionnary(clearedEdges[i]);
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, clearedEdges[i], view));
}
}
}
}
public void clearMetaEdges(AbstractNode node) {
boolean locked = dhns.conditionalWriteLock();
business.clearMetaEdges(node);
graphVersion.incEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
public void resetViewToLeaves() {
boolean locked = dhns.conditionalWriteLock();
edgeProcessor.clearAllMetaEdges();
view.setNodesEnabled(0);
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
node.setEnabled(node.size == 0);
if (node.isEnabled()) {
view.incNodesEnabled(1);
}
edgeProcessor.resetEdgesCounting(node);
}
view.setEdgesCountEnabled(0);
view.setMutualEdgesEnabled(0);
for (TreeIterator itr = new TreeIterator(treeStructure, true, Tautology.instance); itr.hasNext();) {
AbstractNode node = itr.next();
edgeProcessor.computeMetaEdges(node, node);
edgeProcessor.computeEdgesCounting(node);
}
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
public void resetViewToTopNodes() {
boolean locked = dhns.conditionalWriteLock();
edgeProcessor.clearAllMetaEdges();
view.setNodesEnabled(0);
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
node.setEnabled(node.parent == treeStructure.root);
if (node.isEnabled()) {
view.incNodesEnabled(1);
}
edgeProcessor.resetEdgesCounting(node);
}
view.setEdgesCountEnabled(0);
view.setMutualEdgesEnabled(0);
for (TreeIterator itr = new TreeIterator(treeStructure, true, Tautology.instance); itr.hasNext();) {
AbstractNode node = itr.next();
edgeProcessor.computeMetaEdges(node, node);
edgeProcessor.computeEdgesCounting(node);
}
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
public void resetViewToLevel(int level) {
boolean locked = dhns.conditionalWriteLock();
edgeProcessor.clearAllMetaEdges();
view.setNodesEnabled(0);
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
node.setEnabled(node.level == level);
if (node.isEnabled()) {
view.incNodesEnabled(1);
}
edgeProcessor.resetEdgesCounting(node);
}
view.setEdgesCountEnabled(0);
view.setMutualEdgesEnabled(0);
for (TreeIterator itr = new TreeIterator(treeStructure, true, Tautology.instance); itr.hasNext();) {
AbstractNode node = itr.next();
edgeProcessor.computeMetaEdges(node, node);
edgeProcessor.computeEdgesCounting(node);
}
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
public void moveToGroup(AbstractNode node, AbstractNode nodeGroup) {
boolean locked = dhns.conditionalWriteLock();
business.moveToGroup(node, nodeGroup);
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.MOVE_NODES, node, view));
}
public Node group(AbstractNode[] nodes) {
boolean locked = dhns.conditionalWriteLock();
AbstractNode group = dhns.factory().newNode(view.getViewId());
business.group(group, nodes);
graphVersion.incNodeAndEdgeVersion();
dhns.getGraphStructure().addToDictionnary(group);
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.ADD_NODES_AND_EDGES, group, view));
for (int i = 0; i < nodes.length; i++) {
dhns.getEventManager().fireEvent(new NodeEvent(EventType.MOVE_NODES, nodes[i], view));
}
return group;
}
public void ungroup(AbstractNode nodeGroup) {
boolean locked = dhns.conditionalWriteLock();
AbstractNode[] ungroupedNodes = business.ungroup(nodeGroup);
graphVersion.incNodeAndEdgeVersion();
dhns.conditionalWriteUnlock(locked);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.REMOVE_NODES_AND_EDGES, nodeGroup, view));
for (int i = 0; i < ungroupedNodes.length; i++) {
dhns.getEventManager().fireEvent(new NodeEvent(EventType.MOVE_NODES, ungroupedNodes[i], view));
}
}
public void flatten() {
dhns.writeLock();
if (treeStructure.getTreeHeight() > 1) {
TreeIterator nodesIterator = new TreeIterator(treeStructure, true, Tautology.instance);
for (; nodesIterator.hasNext();) {
AbstractNode node = nodesIterator.next();
AbstractEdge[] newEdges = edgeProcessor.flattenNode(node);
if (newEdges != null) {
for (int i = 0; i < newEdges.length; i++) {
AbstractEdge e = newEdges[i];
if (e != null) {
dhns.getGraphStructure().addToDictionnary(e);
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.ADD_NODES_AND_EDGES, e, view));
}
}
}
}
List<AbstractNode> nodesToDelete = new ArrayList<AbstractNode>();
List<AbstractNode> nodesToKeep = new ArrayList<AbstractNode>();
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
if (!node.isEnabled()) {
nodesToDelete.add(node);
} else {
nodesToKeep.add(node);
}
}
for (AbstractNode node : nodesToDelete) {
//Del edges
AbstractEdge[] deletedEdges = edgeProcessor.clearEdges(node);
if (deletedEdges != null) {
for (int j = 0; j < deletedEdges.length; j++) {
if (deletedEdges[j] != null) {
dhns.getGraphStructure().removeFromDictionnary(deletedEdges[j]);
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, deletedEdges[j], view));
}
}
}
dhns.getGraphStructure().removeFromDictionnary(node);
treeStructure.deleteOnlySelf(node);
dhns.getEventManager().fireEvent(new NodeEvent(EventType.REMOVE_NODES_AND_EDGES, node, view));
}
for (AbstractNode node : nodesToKeep) {
node.size = 0;
node.parent = treeStructure.root;
node.level = 1;
node.getPost();
}
treeStructure.root.size = nodesToKeep.size();
treeStructure.root.getPost();
treeStructure.resetLevelSize(nodesToKeep.size());
graphVersion.incNodeAndEdgeVersion();
}
dhns.writeUnlock();
dhns.getEventManager().fireEvent(new GeneralEvent(EventType.META_EDGES_UPDATE, view));
}
//------------------------------------------
private class Business {
private void expand(AbstractNode absNode) {
//Disable parent
absNode.setEnabled(false);
view.decNodesEnabled(1);
edgeProcessor.clearMetaEdges(absNode);
//Enable children
for (ChildrenIterator itr = new ChildrenIterator(treeStructure, absNode, Tautology.instance); itr.hasNext();) {
AbstractNode child = itr.next();
child.setEnabled(true);
view.incNodesEnabled(1);
edgeProcessor.computeMetaEdges(child, child);
}
//Update counting
for (ChildrenIterator itr = new ChildrenIterator(treeStructure, absNode, Tautology.instance); itr.hasNext();) {
AbstractNode child = itr.next();
edgeProcessor.incrementEdgesCounting(child, absNode);
}
edgeProcessor.decrementEdgesCouting(absNode, null);
}
private void retract(AbstractNode parent) {
//Disable children
for (ChildrenIterator itr = new ChildrenIterator(treeStructure, parent, Tautology.instance); itr.hasNext();) {
AbstractNode child = itr.next();
child.setEnabled(false);
view.decNodesEnabled(1);
edgeProcessor.clearMetaEdges(child);
}
//Enable node
parent.setEnabled(true);
view.incNodesEnabled(1);
edgeProcessor.computeMetaEdges(parent, parent);
//Edges counting
for (ChildrenIterator itr = new ChildrenIterator(treeStructure, parent, Tautology.instance); itr.hasNext();) {
AbstractNode child = itr.next();
edgeProcessor.decrementEdgesCouting(child, parent);
}
edgeProcessor.incrementEdgesCounting(parent, null);
}
private void addNode(AbstractNode node) {
boolean enabled = (treeStructure.getEnabledAncestor(node) == null);
node.setEnabled(enabled);
treeStructure.insertAsChild(node, node.parent);
if (node.isEnabled()) {
view.incNodesEnabled(1);
}
}
private void addEdge(AbstractEdge edge) {
AbstractNode sourceNode = edge.getSource(view.getViewId());
AbstractNode targetNode = edge.getTarget(view.getViewId());
boolean enabled = sourceNode.isEnabled() && targetNode.isEnabled();
//Add Edges
sourceNode.getEdgesOutTree().add(edge);
targetNode.getEdgesInTree().add(edge);
if (!edge.isSelfLoop() && sourceNode.getEdgesInTree().hasNeighbour(targetNode)) {
//Mututal edge
view.incMutualEdgesTotal(1);
if (enabled) {
sourceNode.incEnabledMutualDegree();
targetNode.incEnabledMutualDegree();
view.incMutualEdgesEnabled(1);
}
}
view.incEdgesCountTotal(1);
if (enabled) {
view.incEdgesCountEnabled(1);
sourceNode.incEnabledOutDegree();
targetNode.incEnabledInDegree();
}
dhns.getGraphStructure().addToDictionnary(edge);
//Add Meta Edge
if (!edge.isSelfLoop()) {
edgeProcessor.createMetaEdge(edge);
}
}
private AbstractNode[] deleteNode(AbstractNode node, GraphViewImpl graphView) {
AbstractNode[] descendants = new AbstractNode[node.size + 1];
int i = 0;
for (DescendantAndSelfIterator itr = new DescendantAndSelfIterator(graphView.getStructure(), node, Tautology.instance); itr.hasNext();) {
AbstractNode descendant = itr.next();
descendants[i] = descendant;
if (descendant.isEnabled()) {
graphView.getStructureModifier().edgeProcessor.clearMetaEdges(descendant);
graphView.decNodesEnabled(1);
}
AbstractEdge[] deletedEdges = graphView.getStructureModifier().edgeProcessor.clearEdges(descendant);
if (deletedEdges != null) {
for (int j = 0; j < deletedEdges.length; j++) {
if (deletedEdges[j] != null) {
dhns.getGraphStructure().removeFromDictionnary(deletedEdges[j]);
dhns.getEventManager().fireEvent(new EdgeEvent(EventType.REMOVE_NODES_AND_EDGES, deletedEdges[j], graphView));
}
}
}
dhns.getGraphStructure().removeFromDictionnary(descendant);
i++;
}
graphView.getStructure().deleteDescendantAndSelf(node);
return descendants;
}
private boolean delEdge(AbstractEdge edge) {
AbstractNode source = edge.getSource(view.getViewId());
AbstractNode target = edge.getTarget(view.getViewId());
boolean enabled = source.isEnabled() && target.isEnabled();
if (!edge.isSelfLoop() && source.getEdgesInTree().hasNeighbour(target)) {
//mutual
if (enabled) {
view.decMutualEdgesEnabled(1);
source.decEnabledMutualDegree();
target.decEnabledMutualDegree();
}
view.decMutualEdgesTotal(1);
}
view.decEdgesCountTotal(1);
if (enabled) {
view.decEdgesCountEnabled(1);
source.decEnabledOutDegree();
target.decEnabledInDegree();
}
//Remove edge
boolean res = source.getEdgesOutTree().remove(edge);
res = res && target.getEdgesInTree().remove(edge);
dhns.getGraphStructure().removeFromDictionnary(edge);
//Remove edge from possible metaEdge
edgeProcessor.removeEdgeFromMetaEdge(edge);
return res;
}
public boolean delMetaEdge(MetaEdgeImpl edge) {
AbstractNode source = edge.getSource(view.getViewId());
AbstractNode target = edge.getTarget(view.getViewId());
if (!edge.isSelfLoop() && source.getEdgesInTree().hasNeighbour(target)) {
//mutual
view.decMutualMetaEdgesTotal(1);
source.decMutualMetaEdgeDegree();
target.decMutualMetaEdgeDegree();
}
view.decMetaEdgesCount(1);
//Remove edge
boolean res = source.getMetaEdgesOutTree().remove(edge);
res = res && target.getMetaEdgesInTree().remove(edge);
return res;
}
private AbstractEdge[] clearAllEdges() {
return edgeProcessor.clearAllEdges();
}
private AbstractNode[] clearAllNodes() {
AbstractNode[] deletedNodes = new AbstractNode[treeStructure.getTreeSize() - 1];
int n = 0;
for (TreeListIterator itr = new TreeListIterator(treeStructure.getTree(), 1); itr.hasNext();) {
AbstractNode node = itr.next();
node.getNodeData().getNodes().remove(view.getViewId());
dhns.getGraphStructure().removeFromDictionnary(node);
deletedNodes[n++] = node;
}
treeStructure.clear();
view.setNodesEnabled(0);
return deletedNodes;
}
private AbstractEdge[] clearEdges(AbstractNode node) {
return edgeProcessor.clearEdges(node);
}
private void clearMetaEdges(AbstractNode node) {
edgeProcessor.clearMetaEdges(node);
}
private void group(AbstractNode group, AbstractNode[] nodes) {
group.setEnabled(true);
AbstractNode parent = ((AbstractNode) nodes[0]).parent;
//parent = parent.getInView(view.getViewId());
group.parent = parent;
business.addNode(group);
for (int i = 0; i < nodes.length; i++) {
AbstractNode nodeToGroup = nodes[i];
nodeToGroup = nodeToGroup.getInView(view.getViewId());
business.moveToGroup(nodeToGroup, group);
}
}
private AbstractNode[] ungroup(AbstractNode nodeGroup) {
//TODO Better implementation. Just remove nodeGroup from the treelist and lower level of children
int count = 0;
for (ChildrenIterator itr = new ChildrenIterator(treeStructure, nodeGroup, Tautology.instance); itr.hasNext();) {
itr.next();
count++;
}
AbstractNode[] ungroupedNodes = new AbstractNode[count];
if (nodeGroup.isEnabled()) {
business.expand(nodeGroup);
}
for (int i = 0; i < count; i++) {
AbstractNode node = treeStructure.getNodeAt(nodeGroup.getPre() + 1);
business.moveToGroup(node, nodeGroup.parent);
ungroupedNodes[i] = node;
}
business.deleteNode(nodeGroup, view);
return ungroupedNodes;
}
private void moveToGroup(AbstractNode node, AbstractNode nodeGroup) {
AbstractNode toMoveAncestor = treeStructure.getEnabledAncestor(node);
AbstractNode destinationAncestor = treeStructure.getEnabledAncestorOrSelf(nodeGroup);
if (toMoveAncestor != destinationAncestor) {
if (toMoveAncestor != null) {
//The node has an enabled ancestor
//We delete edges from potential meta edges
if (node.size > 0) {
for (DescendantAndSelfIterator itr = new DescendantAndSelfIterator(treeStructure, node, Tautology.instance); itr.hasNext();) {
AbstractNode descendant = itr.next();
edgeProcessor.clearEdgesWithoutRemove(descendant);
}
} else {
edgeProcessor.clearEdgesWithoutRemove(node);
}
} else if (node.isEnabled()) {
//The node is enabled
if (destinationAncestor != null) {
//The destination is enabled or has enabled ancestor
//Node is thus disabled
edgeProcessor.clearMetaEdges(node);
node.setEnabled(false);
view.decNodesEnabled(1);
edgeProcessor.decrementEdgesCouting(node, null);
//DO
} else {
//The node is kept enabled
//Meta edges are still valid only if their target is out of the dest cluster
edgeProcessor.clearMetaEdgesOutOfRange(node, nodeGroup);
}
} else if (node.size > 0) {
if (destinationAncestor != null) {
//The node may have some enabled descendants and we set them disabled
for (DescendantIterator itr = new DescendantIterator(treeStructure, node, Tautology.instance); itr.hasNext();) {
AbstractNode descendant = itr.next();
if (descendant.isEnabled()) {
edgeProcessor.clearMetaEdges(descendant);
descendant.setEnabled(false);
view.decNodesEnabled(1);
edgeProcessor.decrementEdgesCouting(descendant, null);
//TODO
}
}
//DO
} else {
//The node may have some enabled descendants and we keep them enabled
for (DescendantIterator itr = new DescendantIterator(treeStructure, node, Tautology.instance); itr.hasNext();) {
AbstractNode descendant = itr.next();
if (descendant.isEnabled()) {
//Enabled descendants meta edges are still valid only if their target is out of
//the destination cluster
edgeProcessor.clearMetaEdgesOutOfRange(node, nodeGroup);
}
}
}
}
}
treeStructure.move(node, nodeGroup);
if (destinationAncestor != null) {
destinationAncestor.getPre();
//Compute all meta edges for the descendants of node and append them to the enabled
//destinationAncestor
edgeProcessor.computeMetaEdges(node, destinationAncestor);
}
}
/*
private void cloneDescedantAndSelft(AbstractNode node, AbstractNode parentNode) {
if (node.size > 0) {
DescendantAndSelfIterator itr = new DescendantAndSelfIterator(treeStructure, node, Tautology.instance);
for (; itr.hasNext();) {
AbstractNode desc = itr.next();
CloneNode clone = new CloneNode(desc);
if (desc == node) {
//Parent is the given parentNode
clone.parent = parentNode;
} else {
clone.parent = desc.parent.getOriginalNode().getClones(); //The last clone added
}
addNode(clone);
}
} else {
CloneNode clone = new CloneNode(node);
clone.parent = parentNode;
addNode(clone);
}
}
private void unAttachClones(CloneNode node) {
for (int i = node.getPre(); i <= node.pre + node.size; i++) {
AbstractNode n = treeStructure.getNodeAt(i);
if (n.isClone()) {
n.getOriginalNode().removeClone((CloneNode) n);
}
}
}*/
}
}
@@ -0,0 +1,307 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.core;
import org.gephi.graph.dhns.node.AbstractNode;
import org.gephi.graph.dhns.node.iterators.TreeListIterator;
/**
* Holds nodes tree and manage basic operations.
*
* @author Mathieu Bastian
*/
public class TreeStructure {
protected DurableTreeList tree;
protected AbstractNode root;
protected final GraphViewImpl view;
public TreeStructure(GraphViewImpl view) {
tree = new DurableTreeList(view);
this.view = view;
initRoot();
}
private void initRoot() {
root = new AbstractNode(0, view != null ? view.getViewId() : 0, 0, 0, 0, null);
tree.add(root);
}
public AbstractNode getNodeAt(int pre) {
return tree.get(pre);
}
public AbstractNode getEnabledAncestorOrSelf(AbstractNode node) {
AbstractNode parent = node;
while (!parent.isEnabled()) {
parent = parent.parent;
if (parent == null || parent.getPre() == 0) {
return null;
}
}
return parent;
}
public AbstractNode[] getEnabledAncestorsOrSelf(AbstractNode node) {
AbstractNode enabled = getEnabledAncestorOrSelf(node);
if (enabled != null) {
return new AbstractNode[]{enabled};
} else {
return null;
}
}
/*public AbstractNode[] getEnabledAncestorsOrSelf(AbstractNode node) {
PreNode preNode = node.getOriginalNode();
if (preNode.getClones() == null) {
AbstractNode enabled = getEnabledAncestorOrSelf(preNode);
if (enabled != null) {
return new AbstractNode[]{enabled};
} else {
return null;
}
} else {
List<AbstractNode> nodeList = new ArrayList<AbstractNode>();
AbstractNode enabled = getEnabledAncestorOrSelf(preNode);
if (enabled != null) {
nodeList.add(enabled);
}
CloneNode cn = preNode.getClones();
while (cn != null) {
enabled = getEnabledAncestorOrSelf(cn);
if (enabled != null && !nodeList.contains(enabled)) {
nodeList.add(enabled.getOriginalNode());
}
cn = cn.getNext();
}
return nodeList.toArray(new AbstractNode[0]);
}
}*/
public AbstractNode getEnabledAncestor(AbstractNode node) {
AbstractNode parent = node.parent;
while (!parent.isEnabled()) {
if (parent.getPre() == 0) {
return null;
}
parent = parent.parent;
}
return parent;
}
public void insertAtEnd(AbstractNode node) {
node.pre = tree.size();
tree.add(node);
}
public void insertAsChild(AbstractNode node, AbstractNode parent) {
node.parent = parent;
node.pre = parent.getPre() + parent.size + 1;
node.level = parent.level + 1;
tree.add(node.pre, node);
incrementAncestorsSize(node);
}
public void resetLevelSize(int firstLevel) {
tree.levelsSize = new int[1 + (firstLevel > 0 ? 1 : 0)];
if (firstLevel > 0) {
tree.levelsSize[1] = firstLevel;
}
}
public void move(AbstractNode node, AbstractNode newParent) {
AbstractNode sourceParent = node.parent;
int sourceSize = 1 + node.size;
tree.move(node.getPre(), newParent.getPre());
if (sourceParent != null) {
decrementAncestorAndSelfSize(sourceParent, sourceSize);
}
//Increment ancestor & self
incrementAncestorsAndSelfSize(newParent, sourceSize);
/* nodeSize = node.size;
int nodePre = node.getPre();
boolean forward = newParent.getPre()+newParent.size+1 > nodePre;
//Move node itself
decrementAncestorSize(node, 1);
tree.removeAndKeepParent(nodePre);
insertAsChild(node, newParent);
node.size = 0;
//showTreeAsTable();
if(nodeSize>0) {
//Move descendants
for(int i=0;i<nodeSize;i++) {
int descPre = nodePre;
if(!forward) {
descPre += i + 1;
}
decrementAncestorSize(node, 1);
PreNode descendant = tree.removeAndKeepParent(descPre);
//System.out.println("descendant "+descendant.getId());
PreNode parent = descendant.parent;
insertAsChild(descendant, parent);
descendant.size = 0;
}
}*/
}
public void deleteAtPre(AbstractNode node) {
int pre = node.getPre();
AbstractNode n = tree.remove(pre);
n.removeFromView(view.getViewId());
for (int i = 0; i < node.size; i++) {
n = tree.remove(pre);
n.removeFromView(view.getViewId());
}
}
public void deleteDescendantAndSelf(AbstractNode node) {
decrementAncestorSize(node, node.size + 1);
deleteAtPre(node);
}
public void deleteOnlySelf(AbstractNode node) {
int pre = node.getPre();
AbstractNode n = tree.remove(pre);
n.removeFromView(view.getViewId());
}
public void incrementAncestorsSize(AbstractNode node) {
incrementAncestorsSize(node, 1);
}
public void incrementAncestorsSize(AbstractNode node, int shift) {
while (node.parent != null) {
node = node.parent;
node.size += shift;
node.getPost();
}
}
public void incrementAncestorsAndSelfSize(AbstractNode node, int shift) {
while (node != null) {
node.size += shift;
node.getPost();
node = node.parent;
}
}
public void decrementAncestorSize(AbstractNode node, int shift) {
while (node.parent != null) {
node = node.parent;
node.size -= shift;
node.getPost();
}
}
public void decrementAncestorAndSelfSize(AbstractNode node, int shift) {
while (node != null) {
node.size -= shift;
node.getPost();
node = node.parent;
}
}
public boolean hasEnabledDescendant(AbstractNode node) {
for (int i = node.getPre() + 1; i <= node.pre + node.size; i++) {
AbstractNode descendant = tree.get(i);
if (descendant.isEnabled()) {
return true;
}
}
return false;
}
public void showTreeAsTable() {
System.out.println("pre\tsize\tlevel\tparent\tpost\tenabled\tid");
System.out.println("-----------------------------------------------------------------");
int pre = 0;
for (AbstractNode p : tree) {
System.out.println(p.pre + "\t" + p.size + "\t" + p.level + "\t" + (p.parent == null ? "null" : p.parent.getPre()) + "\t" + p.post + "\t" + p.isEnabled() + "\t" + p.getId());
pre++;
}
}
public void clear() {
//Clean nodes
for (TreeListIterator itr = new TreeListIterator(tree); itr.hasNext();) {
AbstractNode preNode = itr.next();
preNode.avlNode = null;
preNode.parent = null;
}
tree.clear();
root = null;
initRoot();
}
public int getTreeSize() {
return tree.size();
}
public int getTreeHeight() {
int[] levelsSize = tree.levelsSize;
for (int i = levelsSize.length - 1; i >= 0; i--) {
if (levelsSize[i] > 0) {
return i;
}
}
return 0;
}
public int getLevelSize(int level) {
return tree.levelsSize[level];
}
public DurableTreeList getTree() {
return tree;
}
public AbstractNode getRoot() {
return root;
}
}
@@ -0,0 +1,168 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.utils.collection.avl.AVLItem;
import org.gephi.graph.api.Attributes;
import org.gephi.graph.api.Edge;
import org.gephi.graph.dhns.node.AbstractNode;
/**
* Abstract edge with one source and one target.
*
* @author Mathieu Bastian
*/
public abstract class AbstractEdge implements Edge, AVLItem {
protected final int ID;
protected final AbstractNode source;
protected final AbstractNode target;
protected EdgeDataImpl edgeData;
public AbstractEdge(int ID, AbstractNode source, AbstractNode target) {
this.source = source;
this.target = target;
this.ID = ID;
this.edgeData = new EdgeDataImpl(this);
}
public AbstractEdge(AbstractEdge edge, AbstractNode source, AbstractNode target) {
this.source = source;
this.target = target;
this.ID = edge.ID;
this.edgeData = edge.edgeData;
}
public AbstractNode getSource() {
return source;
}
public AbstractNode getTarget() {
return target;
}
public AbstractNode getSource(int viewId) {
return source.getInView(viewId);
}
public AbstractNode getTarget(int viewId) {
return target.getInView(viewId);
}
public float getWeight() {
return edgeData.getWeight();
}
public float getWeight(double low, double high) {
return edgeData.getWeight(low, high);
}
public void setWeight(float weight) {
edgeData.setWeight(weight);
}
public int getNumber() {
return ID;
}
public EdgeDataImpl getEdgeData() {
return edgeData;
}
public Attributes getAttributes() {
return edgeData.getAttributes();
}
public AbstractEdge getUndirected(int viewId) {
if (source == target) {
return this;
}
AbstractEdge mutual = getSource(viewId).getEdgesInTree().getItem(target.getNumber());
if (mutual != null && mutual.getId() < ID) {
return mutual;
}
return this;
}
public boolean isDirected() {
return true;
}
public boolean isSelfLoop() {
return source == target;
}
public boolean isValid(int viewId) {
return source.isValid(viewId) && target.isValid(viewId);
}
public boolean isValid() {
return source.avlNode != null && target.avlNode != null;
}
public boolean isMetaEdge() {
return false;
}
public boolean isMixed() {
return false;
}
public boolean hasAttributes() {
return edgeData.getAttributes() != null;
}
public void setAttributes(Attributes attributes) {
if (attributes != null) {
edgeData.setAttributes(attributes);
}
}
public int getId() {
return ID;
}
@Override
public String toString() {
return source.getId() + "-" + target.getId();
}
}
@@ -0,0 +1,97 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.MetaEdge;
import org.gephi.graph.api.Node;
import org.gephi.graph.spi.MetaEdgeBuilder;
/**
*
* @author Mathieu Bastian
*/
public class AverageMetaEdgeBuilder implements MetaEdgeBuilder {
//If the edge pushed to the metaEdge has a common adjacent node with the metaEdge, it is called
//a non-deep edge and should be considered less important and thus less weighted
private float nonDeepDivisor = 1f;
public AverageMetaEdgeBuilder() {
}
public AverageMetaEdgeBuilder(float divisor) {
this.nonDeepDivisor = divisor;
}
public void pushEdge(Edge edge, Node source, Node target, MetaEdge metaEdge) {
float edgeWeight = edge.getWeight();
float metaWeight = metaEdge.getWeight();
float edgeCount = metaEdge.getCount();
float div = 1f;
if (source == metaEdge.getSource()
|| source == metaEdge.getTarget()
|| target == metaEdge.getTarget()
|| target == metaEdge.getSource()) {
div = nonDeepDivisor;
}
edgeWeight /= div;
metaWeight = (metaWeight * edgeCount + edgeWeight) / (edgeCount + 1);
metaEdge.setWeight(metaWeight);
}
public void pullEdge(Edge edge, Node source, Node target, MetaEdge metaEdge) {
float edgeWeight = edge.getWeight();
float metaWeight = metaEdge.getWeight();
float edgeCount = metaEdge.getCount();
float div = 1f;
if (source == metaEdge.getSource()
|| source == metaEdge.getTarget()
|| target == metaEdge.getTarget()
|| target == metaEdge.getSource()) {
div = nonDeepDivisor;
}
edgeWeight /= div;
metaWeight = (metaWeight * edgeCount - edgeWeight) / (edgeCount - 1);
metaEdge.setWeight(metaWeight);
}
}
@@ -0,0 +1,302 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.data.attributes.api.AttributeRow;
import org.gephi.data.attributes.api.AttributeType;
import org.gephi.data.attributes.api.Estimator;
import org.gephi.data.attributes.type.DynamicFloat;
import org.gephi.data.properties.PropertiesColumn;
import org.gephi.graph.api.Attributes;
import org.gephi.graph.api.EdgeData;
import org.gephi.graph.spi.LayoutData;
import org.gephi.graph.api.NodeData;
import org.gephi.graph.api.Model;
import org.gephi.graph.api.TextData;
/**
* Implementation of the edge data interface.
*
* @author Mathieu Bastian
*/
public class EdgeDataImpl implements EdgeData {
protected AbstractEdge edge;
protected LayoutData layoutData;
protected float r = -1f;
protected float g = 0f;
protected float b = 0f;
protected float alpha = 1f;
private String label;
private Model model;
protected Attributes attributes;
protected TextData textData;
public EdgeDataImpl(AbstractEdge edge) {
this.edge = edge;
}
public AbstractEdge getEdge() {
return edge;
}
public NodeData getSource() {
return edge.getSource().getNodeData();
}
public NodeData getTarget() {
return edge.getTarget().getNodeData();
}
public String getLabel() {
if (attributes != null) {
return (String) attributes.getValue(PropertiesColumn.EDGE_LABEL.getIndex());
} else {
return label;
}
}
public LayoutData getLayoutData() {
return layoutData;
}
public void setLayoutData(LayoutData layoutData) {
this.layoutData = layoutData;
}
public Attributes getAttributes() {
return attributes;
}
public void setAttributes(Attributes attributes) {
this.attributes = attributes;
}
public float x() {
return (getSource().x() + 2 * getTarget().x()) / 3f;
}
public float y() {
return (getSource().y() + 2 * getTarget().y()) / 3f;
}
public float z() {
return (getSource().z() + 2 * getTarget().z()) / 3f;
}
/**
* Unimplemented for edges. <code>UnsupportedOperationException</code> will be thrown.
*/
public void setX(float x) {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Unimplemented for edges. <code>UnsupportedOperationException</code> will be thrown.
*/
public void setY(float y) {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Unimplemented for edges. <code>UnsupportedOperationException</code> will be thrown.
*/
public void setZ(float z) {
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Always returns 0 for an edge element
* @return 0 (not implemented for edges).
*/
public float getRadius() {
return 0;
}
/**
* Returns weight of the edge.
* @return Edge weight
*/
public float getSize() {
return edge.getWeight();
}
/**
* Set weight of the edge
* @param size Weight for the edge
*/
public void setSize(float size) {
edge.setWeight(size);
}
public float r() {
return r;
}
public float g() {
return g;
}
public float b() {
return b;
}
/**
* <p>Get red component of the edge color.
* Ranges from 0.0 to 1.0</p>
* <p><b>May return -1 for indicating that the edge has no specific color</b></p>
* @return Red color component or -1 for indicating no specific color.
*/
public void setR(float r) {
this.r = r;
}
public void setG(float g) {
this.g = g;
}
public void setB(float b) {
this.b = b;
}
public void setColor(float r, float g, float b) {
this.r = r;
this.g = g;
this.b = b;
}
public float alpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
}
public Model getModel() {
return model;
}
public void setModel(Model obj) {
this.model = obj;
}
public TextData getTextData() {
return textData;
}
public void setTextData(TextData textData) {
this.textData = textData;
}
public void setLabel(String label) {
if (attributes != null) {
attributes.setValue(PropertiesColumn.EDGE_LABEL.getIndex(), label);
} else {
this.label = label;
}
}
public String setId(String id) {
if (attributes == null) {
return null;
}
String oldId = (String) attributes.getValue(PropertiesColumn.EDGE_ID.getIndex());
attributes.setValue(PropertiesColumn.EDGE_ID.getIndex(), id);
return oldId;
}
public String getId() {
if (attributes == null) {
return null;
}
return (String) attributes.getValue(PropertiesColumn.EDGE_ID.getIndex());
}
public float getWeight() {
if (attributes == null) {
return 1f;
}
Object weight = attributes.getValue(PropertiesColumn.EDGE_WEIGHT.getIndex());
if (weight instanceof DynamicFloat) {
weight = ((DynamicFloat) weight).getValue(Estimator.AVERAGE);
}
if (weight == null) {
return 1f;
}
return (Float) weight;
}
public float getWeight(double low, double high) {
if (attributes == null) {
return 1f;
}
Object weight = attributes.getValue(PropertiesColumn.EDGE_WEIGHT.getIndex());
if (weight instanceof DynamicFloat) {
weight = ((DynamicFloat) weight).getValue(low, high, Estimator.AVERAGE);
}
if (weight == null) {
return 1f;
}
return (Float) weight;
}
public void setWeight(float weight) {
if (attributes != null) {
if (!((AttributeRow) attributes).getColumnAt(PropertiesColumn.EDGE_WEIGHT.getIndex()).getType().equals(AttributeType.DYNAMIC_FLOAT)) {
attributes.setValue(PropertiesColumn.EDGE_WEIGHT.getIndex(), weight);
}
}
}
public void moveFrom(EdgeData edgeData) {
this.r = edgeData.r();
this.g = edgeData.g();
this.b = edgeData.b();
this.alpha = edgeData.alpha();
this.label = edgeData.getLabel();
this.textData = edgeData.getTextData();
if (attributes != null) {
((AttributeRow) attributes).setValues((AttributeRow) edgeData.getAttributes());
}
}
}
@@ -0,0 +1,106 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.api.MetaEdge;
import org.gephi.graph.dhns.node.AbstractNode;
/**
* Meta edge implementation. Edge between upper activated clusters in hierarchy. Contains lower edges.
*
* @author Mathieu Bastian
*/
public class MetaEdgeImpl extends AbstractEdge implements MetaEdge {
private int count = 0;
private int directedCount = 0;
public MetaEdgeImpl(int ID, AbstractNode source, AbstractNode target) {
super(ID, source, target);
setWeight(0f);
}
public boolean addEdge(AbstractEdge edge) {
if (edge.isDirected()) {
directedCount++;
}
count++;
return true;
}
public boolean removeEdge(AbstractEdge edge) {
if (edge.isDirected()) {
directedCount--;
}
count--;
return true;
}
public boolean isEmpty() {
return count == 0;
}
public int getCount() {
return count;
}
@Override
public boolean isDirected() {
return directedCount > 0;
}
@Override
public boolean isMetaEdge() {
return true;
}
public AbstractEdge getUndirected() {
if (source == target) {
return this;
}
AbstractEdge mutual = source.getMetaEdgesInTree().getItem(target.getNumber());
if (mutual != null && mutual.getId() < ID) {
return mutual;
}
return this;
}
}
@@ -0,0 +1,74 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.dhns.node.AbstractNode;
/**
* Main edge implementation + sparse support.
*
* @author Mathieu Bastian
*/
public class MixedEdgeImpl extends AbstractEdge {
protected boolean directed;
public MixedEdgeImpl(int ID, AbstractNode source, AbstractNode target, boolean directed) {
super(ID, source, target);
this.directed = directed;
}
public MixedEdgeImpl(AbstractEdge edge, AbstractNode source, AbstractNode target, boolean directed) {
super(edge, source, target);
this.directed = directed;
}
@Override
public boolean isDirected() {
return directed;
}
@Override
public boolean isMixed() {
return true;
}
}
@@ -0,0 +1,60 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.dhns.node.AbstractNode;
/**
* Main Edge implementation. Has a source and a target.
*
* @author Mathieu Bastian
*/
public class ProperEdgeImpl extends AbstractEdge {
public ProperEdgeImpl(int ID, AbstractNode source, AbstractNode target) {
super(ID, source, target);
}
public ProperEdgeImpl(AbstractEdge edge, AbstractNode source, AbstractNode target) {
super(edge, source, target);
}
}
@@ -0,0 +1,60 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.dhns.node.AbstractNode;
/**
* Edges with source equal target.
*
* @author Mathieu Bastian
*/
public class SelfLoopImpl extends AbstractEdge {
public SelfLoopImpl(int ID, AbstractNode node) {
super(ID, node, node);
}
public SelfLoopImpl(AbstractEdge edge, AbstractNode node) {
super(edge, node, node);
}
}
@@ -0,0 +1,93 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge;
import org.gephi.graph.api.Edge;
import org.gephi.graph.api.MetaEdge;
import org.gephi.graph.api.Node;
import org.gephi.graph.spi.MetaEdgeBuilder;
/**
*
* @author Mathieu Bastian
*/
public class SumMetaEdgeBuilder implements MetaEdgeBuilder {
//If the edge pushed to the metaEdge has a common adjacent node with the metaEdge, it is called
//a non-deep edge and should be considered less important and thus less weighted
private float nonDeepDivisor = 1f;
public SumMetaEdgeBuilder() {
}
public SumMetaEdgeBuilder(float divisor) {
this.nonDeepDivisor = divisor;
}
public void pushEdge(Edge edge, Node source, Node target, MetaEdge metaEdge) {
float edgeWeight = edge.getWeight();
float metaWeight = metaEdge.getWeight();
float div = 1f;
if (edge.getSource() == metaEdge.getSource()
|| edge.getSource() == metaEdge.getTarget()
|| edge.getTarget() == metaEdge.getTarget()
|| edge.getTarget() == metaEdge.getSource()) {
div = nonDeepDivisor;
}
metaWeight += edgeWeight / div;
metaEdge.setWeight(metaWeight);
}
public void pullEdge(Edge edge, Node source, Node target, MetaEdge metaEdge) {
float edgeWeight = edge.getWeight();
float metaWeight = metaEdge.getWeight();
float div = 1f;
if (source == metaEdge.getSource()
|| source == metaEdge.getTarget()
|| target == metaEdge.getTarget()
|| target == metaEdge.getSource()) {
div = nonDeepDivisor;
}
metaWeight -= edgeWeight / div;
metaEdge.setWeight(metaWeight);
}
}
@@ -0,0 +1,58 @@
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org
This file is part of Gephi.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
Copyright 2011 Gephi Consortium. All rights reserved.
The contents of this file are subject to the terms of either the GNU
General Public License Version 3 only ("GPL") or the Common
Development and Distribution License("CDDL") (collectively, the
"License"). You may not use this file except in compliance with the
License. You can obtain a copy of the License at
http://gephi.org/about/legal/license-notice/
or /cddl-1.0.txt and /gpl-3.0.txt. See the License for the
specific language governing permissions and limitations under the
License. When distributing the software, include this License Header
Notice in each file and include the License files at
/cddl-1.0.txt and /gpl-3.0.txt. If applicable, add the following below the
License Header, with the fields enclosed by brackets [] replaced by
your own identifying information:
"Portions Copyrighted [year] [name of copyright owner]"
If you wish your version of this file to be governed by only the CDDL
or only the GPL Version 3, indicate your decision by adding
"[Contributor] elects to include this software in this distribution
under the [CDDL or GPL Version 3] license." If you do not indicate a
single choice of license, a recipient has the option to distribute
your version of this file under either the CDDL, the GPL Version 3 or
to extend the choice of license to its licensees as provided above.
However, if you add GPL Version 3 code and therefore, elected the GPL
Version 3 license, then the option applies only if the new code is
made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
package org.gephi.graph.dhns.edge.iterators;
import org.gephi.graph.dhns.edge.AbstractEdge;
/**
* Abstract Iterator.
*
* @author Mathieu Bastian
*/
public abstract class AbstractEdgeIterator {
public abstract boolean hasNext();
public abstract AbstractEdge next();
public abstract void remove();
}

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais