add pw-frontend

This commit is contained in:
Ilion Beyst 2021-12-22 13:59:13 +01:00
parent 218ebc3b8f
commit 96ee00242f
59 changed files with 7130 additions and 0 deletions

View file

@ -0,0 +1,2 @@
[*.{js,ts,html,svelte}]
indent_size = 2

5
web/pw-frontend/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
/node_modules/
/dist/
/.vscode/
.DS_Store
package-lock.json

48
web/pw-frontend/README.md Normal file
View file

@ -0,0 +1,48 @@
# Svelte + TS + Vite
This template should help get you started developing with Svelte and TypeScript in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## Need an official Svelte framework?
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
## Technical considerations
**Why use this over SvelteKit?**
- It brings its own routing solution which might not be preferable for some users.
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
`vite dev` and `vite build` wouldn't work in a SvelteKit environment, for example.
This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
**Why include `.vscode/extensions.json`?**
Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
**Why enable `allowJs` in the TS template?**
While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
**Why is HMR not preserving my local component state?**
HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
```ts
// store.ts
// An extremely simple external store
import { writable } from 'svelte/store'
export default writable(0)
```

View file

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<!-- polyfill global -->
<script>
const global = globalThis;
</script>
<!-- end polyfill -->
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Planetwars</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View file

@ -0,0 +1,30 @@
{
"name": "pw-frontend",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
"@tsconfig/svelte": "^2.0.1",
"rollup-plugin-polyfill-node": "^0.8.0",
"svelte": "^3.44.0",
"svelte-check": "^2.2.7",
"svelte-preprocess": "^4.9.8",
"tslib": "^2.3.1",
"typescript": "^4.4.4",
"vite": "^2.7.2"
},
"dependencies": {
"buffer": "^6.0.3",
"extract-svg-path": "^2.1.0",
"load-svg": "^1.0.0",
"planetwars-rs": "file:./planetwars-rs/pkg",
"svg-mesh-3d": "^1.1.0",
"ts-heap": "^1.1.3"
}
}

View file

@ -0,0 +1,2 @@
pkg/**
target/**

View file

@ -0,0 +1,44 @@
[package]
name = "planetwars-rs"
version = "0.1.0"
authors = ["ajuvercr <arthur.vercruysse@ugent.be>"]
edition = "2018"
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-Oz", "--enable-mutable-globals"]
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = "0.2"
# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.1", optional = true }
# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
#
# Unfortunately, `wee_alloc` requires nightly Rust when targeting wasm for now.
wee_alloc = { version = "0.4.2", optional = true }
serde = "1.0.100"
serde_derive = "1.0.100"
serde_json = "1.0"
octoon-math = "0.1.7"
voronoi = "0.1.4"
[dev-dependencies]
wasm-bindgen-test = "0.2"
[profile.release]
# Tell `rustc` to optimize for small code size.
opt-level = "s"
[workspace]

View file

@ -0,0 +1,373 @@
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate octoon_math;
extern crate serde_json;
extern crate voronoi;
use octoon_math::Mat3;
use voronoi::{make_polygons, voronoi, Point};
mod types;
mod utils;
use std::collections::HashMap;
use wasm_bindgen::prelude::*;
macro_rules! console_log {
// Note that this is using the `log` function imported above during
// `bare_bones`
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[derive(Debug, Clone)]
pub struct Circle {
r: f32,
x: f32,
y: f32,
a0: f32,
ad: f32,
distance: usize,
}
use std::f32::consts::PI;
fn spr(from: f32) -> f32 {
let pi2 = PI * 2.;
((from % pi2) + pi2) % pi2
}
impl Circle {
pub fn new(p1: &types::Planet, p2: &types::Planet) -> Self {
let x1 = p1.x;
let y1 = p1.y;
let x2 = p2.x;
let y2 = p2.y;
// Distance between planets
let q = ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt();
// Center of between planets
let x3 = (x1 + x2) / 2.0;
let y3 = (y1 + y2) / 2.0;
// Radius of circle
let r = q * 1.0;
// Center of circle
let x = x3 + (r.powi(2) - (q / 2.0).powi(2)).sqrt() * (y1 - y2) / q;
let y = y3 + (r.powi(2) - (q / 2.0).powi(2)).sqrt() * (x2 - x1) / q;
// console_log!("{},{} -> {},{} ({},{} r={})", x1, y1, x2, y2, x, y, r);
let a0 = spr((y - y1).atan2(x - x1));
let a2 = spr((y - y2).atan2(x - x2));
let mut ad = spr(a0 - a2);
if ad > PI {
ad = spr(a2 - a0);
}
// console_log!("a1 {} a2 {} ad {}", a0/PI * 180.0, a2/PI * 180.0, ad/PI*180.0);
let distance = q.ceil() as usize + 1;
Self {
r,
x,
y,
a0,
ad,
distance,
}
}
pub fn get_for_remaining(&self, remaining: usize) -> ((Mat3<f32>, f32), (Mat3<f32>, f32)) {
(
self.get_remaining(remaining),
self.get_remaining((remaining + 1).min(self.distance - 1)),
)
}
fn get_remaining(&self, remaining: usize) -> (Mat3<f32>, f32) {
let alpha = self.a0 + (1.0 - (remaining as f32 / self.distance as f32)) * self.ad;
let cos = alpha.cos();
let sin = alpha.sin();
(
Mat3::new(
0.3,
0.0,
0.0,
0.0,
0.3,
0.0,
-self.x + cos * self.r,
-self.y + sin * self.r,
0.3,
),
alpha,
)
}
}
fn create_voronoi(planets: &Vec<types::Planet>, bbox: f32) -> (Vec<f32>, Vec<usize>) {
let mut verts: Vec<[f32; 2]> = planets.iter().map(|p| [p.x, p.y]).collect();
let mut ids = Vec::new();
let vor_points = planets
.iter()
.map(|p| Point::new(p.x as f64, p.y as f64))
.collect();
let vor = voronoi(vor_points, bbox as f64);
let vor = make_polygons(&vor);
for poly in vor.iter() {
// Get planet index for planet that is inside this poligon
let idx = 0;
let mut prev = ids.len() + poly.len() - 1;
for p in poly.iter() {
let now = verts.len();
verts.push([p.x.0 as f32, p.y.0 as f32]);
ids.push(idx);
ids.push(now);
ids.push(prev);
prev = now;
}
}
(verts.concat(), ids)
}
#[wasm_bindgen]
pub struct Game {
states: Vec<types::State>,
turn: usize,
planet_map: HashMap<(String, String), Circle>,
/* put extra shit here */
view_box: Vec<f32>,
planets: Vec<f32>,
planet_ships: Vec<usize>,
ship_locations: Vec<f32>,
ship_label_locations: Vec<f32>,
ship_colours: Vec<f32>,
ship_counts: Vec<usize>,
current_planet_colours: Vec<f32>,
voronoi_vertices: Vec<f32>,
voronoi_colors: Vec<f32>,
voronoi_indices: Vec<usize>,
}
#[wasm_bindgen]
impl Game {
pub fn new(file: &str) -> Self {
utils::set_panic_hook();
// First line is fucked but we just filter out things that cannot parse
let states: Vec<types::State> = file
.split("\n")
.filter_map(|line| serde_json::from_str(line).ok())
.collect();
let mut planet_map = HashMap::new();
// Iterator?
for p1 in states[0].planets.iter() {
for p2 in states[0].planets.iter() {
planet_map.insert((p1.name.clone(), p2.name.clone()), Circle::new(&p1, &p2));
}
}
let view_box = utils::caclulate_viewbox(&states[0].planets);
let (voronoi_vertices, voronoi_indices) =
create_voronoi(&states[0].planets, view_box[2].max(view_box[3]));
let voronoi_colors: Vec<f32> = voronoi_indices
.iter()
.map(|_| [0.0, 0.0, 0.0])
.collect::<Vec<[f32; 3]>>()
.concat(); // Init these colours on black
Self {
planets: utils::get_planets(&states[0].planets, 2.0),
planet_ships: Vec::new(),
view_box,
planet_map,
turn: 0,
states,
ship_locations: Vec::new(),
ship_label_locations: Vec::new(),
ship_colours: Vec::new(),
ship_counts: Vec::new(),
current_planet_colours: Vec::new(),
voronoi_vertices,
voronoi_indices,
voronoi_colors,
}
}
pub fn push_state(&mut self, state_str: &str) {
if let Ok(state) = serde_json::from_str(state_str) {
self.states.push(state);
}
}
pub fn get_viewbox(&self) -> Vec<f32> {
self.view_box.clone()
}
pub fn get_planets(&self) -> Vec<f32> {
self.planets.clone()
}
pub fn get_planet_ships(&self) -> Vec<usize> {
self.planet_ships.clone()
}
pub fn get_planet_colors(&self) -> Vec<f32> {
self.current_planet_colours.clone()
}
pub fn turn_count(&self) -> usize {
self.states.len()
}
pub fn update_turn(&mut self, turn: usize) -> usize {
self.turn = turn.min(self.states.len() - 1);
self.update_planet_ships();
self.update_planet_colours();
self.update_voronoi_colors();
self.update_ship_locations();
self.update_ship_counts();
self.turn
}
fn update_planet_ships(&mut self) {
self.planet_ships = self.states[self.turn]
.planets
.iter()
.map(|p| p.ship_count as usize)
.collect();
}
fn update_voronoi_colors(&mut self) {
for (i, p) in self.states[self.turn].planets.iter().enumerate() {
let color = utils::COLORS[p.owner.unwrap_or(0) as usize % utils::COLORS.len()];
self.voronoi_colors[i * 3 + 0] = color[0];
self.voronoi_colors[i * 3 + 1] = color[1];
self.voronoi_colors[i * 3 + 2] = color[2];
}
}
fn update_planet_colours(&mut self) {
let mut new_vec: Vec<[f32; 3]> = Vec::new();
let planets_now = self.states[self.turn].planets.iter();
let planets_later = self.states[(self.turn + 1).min(self.states.len() - 1)]
.planets
.iter();
for (p1, p2) in planets_now.zip(planets_later) {
new_vec
.push(utils::COLORS[p1.owner.unwrap_or(0) as usize % utils::COLORS.len()].into());
new_vec
.push(utils::COLORS[p2.owner.unwrap_or(0) as usize % utils::COLORS.len()].into());
}
self.current_planet_colours = new_vec.concat::<f32>();
}
fn update_ship_locations(&mut self) {
let mut new_sl = Vec::new();
let mut new_sll = Vec::new();
let t = Mat3::new(0.2, 0., 0., 0., 0.2, 0.0, 0., -0.5, 0.2);
for ship in self.states[self.turn].expeditions.iter() {
let ((o1, a1), (o2, a2)) = self
.planet_map
.get(&(ship.origin.clone(), ship.destination.clone()))
.unwrap()
.get_for_remaining(ship.turns_remaining as usize);
new_sl.push((o1 * Mat3::rotate_z(a1)).to_array());
new_sl.push((o2 * Mat3::rotate_z(a2)).to_array());
new_sll.push((o1 + t).to_array());
new_sll.push((o2 + t).to_array());
}
self.ship_locations = new_sl.concat();
self.ship_label_locations = new_sll.concat();
self.ship_colours = self.states[self.turn]
.expeditions
.iter()
.map(|s| utils::COLORS[s.owner as usize % utils::COLORS.len()])
.collect::<Vec<[f32; 3]>>()
.concat();
}
fn update_ship_counts(&mut self) {
self.ship_counts = self.states[self.turn]
.expeditions
.iter()
.map(|s| s.ship_count as usize)
.collect();
}
pub fn get_max_ships(&self) -> usize {
self.states
.iter()
.map(|s| s.expeditions.len())
.max()
.unwrap()
}
pub fn get_ship_locations(&self) -> Vec<f32> {
self.ship_locations.clone()
}
pub fn get_ship_label_locations(&self) -> Vec<f32> {
self.ship_label_locations.clone()
}
pub fn get_ship_colours(&self) -> Vec<f32> {
self.ship_colours.clone()
}
pub fn get_ship_counts(&self) -> Vec<usize> {
self.ship_counts.clone()
}
pub fn get_voronoi_verts(&self) -> Vec<f32> {
self.voronoi_vertices.clone()
}
pub fn get_voronoi_colours(&self) -> Vec<f32> {
self.voronoi_colors.clone()
}
pub fn get_voronoi_inds(&self) -> Vec<usize> {
self.voronoi_indices.clone()
}
}
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}

View file

@ -0,0 +1,45 @@
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Expedition {
pub id: u64,
pub ship_count: u64,
pub origin: String,
pub destination: String,
pub owner: u64,
pub turns_remaining: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Planet {
pub ship_count: u64,
pub x: f32,
pub y: f32,
pub owner: Option<u32>,
pub name: String,
}
use std::hash::{Hash, Hasher};
use std::mem;
impl Hash for Planet {
fn hash<H: Hasher>(&self, state: &mut H) {
unsafe {
let x: u32 = mem::transmute_copy(&self.x);
let y: u32 = mem::transmute_copy(&self.y);
state.write_u32(x);
state.write_u32(y);
}
}
}
impl PartialEq for Planet {
fn eq(&self, other: &Self) -> bool {
(self.x - other.x).abs() < 0.0001 && (self.y - other.y).abs() < 0.0001
}
}
impl Eq for Planet {}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct State {
pub planets: Vec<Planet>,
pub expeditions: Vec<Expedition>,
}

View file

@ -0,0 +1,65 @@
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
/// this is total extra, so it the planet viewbox is like 100px wide, it will now be in total 110 pixels wide
static VIEWBOX_SCALE: f32 = 0.1;
pub static COLORS: [[f32; 3]; 10] = [
[0.5, 0.5, 0.5],
[1.0, 0.50, 0.0], // #FF8000
[0.0, 0.50, 1.0], // #0080ff
[1.0, 0.4, 0.58], // #FF6693
[0.24, 0.79, 0.33], // #3fcb55
[0.79, 0.76, 0.24], // #cbc33f
[0.81, 0.25, 0.91], // #cf40e9
[0.94, 0.32, 0.32], // #FF3F0D
[0.11, 0.93, 0.94], // #1beef0
[0.05, 0.77, 1.0], // #0DC5FF
];
use super::types;
pub fn caclulate_viewbox(planets: &Vec<types::Planet>) -> Vec<f32> {
let mut iter = planets.iter();
let init = match iter.next() {
Some(p) => (p.x, p.y, p.x, p.y),
None => return vec![0.0, 0.0, 0.0, 0.0],
};
let (min_x, min_y, max_x, max_y) =
planets
.iter()
.fold(init, |(min_x, min_y, max_x, max_y), p| {
(
min_x.min(p.x),
min_y.min(p.y),
max_x.max(p.x),
max_y.max(p.y),
)
});
let (width, height) = (max_x - min_x, max_y - min_y);
let (dx, dy) = (
(VIEWBOX_SCALE * width).max(6.0),
(VIEWBOX_SCALE * height).max(6.0),
);
vec![min_x - dx / 2.0, min_y - dy / 2.0, width + dx, height + dy]
}
pub fn get_planets(planets: &Vec<types::Planet>, r: f32) -> Vec<f32> {
planets.iter().fold(Vec::new(), |mut cum, p| {
cum.push(p.x);
cum.push(p.y);
cum.push(r);
cum
})
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.4 KiB

View file

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 493.0475 493.16002"
xml:space="preserve"
sodipodi:docname="jupiter-with-satellite.svg"
width="493.04749"
height="493.16"
inkscape:version="0.92.1 r15371"><metadata
id="metadata45"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs43" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview41"
showgrid="false"
inkscape:zoom="0.38562218"
inkscape:cx="-121.54471"
inkscape:cy="246.58001"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
id="g8"
transform="translate(-118.9515,-59.419)">
<path
d="M 539.776,131.64 C 493.205,85.067 431.282,59.419 365.417,59.419 c -65.865,0 -127.785,25.649 -174.359,72.221 -96.142,96.142 -96.142,252.575 0,348.718 46.573,46.573 108.494,72.221 174.359,72.221 65.865,0 127.786,-25.648 174.359,-72.221 46.574,-46.573 72.223,-108.494 72.223,-174.359 0,-65.865 -25.647,-127.786 -72.223,-174.359 z M 375.169,405.983 c -12.849,11.452 -28.27,18.565 -40.247,18.565 -3.901,0 -9.259,-0.794 -12.626,-4.57 -3.823,-4.287 -4.311,-11.821 -1.337,-20.669 3.484,-10.375 11.047,-21.12 21.292,-30.252 12.849,-11.452 28.27,-18.565 40.247,-18.565 3.901,0 9.259,0.794 12.626,4.568 9.699,10.882 -2.733,35.57 -19.955,50.923 z m -59.521,27.38 c 5.126,3.72 11.674,5.68 19.274,5.68 15.617,0 34.268,-8.313 49.89,-22.24 23.566,-21.006 33.496,-48.135 25.096,-65.431 0.069,-0.069 0.138,-0.134 0.205,-0.203 l 0.245,-0.245 c 56.354,-56.355 104.89,-119.767 140.932,-183.964 9.652,12.849 17.879,26.565 24.597,40.957 -35.262,61.327 -80.521,119.83 -134.614,173.92 -54.098,54.099 -112.607,99.362 -173.935,134.623 -14.394,-6.719 -28.111,-14.945 -40.961,-24.599 30.178,-16.937 60.136,-36.571 89.271,-58.498 z M 466.754,97.09 c -35.38,61.735 -80.828,120.58 -135.241,174.991 -54.389,54.389 -113.209,99.824 -174.915,135.197 -5.757,-11.897 -10.44,-24.186 -14.05,-36.725 56.493,-34.46 110.419,-77.182 160.338,-127.099 49.957,-49.957 92.703,-103.921 127.17,-160.452 12.628,3.642 24.897,8.353 36.698,14.088 z m -265.444,44.8 c 43.835,-43.835 102.116,-67.977 164.109,-67.977 7.242,0 14.43,0.342 21.555,0.995 -31.234,48.087 -68.655,94.211 -111.341,137.176 -2.821,2.839 -2.807,7.429 0.034,10.25 1.413,1.404 3.262,2.107 5.108,2.107 1.863,0 3.725,-0.714 5.142,-2.14 44.565,-44.857 84.642,-94.977 116.958,-145.384 4.187,0.676 8.346,1.459 12.472,2.359 -33.458,54.163 -74.692,105.911 -122.709,153.927 -47.981,47.981 -99.69,89.192 -153.82,122.642 -16.314,-74.713 4.517,-155.981 62.492,-213.955 z m -37.988,278.24 c 62.996,-36.051 123.004,-82.362 178.439,-137.797 55.457,-55.457 101.781,-115.487 137.837,-178.506 18.062,10.238 34.849,22.985 49.928,38.064 4.164,4.164 8.148,8.46 11.953,12.874 -35.656,64.768 -84.421,128.944 -141.318,185.854 -4.865,-3.019 -10.834,-4.622 -17.665,-4.622 -15.617,0 -34.269,8.313 -49.892,22.24 -12.097,10.783 -21.113,23.731 -25.389,36.457 -3.457,10.294 -3.575,19.665 -0.495,27.248 -30.198,22.709 -61.277,42.902 -92.54,60.113 -4.414,-3.803 -8.708,-7.786 -12.872,-11.95 -15.228,-15.229 -27.882,-32.071 -37.986,-49.975 z m 366.205,49.976 c -43.835,43.835 -102.116,67.977 -164.109,67.977 -15.161,0 -30.098,-1.453 -44.659,-4.276 18.864,-11.87 37.661,-24.833 55.998,-38.625 3.2,-2.406 3.841,-6.951 1.435,-10.149 -2.406,-3.2 -6.952,-3.84 -10.149,-1.435 -19.855,14.934 -46.393,32.45 -67.363,45.368 -5.606,-1.62 -11.142,-3.448 -16.596,-5.487 58.968,-35.049 115.237,-79.19 167.435,-131.388 52.192,-52.19 96.333,-108.454 131.381,-167.423 2.049,5.485 3.887,11.051 5.512,16.69 -23.941,38.799 -55.866,83.002 -87.51,118.944 -2.645,3.004 -2.356,7.585 0.649,10.228 1.379,1.212 3.086,1.808 4.787,1.808 2.009,0 4.012,-0.832 5.443,-2.459 30.673,-34.837 58.031,-71.308 81.446,-108.536 2.821,14.559 4.276,29.493 4.276,44.652 10e-4,61.995 -24.139,120.276 -67.976,164.111 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 337.815,406.147 c -4.829,-5.418 0.615,-18.151 12.159,-28.441 11.544,-10.29 24.817,-14.24 29.646,-8.822 4.829,5.417 -0.615,18.151 -12.159,28.441 -11.545,10.29 -24.817,14.24 -29.646,8.822 z"
id="path6"
inkscape:connector-curvature="0" />
</g>
<g
id="g10"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g12"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g14"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g16"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g18"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g20"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g22"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g24"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g26"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g28"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g30"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g32"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g34"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g36"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g38"
transform="translate(-118.9515,-59.419)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.17 272.17"
xml:space="preserve"
sodipodi:docname="mars-with-satellite.svg"
width="272.17001"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs41" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview39"
showgrid="false"
inkscape:zoom="0.74916113"
inkscape:cx="-15.912826"
inkscape:cy="157.50949"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g6" />
<g
id="g6"
transform="translate(-14.578,-42.849)">
<path
d="m 150.663,42.849 c -75.037,0 -136.085,61.047 -136.085,136.085 0,75.038 61.048,136.085 136.085,136.085 75.037,0 136.085,-61.048 136.085,-136.085 0,-75.037 -61.048,-136.085 -136.085,-136.085 z m 94.519,49.737 C 215.47,98.072 194.155,95.67 181.775,85.417 166.119,72.442 142.824,62.802 112.41,56.684 c 12.085,-3.79 24.935,-5.835 38.253,-5.835 37.388,0 71.082,16.104 94.519,41.737 z M 49.864,99.992 c 7.659,4.116 14.848,7.336 20.496,9.16 l 1.405,0.455 c 11.474,3.718 26.173,8.48 38.353,8.48 9.974,0 18.259,-3.194 21.701,-12.769 1.564,-4.354 1.492,-8.272 -0.214,-11.644 -3.639,-7.188 -13.464,-10.107 -25.902,-13.801 -2.913,-0.865 -5.924,-1.76 -8.986,-2.75 -4.31,-1.395 -10.33,-3.021 -17.181,-4.657 5.813,-3.896 11.958,-7.332 18.388,-10.249 35.034,5.547 62.249,15.687 78.747,29.361 9.52,7.883 23.149,11.833 40.721,11.833 9.978,0 21.246,-1.291 33.734,-3.842 3.017,3.811 5.819,7.799 8.394,11.942 -7.815,0.09 -15.483,0.207 -23.256,0.357 -32.772,0.63 -51.646,9.594 -69.899,18.262 -16.304,7.742 -31.704,15.056 -56.158,15.056 -19.363,0 -45.543,-6.853 -75.875,-19.812 4.196,-9.082 9.42,-17.595 15.532,-25.382 z M 71.002,78.711 c 9.393,2.083 17.789,4.256 23.251,6.023 3.154,1.021 6.213,1.929 9.171,2.808 9.751,2.896 18.96,5.631 21.043,9.745 0.436,0.861 0.892,2.351 -0.177,5.326 -4.637,12.897 -27.272,6.767 -50.06,-0.616 L 72.82,101.54 C 67.967,99.972 61.794,97.234 55.123,93.723 59.98,88.283 65.292,83.259 71.002,78.711 Z M 23.02,168.333 c 35.942,5.647 57.003,15.954 59.452,29.178 0.284,1.535 -0.071,2.922 -1.119,4.364 -2.927,4.03 -13.653,11.492 -52.407,16.946 -4.126,-12.559 -6.367,-25.966 -6.367,-39.887 -0.001,-3.57 0.153,-7.104 0.441,-10.601 z m 23.365,84.896 c 22.439,-3.993 52.181,-14.162 77.357,-39.338 42.857,-42.857 53.898,-42.857 78.089,-42.857 9.532,0 21.889,5.026 34.971,10.348 13.57,5.52 27.555,11.194 41.059,12.592 -0.781,6.647 -2.069,13.141 -3.832,19.44 -9.441,0.149 -18.893,-1.263 -28.848,-2.765 -23.035,-3.475 -49.144,-7.414 -80.863,8.749 -36.661,18.676 -56.554,50.852 -67.026,75.957 -20.42,-9.398 -37.963,-24.01 -50.907,-42.126 z m 68.931,48.827 c -3.62,-1.041 -7.173,-2.242 -10.656,-3.586 9.935,-23.833 28.755,-54.35 63.288,-71.943 29.436,-14.998 53.129,-11.422 76.039,-7.966 9.394,1.417 18.359,2.748 27.51,2.855 -2.915,8.266 -6.65,16.149 -11.117,23.543 -29.036,-6.441 -59.028,-1.667 -89.203,14.214 -24.231,12.752 -43.497,30.024 -55.861,42.883 z m 35.347,4.963 c -9.027,0 -17.837,-0.944 -26.341,-2.729 11.947,-11.958 29.304,-26.84 50.581,-38.037 27.413,-14.427 54.562,-19.154 80.787,-14.093 -23.175,33.139 -61.609,54.859 -105.027,54.859 z M 278.55,186.003 c -12.347,-1.311 -25.739,-6.745 -38.734,-12.031 -13.827,-5.625 -26.889,-10.938 -37.985,-10.938 -27.418,0 -40.278,1.733 -83.745,45.2 -25.043,25.043 -54.972,34.354 -76.548,37.691 -3.79,-6.151 -7.074,-12.644 -9.795,-19.422 31.269,-4.529 49.643,-11.06 56.083,-19.926 2.324,-3.201 3.193,-6.839 2.513,-10.521 -3.943,-21.297 -37.42,-31.136 -66.412,-35.676 1.399,-9.598 3.865,-18.853 7.275,-27.643 31.702,13.558 58.277,20.448 79.003,20.448 26.258,0 42.448,-7.689 59.59,-15.83 17.488,-8.305 35.571,-16.893 66.622,-17.49 9.222,-0.177 18.305,-0.308 27.659,-0.402 9.362,17.782 14.672,38.016 14.672,59.47 0,2.373 -0.07,4.729 -0.198,7.07 z"
id="path2"
inkscape:connector-curvature="0" />
</g>
<g
id="g8"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g10"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g12"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g14"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g16"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g18"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g20"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g22"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g24"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g26"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g28"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g30"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g32"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g34"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g36"
transform="translate(-14.578,-42.849)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.044 272.17001"
xml:space="preserve"
sodipodi:docname="neptune-with-satellite.svg"
width="272.04401"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata79"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs77" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview75"
showgrid="false"
inkscape:zoom="0.75655574"
inkscape:cx="-13.59678"
inkscape:cy="155.969"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g42" />
<g
id="g42"
transform="translate(-12.275,-39.769)">
<path
d="m 148.297,39.769 c -36.35,0 -70.524,14.155 -96.227,39.858 -53.06,53.06 -53.06,139.394 0,192.454 25.703,25.703 59.877,39.858 96.227,39.858 36.35,0 70.524,-14.155 96.227,-39.858 53.06,-53.06 53.06,-139.394 0,-192.454 C 218.821,53.924 184.647,39.769 148.297,39.769 Z M 271.474,165.86 c -8.235,-5.915 -18.998,-2.783 -29.532,8.588 -8.691,9.382 -15.31,21.945 -19.67,37.341 -0.602,2.125 0.633,4.336 2.759,4.938 2.127,0.601 4.336,-0.634 4.938,-2.759 4.013,-14.169 10.016,-25.637 17.842,-34.084 3.54,-3.822 12.475,-12.208 18.997,-7.527 8.074,5.799 7.154,21.44 6.385,27.895 -1.709,14.318 -7.573,26.757 -15.687,33.274 -2.358,1.895 -5.645,3.751 -7.902,1.84 -2.635,-2.23 -3.822,-7.371 -3.344,-14.476 0.148,-2.204 -1.519,-4.111 -3.723,-4.26 -2.226,-0.138 -4.111,1.519 -4.26,3.723 -0.672,9.986 1.399,17.091 6.158,21.119 2.164,1.832 4.646,2.741 7.302,2.741 1.832,0 3.748,-0.447 5.699,-1.306 -5.142,8.369 -11.327,16.273 -18.569,23.516 -1.59,1.59 -3.216,3.13 -4.873,4.625 -3.667,-4.799 -6.198,-12.047 -7.225,-20.88 -0.256,-2.194 -2.241,-3.763 -4.437,-3.511 -2.194,0.255 -3.766,2.241 -3.511,4.436 1.23,10.565 4.34,19.14 9.059,25.132 -16.61,13.223 -36.039,21.995 -56.813,25.702 5.189,-6.479 10.531,-16.472 12.156,-31.099 0.244,-2.196 -1.338,-4.173 -3.534,-4.417 -2.186,-0.244 -4.173,1.338 -4.417,3.534 -2.288,20.594 -12.727,30.327 -17.241,33.631 -3.223,0.241 -6.469,0.364 -9.735,0.364 -34.213,0 -66.378,-13.323 -90.57,-37.516 -33.004,-33.004 -44.189,-79.685 -33.57,-121.967 11.195,1.303 26.82,4.299 43.035,11.16 0.509,0.215 1.037,0.317 1.557,0.317 1.559,0 3.04,-0.917 3.686,-2.442 0.861,-2.034 -0.09,-4.381 -2.125,-5.242 C 53.868,141.293 38.021,138.111 26.373,136.664 32.383,117.86 42.832,100.179 57.727,85.285 68.941,74.071 81.87,65.197 95.92,58.898 c -0.781,0.832 -1.538,1.704 -2.252,2.627 -5.132,6.638 -6.665,13.818 -4.432,20.764 0.676,2.103 2.932,3.261 5.032,2.584 2.104,-0.676 3.26,-2.929 2.584,-5.032 -3.119,-9.701 6.766,-18.895 16.179,-23.821 8.789,-4.599 19.379,-7.341 31.542,-8.193 1.239,-0.035 2.48,-0.058 3.724,-0.058 12.251,0 24.237,1.717 35.691,5.022 2.36,0.884 4.63,1.872 6.793,2.972 5.949,3.025 9.001,6.12 9.604,9.737 0.85,5.096 -4.18,9.225 -6.381,10.763 -11.526,8.055 -26.655,7.89 -37.317,6.332 -2.189,-0.324 -4.217,1.194 -4.536,3.38 -0.319,2.186 1.194,4.217 3.38,4.536 3.699,0.54 7.881,0.924 12.299,0.924 10.028,0 21.264,-1.981 30.757,-8.614 7.284,-5.089 10.815,-11.882 9.689,-18.635 -0.103,-0.615 -0.243,-1.208 -0.409,-1.783 8.589,4.523 16.694,10.047 24.165,16.52 -8.145,14.582 -23.589,20.575 -35.122,23.032 -2.16,0.46 -3.538,2.585 -3.078,4.746 0.4,1.88 2.061,3.167 3.908,3.167 0.276,0 0.557,-0.029 0.838,-0.089 12.722,-2.711 29.678,-9.305 39.469,-25.296 0.273,0.269 0.551,0.531 0.823,0.803 23.661,23.662 36.104,54.354 37.344,85.415 -1.287,-1.834 -2.844,-3.479 -4.74,-4.841 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 137.556,85.235 c 0.603,0.324 1.251,0.478 1.891,0.478 1.425,0 2.804,-0.764 3.526,-2.106 1.046,-1.946 0.317,-4.371 -1.628,-5.417 -1.062,-0.571 -6.264,-3.626 -4.383,-7.716 1.226,-2.667 4.829,-4.64 11.012,-6.032 6.876,-1.548 17.445,-1.943 24.605,2.034 1.188,0.66 1.884,1.448 1.862,2.11 -0.027,0.803 -0.928,2.024 -2.877,2.94 -2,0.94 -2.858,3.322 -1.919,5.322 0.94,1.999 3.322,2.859 5.321,1.918 4.54,-2.133 7.332,-5.838 7.47,-9.91 0.128,-3.778 -2.05,-7.195 -5.973,-9.374 -9.12,-5.066 -21.604,-4.792 -30.247,-2.845 -5.602,1.261 -13.409,3.721 -16.523,10.494 -3.061,6.654 0.099,13.93 7.863,18.104 z"
id="path4"
inkscape:connector-curvature="0" />
<path
d="m 100.492,96.756 c 2.997,2.273 6.354,4.294 10.263,6.181 0.561,0.271 1.152,0.398 1.735,0.398 1.487,0 2.916,-0.833 3.605,-2.263 0.96,-1.99 0.125,-4.381 -1.864,-5.341 -3.424,-1.652 -6.337,-3.402 -8.906,-5.35 -1.76,-1.335 -4.27,-0.991 -5.604,0.77 -1.334,1.762 -0.989,4.271 0.771,5.605 z"
id="path6"
inkscape:connector-curvature="0" />
<path
d="m 179.091,111.757 c 0.047,10e-4 4.807,-0.026 7.63,-0.253 2.202,-0.177 3.844,-2.106 3.667,-4.308 -0.177,-2.203 -2.137,-3.843 -4.308,-3.667 -4.037,0.325 -6.639,0.235 -6.68,0.233 -2.181,-0.089 -4.063,1.634 -4.149,3.84 -0.086,2.208 1.633,4.068 3.84,4.155 z"
id="path8"
inkscape:connector-curvature="0" />
<path
d="m 201.867,133.619 c 0.336,0 9.337,-2.448 13.524,-3.81 2.101,-0.683 3.25,-2.94 2.566,-5.041 -0.684,-2.101 -2.938,-3.25 -5.041,-2.567 -4.04,1.314 -8.099,2.507 -12.062,3.547 -2.138,0.561 -3.415,2.748 -2.854,4.884 0.472,1.798 2.092,2.987 3.867,2.987 z"
id="path10"
inkscape:connector-curvature="0" />
<path
d="m 187.617,128.737 c -46.298,8.716 -77.082,-4.029 -94.75,-16.257 -1.817,-1.257 -4.309,-0.804 -5.565,1.013 -1.257,1.816 -0.804,4.308 1.013,5.565 14.605,10.108 37.502,20.561 69.73,20.561 9.526,0 19.871,-0.914 31.054,-3.02 2.171,-0.409 3.6,-2.5 3.19,-4.671 -0.41,-2.172 -2.508,-3.602 -4.672,-3.191 z"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 77.141,110.083 c 0.771,0.723 1.753,1.081 2.733,1.081 1.068,0 2.133,-0.425 2.92,-1.266 1.51,-1.612 1.427,-4.144 -0.185,-5.654 -3.733,-3.497 -5.615,-5.951 -5.675,-6.029 -1.327,-1.763 -3.831,-2.119 -5.596,-0.795 -1.768,1.326 -2.125,3.833 -0.8,5.6 0.092,0.121 2.267,3.001 6.603,7.063 z"
id="path14"
inkscape:connector-curvature="0" />
<path
d="m 41.149,171.992 c -1.633,-0.278 -3.294,-0.535 -4.938,-0.763 -2.188,-0.302 -4.208,1.224 -4.512,3.411 -0.304,2.188 1.223,4.208 3.412,4.513 1.563,0.217 5.149,0.783 5.373,0.783 1.915,0 3.607,-1.379 3.938,-3.33 0.37,-2.178 -1.095,-4.244 -3.273,-4.614 z"
id="path16"
inkscape:connector-curvature="0" />
<path
d="m 53.789,182.977 c 13.524,3.751 45.748,15.723 52.875,45.778 0.436,1.839 2.077,3.078 3.889,3.078 0.306,0 0.616,-0.035 0.926,-0.109 2.149,-0.51 3.479,-2.666 2.969,-4.815 -3.121,-13.162 -10.671,-24.582 -22.441,-33.944 -9.71,-7.724 -22.186,-13.843 -36.079,-17.697 -2.125,-0.589 -4.333,0.656 -4.924,2.785 -0.59,2.129 0.656,4.333 2.785,4.924 z"
id="path18"
inkscape:connector-curvature="0" />
<path
d="m 110.315,242.16 c -2.004,-0.927 -4.382,-0.057 -5.311,1.948 -1.013,2.187 -2.39,4.152 -4.093,5.843 -1.568,1.557 -1.577,4.089 -0.02,5.657 0.782,0.788 1.81,1.182 2.838,1.182 1.019,0 2.039,-0.387 2.818,-1.162 2.378,-2.362 4.301,-5.106 5.715,-8.157 0.929,-2.005 0.057,-4.383 -1.947,-5.311 z"
id="path20"
inkscape:connector-curvature="0" />
<path
d="m 90.255,255.468 c -8.356,1.642 -17.778,-1.182 -24.588,-7.365 -12.756,-11.582 -12.75,-24.255 -8.729,-29.174 3.817,-4.669 8.713,-5.013 12.147,-4.479 6.578,1.022 13.085,6.143 15.473,12.175 0.813,2.054 3.139,3.062 5.191,2.247 2.054,-0.813 3.06,-3.137 2.247,-5.191 -3.473,-8.774 -12.187,-15.66 -21.683,-17.136 -7.773,-1.208 -14.724,1.392 -19.57,7.321 -10.192,12.469 -0.554,30.991 9.545,40.16 6.995,6.351 16.232,9.895 25.219,9.894 2.12,0 4.228,-0.197 6.288,-0.602 2.168,-0.426 3.58,-2.528 3.155,-4.696 -0.425,-2.167 -2.526,-3.58 -4.695,-3.154 z"
id="path22"
inkscape:connector-curvature="0" />
<path
d="m 82.824,236.937 c -2.256,1.781 -4.846,1.359 -6.622,0.692 -3.652,-1.372 -6.874,-4.924 -7.496,-8.263 -0.404,-2.171 -2.489,-3.603 -4.665,-3.2 -2.172,0.405 -3.604,2.493 -3.2,4.665 1.129,6.061 6.289,11.936 12.547,14.287 1.924,0.723 3.86,1.08 5.739,1.08 3.157,0 6.152,-1.008 8.651,-2.98 1.734,-1.368 2.031,-3.883 0.663,-5.618 -1.367,-1.735 -3.883,-2.032 -5.617,-0.663 z"
id="path24"
inkscape:connector-curvature="0" />
<path
d="m 109.058,172.892 c -1.629,-1.493 -4.159,-1.385 -5.652,0.243 -1.494,1.628 -1.385,4.158 0.243,5.652 10.774,9.886 29.278,29.985 32.162,53.524 1.465,11.963 -1.974,23.543 -9.683,32.606 -3.238,3.808 -6.859,6.886 -10.763,9.15 -1.911,1.108 -2.562,3.556 -1.453,5.467 0.742,1.279 2.084,1.994 3.464,1.994 0.681,0 1.372,-0.174 2.003,-0.541 4.693,-2.722 9.014,-6.385 12.843,-10.887 9.176,-10.787 13.271,-24.552 11.53,-38.762 -3.196,-26.086 -23.109,-47.815 -34.694,-58.446 z"
id="path26"
inkscape:connector-curvature="0" />
<path
d="m 94.011,170.834 c 0.716,0.531 1.551,0.788 2.379,0.788 1.223,0 2.431,-0.56 3.216,-1.618 1.316,-1.774 0.944,-4.28 -0.831,-5.595 -1.901,-1.41 -3.876,-2.792 -5.871,-4.108 -1.844,-1.217 -4.325,-0.708 -5.542,1.135 -1.217,1.844 -0.708,4.325 1.135,5.542 1.874,1.235 3.729,2.533 5.514,3.856 z"
id="path28"
inkscape:connector-curvature="0" />
<path
d="m 151.585,173.576 c -1.26,-1.815 -3.749,-2.266 -5.564,-1.009 -1.815,1.257 -2.268,3.749 -1.012,5.564 0.312,0.451 30.974,45.477 13.988,80.185 -0.971,1.984 -0.149,4.38 1.835,5.351 0.565,0.277 1.165,0.408 1.755,0.408 1.479,0 2.901,-0.824 3.596,-2.243 7.945,-16.236 7.9,-36.706 -0.13,-59.195 -5.964,-16.7 -14.125,-28.565 -14.468,-29.061 z"
id="path30"
inkscape:connector-curvature="0" />
<path
d="m 257.729,197.605 c 2.204,-1.072 3.393,3.135 3.063,8.028 -0.148,2.204 1.518,4.112 3.722,4.26 0.092,0.006 0.183,0.009 0.273,0.009 2.086,0 3.845,-1.618 3.987,-3.73 0.482,-7.146 -1.438,-12.739 -5.267,-15.344 -2.692,-1.832 -5.965,-1.991 -9.21,-0.45 -1.996,0.948 -2.845,3.334 -1.897,5.33 0.948,1.996 3.344,2.863 5.329,1.897 z"
id="path32"
inkscape:connector-curvature="0" />
<path
d="m 219.052,227.503 c -0.246,1.928 -0.436,3.879 -0.563,5.801 -0.147,2.204 1.521,4.11 3.725,4.257 0.091,0.006 0.181,0.009 0.271,0.009 2.088,0 3.846,-1.62 3.987,-3.734 0.117,-1.762 0.291,-3.552 0.517,-5.322 0.279,-2.191 -1.271,-4.194 -3.463,-4.473 -2.187,-0.282 -4.195,1.272 -4.474,3.462 z"
id="path34"
inkscape:connector-curvature="0" />
<path
d="m 215.557,170.546 c -1.205,1.852 -0.681,4.33 1.171,5.535 0.674,0.438 1.43,0.647 2.178,0.647 1.309,0 2.59,-0.641 3.356,-1.819 11.387,-17.501 23.308,-27.803 36.441,-31.495 2.127,-0.598 3.366,-2.806 2.769,-4.933 -0.598,-2.126 -2.809,-3.368 -4.933,-2.768 -15.084,4.24 -28.491,15.634 -40.982,34.833 z"
id="path36"
inkscape:connector-curvature="0" />
<path
d="m 206.98,213.368 c 0.409,-2.171 -1.019,-4.263 -3.189,-4.672 -2.163,-0.412 -4.263,1.018 -4.672,3.189 -6.977,36.974 4.454,68.118 4.943,69.425 0.603,1.606 2.126,2.596 3.745,2.596 0.466,0 0.939,-0.082 1.4,-0.254 2.068,-0.773 3.118,-3.077 2.348,-5.146 -0.112,-0.3 -11.122,-30.441 -4.575,-65.138 z"
id="path38"
inkscape:connector-curvature="0" />
</g>
<g
id="g44"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g46"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g48"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g50"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g52"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g54"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g56"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g58"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g60"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g62"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g64"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g66"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g68"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g70"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g72"
transform="translate(-12.275,-39.769)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 265.423 265.423" width="265.423" height="265.423" style="enable-background:new 0 0 265.423 265.423;" xml:space="preserve">
<g>
<path d="M178.689,144.714c52.71-52.71,86.132-138.415,86.463-139.274c0.569-1.477,0.215-3.149-0.903-4.268
s-2.792-1.473-4.268-0.904c-0.86,0.332-86.565,33.754-139.275,86.464c-8.581,8.581-15.959,16.57-22.168,24.013l-10.158-2.289
c7.048-17.806,10.429-32.508,10.662-33.541c0.348-1.543-0.245-3.146-1.515-4.091c-1.27-0.942-2.976-1.051-4.354-0.273
c-1.579,0.892-38.902,22.154-60.387,51.041c-11.011,14.805-16.817,26.156-17.75,34.704c-0.154,1.41,0.451,2.797,1.589,3.644
l18.829,14.003c0.702,0.521,1.541,0.79,2.388,0.79c0.527,0,1.058-0.104,1.559-0.316c6.105-2.584,12.977-8.438,20.85-17.764
l12.899,2.908c-0.044,0.909-0.057,1.807-0.027,2.69l-14.11,14.11c-1.562,1.562-1.562,4.095,0,5.656l24.395,24.396
c0.781,0.781,1.805,1.172,2.829,1.172c1.023,0,2.047-0.391,2.829-1.172l14.12-14.119c0.362,0.012,0.724,0.025,1.091,0.025
c0.522,0,1.05-0.016,1.581-0.041l2.91,12.893c-9.325,7.873-15.179,14.745-17.762,20.849c-0.553,1.307-0.373,2.809,0.474,3.946
l14.003,18.828c0.759,1.021,1.953,1.613,3.209,1.613c0.144,0,0.289-0.008,0.434-0.023c8.547-0.933,19.898-6.738,34.704-17.749
c28.887-21.485,50.15-58.809,51.042-60.387c0.778-1.378,0.67-3.085-0.274-4.354c-0.945-1.27-2.55-1.865-4.091-1.515
c-1.032,0.232-15.736,3.614-33.544,10.663l-2.286-10.138C162.105,160.693,170.084,153.318,178.689,144.714z M220.677,76.274
c-12.517-8.22-23.307-19.01-31.527-31.527c26.944-16.301,52.071-27.837,64.873-33.348
C248.515,24.199,236.982,49.325,220.677,76.274z M126.363,92.387c16.565-16.565,36.509-31.196,55.974-43.438
c8.876,13.571,20.565,25.261,34.137,34.138c-12.24,19.459-26.872,39.4-43.443,55.971c-30.455,30.455-52.945,45.26-68.755,45.26
c-6.154,0-11.269-2.249-16.097-7.076c-7.308-7.308-8.891-15.574-5.132-26.806C87.963,135.744,102.536,116.215,126.363,92.387z
M38.273,166.066l-14.916-11.093c1.527-6.898,6.847-16.506,15.849-28.609c14.469-19.453,37.249-35.72,49.478-43.65
c-4.078,13.993-13.103,40.49-27.571,59.944C52.11,154.762,44.44,162.62,38.273,166.066z M65.815,149.704
c0.568-0.744,1.138-1.495,1.716-2.272c7.214-9.7,13.09-20.861,17.73-31.478l7.704,1.736c-8.757,11.369-14.55,21.378-17.504,30.208
c-0.425,1.27-0.772,2.51-1.083,3.737L65.815,149.704z M86.237,197.926l-18.738-18.738l7.511-7.511
c1.554,4.026,4.049,7.758,7.512,11.221c3.483,3.483,7.203,5.977,11.222,7.521L86.237,197.926z M139.055,226.214
c-12.104,9.002-21.709,14.322-28.608,15.849l-11.093-14.915c3.447-6.167,11.305-13.837,23.409-22.839
c19.454-14.47,45.951-23.494,59.944-27.571C174.775,188.965,158.509,211.745,139.055,226.214z M149.465,180.16
c-10.616,4.64-21.778,10.515-31.477,17.729c-0.778,0.579-1.53,1.149-2.275,1.718l-1.928-8.543
c9.786-2.453,20.97-8.558,33.95-18.573L149.465,180.16z"/>
<path d="M172.264,113.241c5.209,0,10.105-2.028,13.789-5.712c3.684-3.683,5.712-8.579,5.712-13.788s-2.028-10.105-5.711-13.788
c-3.683-3.684-8.58-5.712-13.789-5.712c-5.208,0-10.105,2.028-13.788,5.712c-3.684,3.683-5.712,8.579-5.712,13.788
s2.028,10.105,5.712,13.788C162.159,111.213,167.055,113.241,172.264,113.241z M164.132,85.609c2.172-2.172,5.06-3.368,8.131-3.368
c3.072,0,5.96,1.196,8.132,3.368c2.172,2.172,3.368,5.061,3.368,8.132s-1.196,5.96-3.368,8.132
c-2.172,2.172-5.06,3.368-8.132,3.368c-3.072,0-5.959-1.196-8.132-3.368c-2.172-2.172-3.368-5.061-3.368-8.132
S161.96,87.781,164.132,85.609z"/>
<path d="M35.502,194.423c-19.575,0-35.5,15.925-35.5,35.5v31.5c0,2.209,1.791,4,4,4h31.5c19.575,0,35.5-15.925,35.5-35.5
S55.077,194.423,35.502,194.423z M46.16,207.12c6.697,0,12.145,5.448,12.145,12.146c0,6.696-5.448,12.145-12.145,12.145H34.015
v-12.145C34.015,212.568,39.463,207.12,46.16,207.12z M35.502,257.423h-27.5v-27.5c0-15.036,12.132-27.285,27.12-27.49
c-5.478,3.604-9.108,9.799-9.108,16.833v16.145c0,2.209,1.791,4,4,4H46.16c7.034,0,13.229-3.63,16.833-9.108
C62.788,245.29,50.539,257.423,35.502,257.423z"/>
<path d="M215.69,68.984c0.702,0.497,1.509,0.735,2.309,0.735c1.253,0,2.488-0.588,3.268-1.688
c2.309-3.259,6.74-11.083,13.172-23.255c1.032-1.953,0.285-4.374-1.668-5.405c-1.952-1.033-4.373-0.285-5.405,1.667
c-7.81,14.78-11.178,20.323-12.627,22.37C213.461,65.211,213.887,67.707,215.69,68.984z"/>
<path d="M234.237,36.556c0.588,0.304,1.215,0.448,1.834,0.448c1.448,0,2.846-0.789,3.557-2.164
c2.243-4.338,3.743-7.294,3.743-7.294c1-1.971,0.213-4.378-1.757-5.378c-1.969-0.997-4.377-0.213-5.377,1.757
c-0.003,0.007-1.492,2.939-3.716,7.241C231.507,33.129,232.275,35.542,234.237,36.556z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.04324 272.17001"
xml:space="preserve"
sodipodi:docname="uranus-with-satellite.svg"
inkscape:version="0.92.1 r15371"
width="272.04324"
height="272.17001"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview57"
showgrid="false"
inkscape:zoom="0.69664401"
inkscape:cx="-68.159453"
inkscape:cy="136.0855"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Capa_1" />
<g
id="g24"
transform="translate(-66.724,-33.299)">
<path
d="M 298.973,73.157 C 273.271,47.454 239.096,33.299 202.746,33.299 c -36.35,0 -70.523,14.155 -96.227,39.858 -53.06,53.06 -53.06,139.394 0,192.454 25.703,25.703 59.877,39.858 96.227,39.858 36.35,0 70.524,-14.155 96.227,-39.858 53.059,-53.061 53.059,-139.395 0,-192.454 z m -5.657,186.796 c -11.681,11.681 -25.225,20.819 -39.956,27.156 17.744,-11.698 34.215,-26.208 48.558,-42.92 1.438,-1.676 1.246,-4.202 -0.43,-5.64 -1.678,-1.44 -4.202,-1.247 -5.641,0.43 -20.23,23.57 -48.084,44.664 -75.601,57.302 -5.753,0.781 -11.595,1.188 -17.501,1.188 -4.154,0 -8.276,-0.2 -12.359,-0.589 17.939,-6.343 34.995,-14.887 50.872,-25.52 1.836,-1.229 2.327,-3.714 1.098,-5.549 -1.229,-1.835 -3.712,-2.328 -5.549,-1.098 -19.625,13.143 -41.113,22.987 -63.873,29.279 -5.029,-1.193 -9.966,-2.688 -14.791,-4.477 4.071,-0.974 8.123,-2.079 12.128,-3.313 2.111,-0.651 3.296,-2.89 2.645,-5.001 -0.649,-2.11 -2.89,-3.294 -5,-2.645 -7.405,2.282 -14.973,4.095 -22.518,5.427 -11.638,-5.838 -22.419,-13.502 -31.997,-22.834 4.553,-0.896 9.091,-1.914 13.555,-3.076 2.138,-0.556 3.421,-2.74 2.864,-4.878 -0.555,-2.138 -2.736,-3.42 -4.878,-2.864 -5.959,1.55 -12.05,2.85 -18.137,3.902 C 96.417,242.502 88.55,229.31 83.208,215.361 c 7.844,-2.009 15.644,-4.451 23.246,-7.289 2.069,-0.772 3.121,-3.077 2.348,-5.146 -0.772,-2.069 -3.079,-3.122 -5.146,-2.348 -7.545,2.817 -15.292,5.233 -23.078,7.202 -1.7,-5.44 -3.033,-10.971 -3.992,-16.555 17.341,-5.604 33.99,-13.242 49.518,-22.786 1.882,-1.157 2.47,-3.62 1.313,-5.502 -1.158,-1.881 -3.62,-2.47 -5.503,-1.313 -14.584,8.964 -30.193,16.189 -46.445,21.555 -0.793,-7.386 -0.95,-14.826 -0.465,-22.234 8.314,-3.591 16.365,-7.688 23.955,-12.209 1.897,-1.13 2.521,-3.585 1.39,-5.483 -1.13,-1.898 -3.585,-2.521 -5.483,-1.39 -6.041,3.597 -12.387,6.918 -18.932,9.917 1.118,-8.127 3.015,-16.165 5.69,-23.995 12.924,-7.601 26.339,-17.69 37.186,-27.603 1.631,-1.49 1.745,-4.02 0.255,-5.651 -1.491,-1.632 -4.021,-1.745 -5.651,-0.254 -8.4,7.676 -17.365,14.679 -26.729,20.916 6.137,-13.178 14.632,-25.519 25.492,-36.379 24.192,-24.192 56.357,-37.516 90.57,-37.516 4.656,0 9.271,0.255 13.836,0.743 -1.347,4.072 -2.817,8.13 -4.393,12.113 -0.813,2.054 0.193,4.378 2.248,5.191 0.482,0.191 0.98,0.282 1.471,0.282 1.593,0 3.099,-0.958 3.721,-2.529 1.813,-4.582 3.485,-9.26 5.002,-13.947 5.613,0.961 11.128,2.297 16.52,3.984 -6.004,23.81 -15.831,46.266 -29.255,66.792 -1.209,1.849 -0.69,4.328 1.158,5.537 0.676,0.442 1.435,0.653 2.186,0.653 1.305,0 2.584,-0.638 3.352,-1.811 13.785,-21.077 23.913,-44.115 30.148,-68.536 14.147,5.434 27.287,13.409 38.866,23.679 -2.015,11.874 -5.07,23.73 -9.118,35.272 -0.731,2.084 0.365,4.367 2.45,5.099 0.438,0.154 0.885,0.227 1.324,0.227 1.651,0 3.197,-1.03 3.774,-2.677 3.599,-10.259 6.438,-20.76 8.495,-31.309 16.699,17.153 27.627,37.862 32.781,59.675 -6.798,23.85 -17.03,45.879 -30.438,65.486 -1.247,1.823 -0.779,4.313 1.044,5.56 0.69,0.472 1.477,0.699 2.254,0.699 1.276,0 2.531,-0.61 3.306,-1.743 11.018,-16.112 19.958,-33.794 26.699,-52.727 3.538,36.789 -8.748,74.828 -36.862,102.942 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 197.27,216.666 c -1.811,1.267 -2.251,3.761 -0.984,5.571 0.778,1.112 2.02,1.707 3.281,1.707 0.791,0 1.592,-0.235 2.289,-0.723 22.879,-16.008 42.555,-36.287 58.479,-60.273 4.438,-6.686 8.573,-13.669 12.288,-20.754 1.025,-1.957 0.271,-4.375 -1.686,-5.4 -1.952,-1.025 -4.374,-0.272 -5.4,1.685 -3.587,6.843 -7.58,13.587 -11.866,20.044 -15.37,23.149 -34.347,42.711 -56.401,58.143 z"
id="path6"
inkscape:connector-curvature="0" />
<path
d="m 164.66,235.919 c -4.826,2.292 -9.791,4.417 -14.757,6.314 -2.063,0.789 -3.098,3.101 -2.309,5.164 0.609,1.594 2.127,2.573 3.737,2.573 0.475,0 0.957,-0.085 1.427,-0.265 5.16,-1.972 10.319,-4.179 15.333,-6.561 1.996,-0.948 2.845,-3.334 1.897,-5.329 -0.946,-1.994 -3.333,-2.842 -5.328,-1.896 z"
id="path8"
inkscape:connector-curvature="0" />
<path
d="m 240.418,146.561 c 1.275,-1.804 0.846,-4.3 -0.958,-5.575 -1.803,-1.275 -4.3,-0.845 -5.575,0.958 -30.046,42.51 -72.305,73.713 -118.993,87.863 -2.114,0.641 -3.309,2.874 -2.668,4.988 0.523,1.728 2.11,2.841 3.826,2.841 0.385,0 0.775,-0.056 1.162,-0.173 48.383,-14.663 92.138,-46.946 123.206,-90.902 z"
id="path10"
inkscape:connector-curvature="0" />
<path
d="m 131.021,125.104 c 22.662,-18.894 41.814,-42.449 55.387,-68.119 1.032,-1.953 0.286,-4.373 -1.667,-5.406 -1.954,-1.035 -4.373,-0.286 -5.405,1.667 -13.09,24.758 -31.568,47.481 -53.438,65.714 -1.696,1.415 -1.926,3.937 -0.511,5.634 0.791,0.949 1.929,1.438 3.074,1.438 0.903,0 1.811,-0.304 2.56,-0.928 z"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 304.583,162.73 c 0.537,0.244 1.1,0.359 1.653,0.359 1.52,0 2.974,-0.872 3.644,-2.346 0.838,-1.843 1.658,-3.714 2.44,-5.563 0.861,-2.034 -0.091,-4.381 -2.125,-5.242 -2.035,-0.861 -4.382,0.09 -5.242,2.125 -0.755,1.784 -1.548,3.59 -2.356,5.37 -0.914,2.012 -0.025,4.383 1.986,5.297 z"
id="path14"
inkscape:connector-curvature="0" />
<path
d="m 301.081,169.845 c -1.931,-1.072 -4.365,-0.374 -5.438,1.557 -5.468,9.855 -11.719,19.443 -18.58,28.495 -25.229,33.293 -57.633,58.594 -93.705,73.166 -2.049,0.828 -3.038,3.159 -2.211,5.207 0.629,1.558 2.128,2.503 3.71,2.503 0.499,0 1.007,-0.094 1.497,-0.292 37.412,-15.114 70.983,-41.308 97.085,-75.752 7.089,-9.353 13.548,-19.26 19.2,-29.446 1.071,-1.932 0.374,-4.366 -1.558,-5.438 z"
id="path16"
inkscape:connector-curvature="0" />
<path
d="m 190.943,141.11 c -4.038,4.545 -8.354,8.994 -12.827,13.222 -1.605,1.518 -1.678,4.049 -0.16,5.655 0.787,0.833 1.846,1.252 2.908,1.252 0.985,0 1.974,-0.362 2.746,-1.093 4.643,-4.387 9.122,-9.004 13.313,-13.723 1.468,-1.652 1.318,-4.18 -0.334,-5.647 -1.651,-1.466 -4.179,-1.318 -5.646,0.334 z"
id="path18"
inkscape:connector-curvature="0" />
<path
d="m 161.323,130.713 c -1.609,1.514 -1.688,4.045 -0.174,5.654 0.787,0.837 1.85,1.26 2.915,1.26 0.982,0 1.967,-0.36 2.739,-1.086 18.801,-17.681 32.125,-35.242 40.733,-53.688 0.934,-2.001 0.068,-4.382 -1.934,-5.316 -2.001,-0.934 -4.382,-0.069 -5.316,1.933 -8.17,17.509 -20.915,34.271 -38.963,51.243 z"
id="path20"
inkscape:connector-curvature="0" />
<path
d="m 148.218,142.343 c -3.322,2.801 -6.804,5.649 -10.644,8.706 -1.729,1.376 -2.014,3.893 -0.638,5.621 0.789,0.992 1.955,1.508 3.132,1.508 0.873,0 1.752,-0.285 2.488,-0.871 3.899,-3.104 7.438,-5.999 10.817,-8.849 1.689,-1.424 1.904,-3.948 0.479,-5.637 -1.422,-1.687 -3.947,-1.902 -5.634,-0.478 z"
id="path22"
inkscape:connector-curvature="0" />
</g>
<g
id="g26"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g28"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g30"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g32"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g34"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g36"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g38"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g40"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g42"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g44"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g46"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g48"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g50"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g52"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g54"
transform="translate(-66.724,-33.299)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.17001 272.17001"
xml:space="preserve"
sodipodi:docname="venus-with-satellite.svg"
width="272.17001"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs41" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview39"
showgrid="false"
inkscape:zoom="0.72525674"
inkscape:cx="-54.610822"
inkscape:cy="136.085"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g6" />
<g
id="g6"
transform="translate(-53.232,-26.616)">
<path
d="m 189.317,26.616 c -75.038,0 -136.085,61.048 -136.085,136.085 0,75.037 61.047,136.085 136.085,136.085 75.038,0 136.085,-61.047 136.085,-136.085 0,-75.038 -61.048,-136.085 -136.085,-136.085 z m 114.537,78.799 c -19.285,81.007 -76.736,147.79 -154.087,179.114 -5.259,-1.711 -10.371,-3.751 -15.309,-6.102 80.857,-31.451 141.937,-101.332 162.187,-185.549 2.629,4.029 5.038,8.214 7.209,12.537 z M 163.18,139.149 c 26.371,-28.772 46.301,-63.476 57.841,-100.56 13.174,3.367 25.536,8.784 36.729,15.887 -19.382,87.483 -83.595,159.155 -168.504,188.074 -8.839,-11.054 -15.885,-23.598 -20.7,-37.19 35.734,-14.765 68.396,-37.583 94.634,-66.211 z M 66.097,197.717 C 64.659,192.664 63.525,187.485 62.714,182.201 125,152.771 174.179,99.363 198.318,34.937 c 5.041,0.352 10.001,0.997 14.865,1.918 -11.221,35.723 -30.474,69.147 -55.901,96.888 -25.304,27.609 -56.763,49.647 -91.185,63.974 z M 189.317,34.616 c 0.192,0 0.382,0.006 0.573,0.007 -23.415,60.543 -69.7,110.809 -128.17,139.196 -0.317,-3.665 -0.488,-7.372 -0.488,-11.118 0,-70.626 57.458,-128.085 128.085,-128.085 z M 94.827,249.08 c 85.048,-30.115 149.458,-102 170.022,-189.755 9.626,7.052 18.236,15.411 25.562,24.818 -18.383,87.024 -81.532,159.278 -165.428,189.276 -11.251,-6.562 -21.416,-14.787 -30.156,-24.339 z m 67.417,38.818 c 71.824,-32.367 125.65,-94.933 146.817,-170.653 4.421,11.608 7.2,24.017 8.052,36.946 -20.52,57.053 -60.724,105.217 -113.336,135.774 -4.748,0.536 -9.571,0.821 -14.46,0.821 -9.287,0 -18.342,-1.002 -27.073,-2.888 z m 63.449,-2.382 c 39.622,-27.44 71.097,-65.121 90.95,-108.895 -5.626,51.82 -42.283,94.456 -90.95,108.895 z"
id="path2"
inkscape:connector-curvature="0" />
</g>
<g
id="g8"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g10"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g12"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g14"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g16"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g18"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g20"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g22"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g24"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g26"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g28"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g30"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g32"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g34"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g36"
transform="translate(-53.232,-26.616)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -0,0 +1,43 @@
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":11},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":10},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":11},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":9},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":10},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":11},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":0,"ship_count":5,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":8},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":9},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":10},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":11},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":11},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":7},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":8},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":9},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":10},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":11}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":10},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":6},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":7},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":8},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":9},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":10},{"id":12,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":9},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":5},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":6},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":7},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":8},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":9},{"id":12,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9},{"id":14,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":8},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":4},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":5},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":6},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":7},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":8},{"id":12,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":14,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9},{"id":16,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":7},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":3},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":4},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":5},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":6},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":7},{"id":12,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7},{"id":14,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":16,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9},{"id":18,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":1,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":6},{"id":1,"ship_count":5,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":2},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":3},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":4},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":5},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":6},{"id":12,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":14,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7},{"id":16,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":18,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9},{"id":20,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":0,"x":-3.0,"y":5.0,"owner":null,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":5},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":10},{"id":2,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":1},{"id":3,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":2},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":3},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":4},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":5},{"id":22,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":5},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5},{"id":14,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":16,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7},{"id":18,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":20,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":4},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":9},{"id":24,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":4,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":1},{"id":5,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":2},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":3},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":4},{"id":22,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":4},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4},{"id":20,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5},{"id":16,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":18,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":3},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":8},{"id":24,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7},{"id":25,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":6,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":1},{"id":7,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":2},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":3},{"id":22,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":3},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":20,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4},{"id":18,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":2},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":7},{"id":24,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":25,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5},{"id":27,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":10},{"id":8,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":1},{"id":9,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":2},{"id":22,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":2},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2},{"id":20,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":11,"ship_count":1,"origin":"tetratos","destination":"protos","owner":2,"turns_remaining":1},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":6},{"id":24,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5},{"id":25,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4},{"id":27,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":9},{"id":29,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":10},{"id":10,"ship_count":1,"origin":"protos","destination":"tetratos","owner":1,"turns_remaining":1},{"id":22,"ship_count":1,"origin":"protos","destination":"duteros","owner":1,"turns_remaining":1},{"id":13,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":1,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":5},{"id":24,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4},{"id":25,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":27,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":8},{"id":29,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":9},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":10},{"id":15,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":3,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":4},{"id":33,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":5},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":25,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2},{"id":27,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":7},{"id":29,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":8},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":9},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":10},{"id":17,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":3},{"id":33,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":4},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2},{"id":34,"ship_count":2,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":5},{"id":19,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1},{"id":27,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":6},{"id":29,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":7},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":8},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":9}]}
{"planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":3,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":2},{"id":33,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":3},{"id":21,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1},{"id":34,"ship_count":2,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":4},{"id":35,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":5},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":8},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":5},{"id":29,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":6},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":7}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":4,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":31,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":23,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":2,"turns_remaining":1},{"id":33,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":2},{"id":36,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":5},{"id":34,"ship_count":2,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":3},{"id":35,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":4},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":7},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":4},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":6},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":5}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":9,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":5,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":10},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":4},{"id":33,"ship_count":2,"origin":"protos","destination":"duteros","owner":2,"turns_remaining":1},{"id":36,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":4},{"id":34,"ship_count":2,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":2},{"id":35,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":3},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":6},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":3},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":5}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":6,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":9},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":3},{"id":38,"ship_count":8,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":5},{"id":36,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":3},{"id":34,"ship_count":2,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":1},{"id":35,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":2},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":5},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":2},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":4}]}
{"planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":8},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":2},{"id":38,"ship_count":8,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":4},{"id":36,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":2},{"id":39,"ship_count":5,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":5},{"id":35,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":1},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":4},{"id":26,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":1},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":3}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":0,"x":3.0,"y":5.0,"owner":null,"name":"tritos"},{"ship_count":1,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":7},{"id":28,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":1},{"id":38,"ship_count":8,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":3},{"id":36,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":1},{"id":39,"ship_count":5,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":4},{"id":40,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":5},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":3},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":2}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":0,"x":6.0,"y":0.0,"owner":null,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":6},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":10},{"id":38,"ship_count":8,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":2},{"id":30,"ship_count":2,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":1},{"id":39,"ship_count":5,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":3},{"id":40,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":4},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":2}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":1,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":5},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":9},{"id":38,"ship_count":8,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":1},{"id":42,"ship_count":3,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":5},{"id":39,"ship_count":5,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":2},{"id":40,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":3},{"id":32,"ship_count":1,"origin":"duteros","destination":"tetratos","owner":1,"turns_remaining":1}]}
{"planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":11,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":3,"x":6.0,"y":0.0,"owner":1,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":4},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":8},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":10},{"id":42,"ship_count":3,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":4},{"id":39,"ship_count":5,"origin":"tetratos","destination":"tritos","owner":2,"turns_remaining":1},{"id":40,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":2},{"id":43,"ship_count":1,"origin":"tetratos","destination":"tritos","owner":1,"turns_remaining":5}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":1,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":3},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":7},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":9},{"id":42,"ship_count":3,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":3},{"id":46,"ship_count":10,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":5},{"id":40,"ship_count":4,"origin":"duteros","destination":"tritos","owner":2,"turns_remaining":1},{"id":43,"ship_count":1,"origin":"tetratos","destination":"tritos","owner":1,"turns_remaining":4},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":10}]}
{"planets":[{"ship_count":6,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":1,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":2},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":6},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":8},{"id":42,"ship_count":3,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":2},{"id":46,"ship_count":10,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":4},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":5},{"id":43,"ship_count":1,"origin":"tetratos","destination":"tritos","owner":1,"turns_remaining":3},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":9},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":10}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":1,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":37,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":1},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":5},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":7},{"id":42,"ship_count":3,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":1},{"id":46,"ship_count":10,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":3},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":4},{"id":43,"ship_count":1,"origin":"tetratos","destination":"tritos","owner":1,"turns_remaining":2},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":8},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":9},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":10},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":11}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":1,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":52,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":5},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":4},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":6},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":11},{"id":46,"ship_count":10,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":2},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":3},{"id":43,"ship_count":1,"origin":"tetratos","destination":"tritos","owner":1,"turns_remaining":1},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":7},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":8},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":9},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":10}]}
{"planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":52,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":4},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":3},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":5},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":10},{"id":46,"ship_count":10,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":1},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":2},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":11},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":6},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":7},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":8},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":9}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":13,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":52,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":3},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":2},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":4},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":9},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":9},{"id":48,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":1},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":10},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":5},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":6},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":7},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":8}]}
{"planets":[{"ship_count":6,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":4,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":8,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":52,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":2},{"id":41,"ship_count":4,"origin":"protos","destination":"tritos","owner":2,"turns_remaining":1},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":3},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":8},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":8},{"id":55,"ship_count":12,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":5},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":9},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":4},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":5},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":6},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":7}]}
{"planets":[{"ship_count":7,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":5,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":8,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":52,"ship_count":6,"origin":"tritos","destination":"tetratos","owner":2,"turns_remaining":1},{"id":56,"ship_count":7,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":5},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":2},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":7},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":7},{"id":55,"ship_count":12,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":4},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":8},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":3},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":4},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":5},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":6}]}
{"planets":[{"ship_count":8,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":2,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":9,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":9},{"id":56,"ship_count":7,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":4},{"id":44,"ship_count":3,"origin":"duteros","destination":"tetratos","owner":2,"turns_remaining":1},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":6},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":6},{"id":55,"ship_count":12,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":3},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":7},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":2},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":3},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":4},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":5}]}
{"planets":[{"ship_count":9,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":7,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":3,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":5,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":8},{"id":56,"ship_count":7,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":3},{"id":58,"ship_count":8,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":5},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":5},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":5},{"id":55,"ship_count":12,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":2},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":6},{"id":45,"ship_count":2,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":1},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":2},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":3},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":4}]}
{"planets":[{"ship_count":2,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":6,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":4,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":6,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":null,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":7},{"id":56,"ship_count":7,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":2},{"id":58,"ship_count":8,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":4},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":4},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":4},{"id":55,"ship_count":12,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":1},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":5},{"id":59,"ship_count":8,"origin":"protos","destination":"pemptos","owner":2,"turns_remaining":10},{"id":47,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":1},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":2},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":3}]}
{"planets":[{"ship_count":3,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":5,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":7,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":6,"x":3.0,"y":-5.0,"owner":2,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":6},{"id":56,"ship_count":7,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":1},{"id":58,"ship_count":8,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":3},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":3},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":3},{"id":60,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":11},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":4},{"id":59,"ship_count":8,"origin":"protos","destination":"pemptos","owner":2,"turns_remaining":9},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":2},{"id":49,"ship_count":1,"origin":"tetratos","destination":"duteros","owner":1,"turns_remaining":1}]}
{"planets":[{"ship_count":4,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":1,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":6,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":14,"x":3.0,"y":-5.0,"owner":2,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":5},{"id":61,"ship_count":6,"origin":"tetratos","destination":"extos","owner":2,"turns_remaining":10},{"id":58,"ship_count":8,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":2},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":2},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":2},{"id":60,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":10},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":3},{"id":59,"ship_count":8,"origin":"protos","destination":"pemptos","owner":2,"turns_remaining":8},{"id":50,"ship_count":5,"origin":"protos","destination":"tetratos","owner":2,"turns_remaining":1}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":2,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":7,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":8,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":2,"x":3.0,"y":-5.0,"owner":2,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":4},{"id":61,"ship_count":6,"origin":"tetratos","destination":"extos","owner":2,"turns_remaining":9},{"id":58,"ship_count":8,"origin":"tetratos","destination":"pemptos","owner":2,"turns_remaining":1},{"id":51,"ship_count":1,"origin":"tetratos","destination":"protos","owner":1,"turns_remaining":1},{"id":54,"ship_count":5,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":1},{"id":60,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":9},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":2},{"id":59,"ship_count":8,"origin":"protos","destination":"pemptos","owner":2,"turns_remaining":7},{"id":62,"ship_count":13,"origin":"pemptos","destination":"extos","owner":2,"turns_remaining":5}]}
{"planets":[{"ship_count":5,"x":-6.0,"y":0.0,"owner":2,"name":"protos"},{"ship_count":3,"x":-3.0,"y":5.0,"owner":2,"name":"duteros"},{"ship_count":8,"x":3.0,"y":5.0,"owner":2,"name":"tritos"},{"ship_count":2,"x":6.0,"y":0.0,"owner":2,"name":"tetratos"},{"ship_count":16,"x":3.0,"y":-5.0,"owner":2,"name":"pemptos"},{"ship_count":6,"x":-3.0,"y":-5.0,"owner":null,"name":"extos"}],"expeditions":[{"id":57,"ship_count":7,"origin":"tritos","destination":"pemptos","owner":2,"turns_remaining":3},{"id":61,"ship_count":6,"origin":"tetratos","destination":"extos","owner":2,"turns_remaining":8},{"id":63,"ship_count":7,"origin":"tetratos","destination":"extos","owner":2,"turns_remaining":10},{"id":62,"ship_count":13,"origin":"pemptos","destination":"extos","owner":2,"turns_remaining":4},{"id":59,"ship_count":8,"origin":"protos","destination":"pemptos","owner":2,"turns_remaining":6},{"id":60,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":8},{"id":53,"ship_count":5,"origin":"duteros","destination":"pemptos","owner":2,"turns_remaining":1}]}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

View file

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 493.0475 493.16002"
xml:space="preserve"
sodipodi:docname="jupiter-with-satellite.svg"
width="493.04749"
height="493.16"
inkscape:version="0.92.1 r15371"><metadata
id="metadata45"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs43" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview41"
showgrid="false"
inkscape:zoom="0.38562218"
inkscape:cx="-121.54471"
inkscape:cy="246.58001"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g8" />
<g
id="g8"
transform="translate(-118.9515,-59.419)">
<path
d="M 539.776,131.64 C 493.205,85.067 431.282,59.419 365.417,59.419 c -65.865,0 -127.785,25.649 -174.359,72.221 -96.142,96.142 -96.142,252.575 0,348.718 46.573,46.573 108.494,72.221 174.359,72.221 65.865,0 127.786,-25.648 174.359,-72.221 46.574,-46.573 72.223,-108.494 72.223,-174.359 0,-65.865 -25.647,-127.786 -72.223,-174.359 z M 375.169,405.983 c -12.849,11.452 -28.27,18.565 -40.247,18.565 -3.901,0 -9.259,-0.794 -12.626,-4.57 -3.823,-4.287 -4.311,-11.821 -1.337,-20.669 3.484,-10.375 11.047,-21.12 21.292,-30.252 12.849,-11.452 28.27,-18.565 40.247,-18.565 3.901,0 9.259,0.794 12.626,4.568 9.699,10.882 -2.733,35.57 -19.955,50.923 z m -59.521,27.38 c 5.126,3.72 11.674,5.68 19.274,5.68 15.617,0 34.268,-8.313 49.89,-22.24 23.566,-21.006 33.496,-48.135 25.096,-65.431 0.069,-0.069 0.138,-0.134 0.205,-0.203 l 0.245,-0.245 c 56.354,-56.355 104.89,-119.767 140.932,-183.964 9.652,12.849 17.879,26.565 24.597,40.957 -35.262,61.327 -80.521,119.83 -134.614,173.92 -54.098,54.099 -112.607,99.362 -173.935,134.623 -14.394,-6.719 -28.111,-14.945 -40.961,-24.599 30.178,-16.937 60.136,-36.571 89.271,-58.498 z M 466.754,97.09 c -35.38,61.735 -80.828,120.58 -135.241,174.991 -54.389,54.389 -113.209,99.824 -174.915,135.197 -5.757,-11.897 -10.44,-24.186 -14.05,-36.725 56.493,-34.46 110.419,-77.182 160.338,-127.099 49.957,-49.957 92.703,-103.921 127.17,-160.452 12.628,3.642 24.897,8.353 36.698,14.088 z m -265.444,44.8 c 43.835,-43.835 102.116,-67.977 164.109,-67.977 7.242,0 14.43,0.342 21.555,0.995 -31.234,48.087 -68.655,94.211 -111.341,137.176 -2.821,2.839 -2.807,7.429 0.034,10.25 1.413,1.404 3.262,2.107 5.108,2.107 1.863,0 3.725,-0.714 5.142,-2.14 44.565,-44.857 84.642,-94.977 116.958,-145.384 4.187,0.676 8.346,1.459 12.472,2.359 -33.458,54.163 -74.692,105.911 -122.709,153.927 -47.981,47.981 -99.69,89.192 -153.82,122.642 -16.314,-74.713 4.517,-155.981 62.492,-213.955 z m -37.988,278.24 c 62.996,-36.051 123.004,-82.362 178.439,-137.797 55.457,-55.457 101.781,-115.487 137.837,-178.506 18.062,10.238 34.849,22.985 49.928,38.064 4.164,4.164 8.148,8.46 11.953,12.874 -35.656,64.768 -84.421,128.944 -141.318,185.854 -4.865,-3.019 -10.834,-4.622 -17.665,-4.622 -15.617,0 -34.269,8.313 -49.892,22.24 -12.097,10.783 -21.113,23.731 -25.389,36.457 -3.457,10.294 -3.575,19.665 -0.495,27.248 -30.198,22.709 -61.277,42.902 -92.54,60.113 -4.414,-3.803 -8.708,-7.786 -12.872,-11.95 -15.228,-15.229 -27.882,-32.071 -37.986,-49.975 z m 366.205,49.976 c -43.835,43.835 -102.116,67.977 -164.109,67.977 -15.161,0 -30.098,-1.453 -44.659,-4.276 18.864,-11.87 37.661,-24.833 55.998,-38.625 3.2,-2.406 3.841,-6.951 1.435,-10.149 -2.406,-3.2 -6.952,-3.84 -10.149,-1.435 -19.855,14.934 -46.393,32.45 -67.363,45.368 -5.606,-1.62 -11.142,-3.448 -16.596,-5.487 58.968,-35.049 115.237,-79.19 167.435,-131.388 52.192,-52.19 96.333,-108.454 131.381,-167.423 2.049,5.485 3.887,11.051 5.512,16.69 -23.941,38.799 -55.866,83.002 -87.51,118.944 -2.645,3.004 -2.356,7.585 0.649,10.228 1.379,1.212 3.086,1.808 4.787,1.808 2.009,0 4.012,-0.832 5.443,-2.459 30.673,-34.837 58.031,-71.308 81.446,-108.536 2.821,14.559 4.276,29.493 4.276,44.652 10e-4,61.995 -24.139,120.276 -67.976,164.111 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 337.815,406.147 c -4.829,-5.418 0.615,-18.151 12.159,-28.441 11.544,-10.29 24.817,-14.24 29.646,-8.822 4.829,5.417 -0.615,18.151 -12.159,28.441 -11.545,10.29 -24.817,14.24 -29.646,8.822 z"
id="path6"
inkscape:connector-curvature="0" />
</g>
<g
id="g10"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g12"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g14"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g16"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g18"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g20"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g22"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g24"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g26"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g28"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g30"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g32"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g34"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g36"
transform="translate(-118.9515,-59.419)">
</g>
<g
id="g38"
transform="translate(-118.9515,-59.419)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.17 272.17"
xml:space="preserve"
sodipodi:docname="mars-with-satellite.svg"
width="272.17001"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs41" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview39"
showgrid="false"
inkscape:zoom="0.74916113"
inkscape:cx="-15.912826"
inkscape:cy="157.50949"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g6" />
<g
id="g6"
transform="translate(-14.578,-42.849)">
<path
d="m 150.663,42.849 c -75.037,0 -136.085,61.047 -136.085,136.085 0,75.038 61.048,136.085 136.085,136.085 75.037,0 136.085,-61.048 136.085,-136.085 0,-75.037 -61.048,-136.085 -136.085,-136.085 z m 94.519,49.737 C 215.47,98.072 194.155,95.67 181.775,85.417 166.119,72.442 142.824,62.802 112.41,56.684 c 12.085,-3.79 24.935,-5.835 38.253,-5.835 37.388,0 71.082,16.104 94.519,41.737 z M 49.864,99.992 c 7.659,4.116 14.848,7.336 20.496,9.16 l 1.405,0.455 c 11.474,3.718 26.173,8.48 38.353,8.48 9.974,0 18.259,-3.194 21.701,-12.769 1.564,-4.354 1.492,-8.272 -0.214,-11.644 -3.639,-7.188 -13.464,-10.107 -25.902,-13.801 -2.913,-0.865 -5.924,-1.76 -8.986,-2.75 -4.31,-1.395 -10.33,-3.021 -17.181,-4.657 5.813,-3.896 11.958,-7.332 18.388,-10.249 35.034,5.547 62.249,15.687 78.747,29.361 9.52,7.883 23.149,11.833 40.721,11.833 9.978,0 21.246,-1.291 33.734,-3.842 3.017,3.811 5.819,7.799 8.394,11.942 -7.815,0.09 -15.483,0.207 -23.256,0.357 -32.772,0.63 -51.646,9.594 -69.899,18.262 -16.304,7.742 -31.704,15.056 -56.158,15.056 -19.363,0 -45.543,-6.853 -75.875,-19.812 4.196,-9.082 9.42,-17.595 15.532,-25.382 z M 71.002,78.711 c 9.393,2.083 17.789,4.256 23.251,6.023 3.154,1.021 6.213,1.929 9.171,2.808 9.751,2.896 18.96,5.631 21.043,9.745 0.436,0.861 0.892,2.351 -0.177,5.326 -4.637,12.897 -27.272,6.767 -50.06,-0.616 L 72.82,101.54 C 67.967,99.972 61.794,97.234 55.123,93.723 59.98,88.283 65.292,83.259 71.002,78.711 Z M 23.02,168.333 c 35.942,5.647 57.003,15.954 59.452,29.178 0.284,1.535 -0.071,2.922 -1.119,4.364 -2.927,4.03 -13.653,11.492 -52.407,16.946 -4.126,-12.559 -6.367,-25.966 -6.367,-39.887 -0.001,-3.57 0.153,-7.104 0.441,-10.601 z m 23.365,84.896 c 22.439,-3.993 52.181,-14.162 77.357,-39.338 42.857,-42.857 53.898,-42.857 78.089,-42.857 9.532,0 21.889,5.026 34.971,10.348 13.57,5.52 27.555,11.194 41.059,12.592 -0.781,6.647 -2.069,13.141 -3.832,19.44 -9.441,0.149 -18.893,-1.263 -28.848,-2.765 -23.035,-3.475 -49.144,-7.414 -80.863,8.749 -36.661,18.676 -56.554,50.852 -67.026,75.957 -20.42,-9.398 -37.963,-24.01 -50.907,-42.126 z m 68.931,48.827 c -3.62,-1.041 -7.173,-2.242 -10.656,-3.586 9.935,-23.833 28.755,-54.35 63.288,-71.943 29.436,-14.998 53.129,-11.422 76.039,-7.966 9.394,1.417 18.359,2.748 27.51,2.855 -2.915,8.266 -6.65,16.149 -11.117,23.543 -29.036,-6.441 -59.028,-1.667 -89.203,14.214 -24.231,12.752 -43.497,30.024 -55.861,42.883 z m 35.347,4.963 c -9.027,0 -17.837,-0.944 -26.341,-2.729 11.947,-11.958 29.304,-26.84 50.581,-38.037 27.413,-14.427 54.562,-19.154 80.787,-14.093 -23.175,33.139 -61.609,54.859 -105.027,54.859 z M 278.55,186.003 c -12.347,-1.311 -25.739,-6.745 -38.734,-12.031 -13.827,-5.625 -26.889,-10.938 -37.985,-10.938 -27.418,0 -40.278,1.733 -83.745,45.2 -25.043,25.043 -54.972,34.354 -76.548,37.691 -3.79,-6.151 -7.074,-12.644 -9.795,-19.422 31.269,-4.529 49.643,-11.06 56.083,-19.926 2.324,-3.201 3.193,-6.839 2.513,-10.521 -3.943,-21.297 -37.42,-31.136 -66.412,-35.676 1.399,-9.598 3.865,-18.853 7.275,-27.643 31.702,13.558 58.277,20.448 79.003,20.448 26.258,0 42.448,-7.689 59.59,-15.83 17.488,-8.305 35.571,-16.893 66.622,-17.49 9.222,-0.177 18.305,-0.308 27.659,-0.402 9.362,17.782 14.672,38.016 14.672,59.47 0,2.373 -0.07,4.729 -0.198,7.07 z"
id="path2"
inkscape:connector-curvature="0" />
</g>
<g
id="g8"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g10"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g12"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g14"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g16"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g18"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g20"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g22"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g24"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g26"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g28"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g30"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g32"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g34"
transform="translate(-14.578,-42.849)">
</g>
<g
id="g36"
transform="translate(-14.578,-42.849)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.044 272.17001"
xml:space="preserve"
sodipodi:docname="neptune-with-satellite.svg"
width="272.04401"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata79"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs77" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview75"
showgrid="false"
inkscape:zoom="0.75655574"
inkscape:cx="-13.59678"
inkscape:cy="155.969"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g42" />
<g
id="g42"
transform="translate(-12.275,-39.769)">
<path
d="m 148.297,39.769 c -36.35,0 -70.524,14.155 -96.227,39.858 -53.06,53.06 -53.06,139.394 0,192.454 25.703,25.703 59.877,39.858 96.227,39.858 36.35,0 70.524,-14.155 96.227,-39.858 53.06,-53.06 53.06,-139.394 0,-192.454 C 218.821,53.924 184.647,39.769 148.297,39.769 Z M 271.474,165.86 c -8.235,-5.915 -18.998,-2.783 -29.532,8.588 -8.691,9.382 -15.31,21.945 -19.67,37.341 -0.602,2.125 0.633,4.336 2.759,4.938 2.127,0.601 4.336,-0.634 4.938,-2.759 4.013,-14.169 10.016,-25.637 17.842,-34.084 3.54,-3.822 12.475,-12.208 18.997,-7.527 8.074,5.799 7.154,21.44 6.385,27.895 -1.709,14.318 -7.573,26.757 -15.687,33.274 -2.358,1.895 -5.645,3.751 -7.902,1.84 -2.635,-2.23 -3.822,-7.371 -3.344,-14.476 0.148,-2.204 -1.519,-4.111 -3.723,-4.26 -2.226,-0.138 -4.111,1.519 -4.26,3.723 -0.672,9.986 1.399,17.091 6.158,21.119 2.164,1.832 4.646,2.741 7.302,2.741 1.832,0 3.748,-0.447 5.699,-1.306 -5.142,8.369 -11.327,16.273 -18.569,23.516 -1.59,1.59 -3.216,3.13 -4.873,4.625 -3.667,-4.799 -6.198,-12.047 -7.225,-20.88 -0.256,-2.194 -2.241,-3.763 -4.437,-3.511 -2.194,0.255 -3.766,2.241 -3.511,4.436 1.23,10.565 4.34,19.14 9.059,25.132 -16.61,13.223 -36.039,21.995 -56.813,25.702 5.189,-6.479 10.531,-16.472 12.156,-31.099 0.244,-2.196 -1.338,-4.173 -3.534,-4.417 -2.186,-0.244 -4.173,1.338 -4.417,3.534 -2.288,20.594 -12.727,30.327 -17.241,33.631 -3.223,0.241 -6.469,0.364 -9.735,0.364 -34.213,0 -66.378,-13.323 -90.57,-37.516 -33.004,-33.004 -44.189,-79.685 -33.57,-121.967 11.195,1.303 26.82,4.299 43.035,11.16 0.509,0.215 1.037,0.317 1.557,0.317 1.559,0 3.04,-0.917 3.686,-2.442 0.861,-2.034 -0.09,-4.381 -2.125,-5.242 C 53.868,141.293 38.021,138.111 26.373,136.664 32.383,117.86 42.832,100.179 57.727,85.285 68.941,74.071 81.87,65.197 95.92,58.898 c -0.781,0.832 -1.538,1.704 -2.252,2.627 -5.132,6.638 -6.665,13.818 -4.432,20.764 0.676,2.103 2.932,3.261 5.032,2.584 2.104,-0.676 3.26,-2.929 2.584,-5.032 -3.119,-9.701 6.766,-18.895 16.179,-23.821 8.789,-4.599 19.379,-7.341 31.542,-8.193 1.239,-0.035 2.48,-0.058 3.724,-0.058 12.251,0 24.237,1.717 35.691,5.022 2.36,0.884 4.63,1.872 6.793,2.972 5.949,3.025 9.001,6.12 9.604,9.737 0.85,5.096 -4.18,9.225 -6.381,10.763 -11.526,8.055 -26.655,7.89 -37.317,6.332 -2.189,-0.324 -4.217,1.194 -4.536,3.38 -0.319,2.186 1.194,4.217 3.38,4.536 3.699,0.54 7.881,0.924 12.299,0.924 10.028,0 21.264,-1.981 30.757,-8.614 7.284,-5.089 10.815,-11.882 9.689,-18.635 -0.103,-0.615 -0.243,-1.208 -0.409,-1.783 8.589,4.523 16.694,10.047 24.165,16.52 -8.145,14.582 -23.589,20.575 -35.122,23.032 -2.16,0.46 -3.538,2.585 -3.078,4.746 0.4,1.88 2.061,3.167 3.908,3.167 0.276,0 0.557,-0.029 0.838,-0.089 12.722,-2.711 29.678,-9.305 39.469,-25.296 0.273,0.269 0.551,0.531 0.823,0.803 23.661,23.662 36.104,54.354 37.344,85.415 -1.287,-1.834 -2.844,-3.479 -4.74,-4.841 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 137.556,85.235 c 0.603,0.324 1.251,0.478 1.891,0.478 1.425,0 2.804,-0.764 3.526,-2.106 1.046,-1.946 0.317,-4.371 -1.628,-5.417 -1.062,-0.571 -6.264,-3.626 -4.383,-7.716 1.226,-2.667 4.829,-4.64 11.012,-6.032 6.876,-1.548 17.445,-1.943 24.605,2.034 1.188,0.66 1.884,1.448 1.862,2.11 -0.027,0.803 -0.928,2.024 -2.877,2.94 -2,0.94 -2.858,3.322 -1.919,5.322 0.94,1.999 3.322,2.859 5.321,1.918 4.54,-2.133 7.332,-5.838 7.47,-9.91 0.128,-3.778 -2.05,-7.195 -5.973,-9.374 -9.12,-5.066 -21.604,-4.792 -30.247,-2.845 -5.602,1.261 -13.409,3.721 -16.523,10.494 -3.061,6.654 0.099,13.93 7.863,18.104 z"
id="path4"
inkscape:connector-curvature="0" />
<path
d="m 100.492,96.756 c 2.997,2.273 6.354,4.294 10.263,6.181 0.561,0.271 1.152,0.398 1.735,0.398 1.487,0 2.916,-0.833 3.605,-2.263 0.96,-1.99 0.125,-4.381 -1.864,-5.341 -3.424,-1.652 -6.337,-3.402 -8.906,-5.35 -1.76,-1.335 -4.27,-0.991 -5.604,0.77 -1.334,1.762 -0.989,4.271 0.771,5.605 z"
id="path6"
inkscape:connector-curvature="0" />
<path
d="m 179.091,111.757 c 0.047,10e-4 4.807,-0.026 7.63,-0.253 2.202,-0.177 3.844,-2.106 3.667,-4.308 -0.177,-2.203 -2.137,-3.843 -4.308,-3.667 -4.037,0.325 -6.639,0.235 -6.68,0.233 -2.181,-0.089 -4.063,1.634 -4.149,3.84 -0.086,2.208 1.633,4.068 3.84,4.155 z"
id="path8"
inkscape:connector-curvature="0" />
<path
d="m 201.867,133.619 c 0.336,0 9.337,-2.448 13.524,-3.81 2.101,-0.683 3.25,-2.94 2.566,-5.041 -0.684,-2.101 -2.938,-3.25 -5.041,-2.567 -4.04,1.314 -8.099,2.507 -12.062,3.547 -2.138,0.561 -3.415,2.748 -2.854,4.884 0.472,1.798 2.092,2.987 3.867,2.987 z"
id="path10"
inkscape:connector-curvature="0" />
<path
d="m 187.617,128.737 c -46.298,8.716 -77.082,-4.029 -94.75,-16.257 -1.817,-1.257 -4.309,-0.804 -5.565,1.013 -1.257,1.816 -0.804,4.308 1.013,5.565 14.605,10.108 37.502,20.561 69.73,20.561 9.526,0 19.871,-0.914 31.054,-3.02 2.171,-0.409 3.6,-2.5 3.19,-4.671 -0.41,-2.172 -2.508,-3.602 -4.672,-3.191 z"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 77.141,110.083 c 0.771,0.723 1.753,1.081 2.733,1.081 1.068,0 2.133,-0.425 2.92,-1.266 1.51,-1.612 1.427,-4.144 -0.185,-5.654 -3.733,-3.497 -5.615,-5.951 -5.675,-6.029 -1.327,-1.763 -3.831,-2.119 -5.596,-0.795 -1.768,1.326 -2.125,3.833 -0.8,5.6 0.092,0.121 2.267,3.001 6.603,7.063 z"
id="path14"
inkscape:connector-curvature="0" />
<path
d="m 41.149,171.992 c -1.633,-0.278 -3.294,-0.535 -4.938,-0.763 -2.188,-0.302 -4.208,1.224 -4.512,3.411 -0.304,2.188 1.223,4.208 3.412,4.513 1.563,0.217 5.149,0.783 5.373,0.783 1.915,0 3.607,-1.379 3.938,-3.33 0.37,-2.178 -1.095,-4.244 -3.273,-4.614 z"
id="path16"
inkscape:connector-curvature="0" />
<path
d="m 53.789,182.977 c 13.524,3.751 45.748,15.723 52.875,45.778 0.436,1.839 2.077,3.078 3.889,3.078 0.306,0 0.616,-0.035 0.926,-0.109 2.149,-0.51 3.479,-2.666 2.969,-4.815 -3.121,-13.162 -10.671,-24.582 -22.441,-33.944 -9.71,-7.724 -22.186,-13.843 -36.079,-17.697 -2.125,-0.589 -4.333,0.656 -4.924,2.785 -0.59,2.129 0.656,4.333 2.785,4.924 z"
id="path18"
inkscape:connector-curvature="0" />
<path
d="m 110.315,242.16 c -2.004,-0.927 -4.382,-0.057 -5.311,1.948 -1.013,2.187 -2.39,4.152 -4.093,5.843 -1.568,1.557 -1.577,4.089 -0.02,5.657 0.782,0.788 1.81,1.182 2.838,1.182 1.019,0 2.039,-0.387 2.818,-1.162 2.378,-2.362 4.301,-5.106 5.715,-8.157 0.929,-2.005 0.057,-4.383 -1.947,-5.311 z"
id="path20"
inkscape:connector-curvature="0" />
<path
d="m 90.255,255.468 c -8.356,1.642 -17.778,-1.182 -24.588,-7.365 -12.756,-11.582 -12.75,-24.255 -8.729,-29.174 3.817,-4.669 8.713,-5.013 12.147,-4.479 6.578,1.022 13.085,6.143 15.473,12.175 0.813,2.054 3.139,3.062 5.191,2.247 2.054,-0.813 3.06,-3.137 2.247,-5.191 -3.473,-8.774 -12.187,-15.66 -21.683,-17.136 -7.773,-1.208 -14.724,1.392 -19.57,7.321 -10.192,12.469 -0.554,30.991 9.545,40.16 6.995,6.351 16.232,9.895 25.219,9.894 2.12,0 4.228,-0.197 6.288,-0.602 2.168,-0.426 3.58,-2.528 3.155,-4.696 -0.425,-2.167 -2.526,-3.58 -4.695,-3.154 z"
id="path22"
inkscape:connector-curvature="0" />
<path
d="m 82.824,236.937 c -2.256,1.781 -4.846,1.359 -6.622,0.692 -3.652,-1.372 -6.874,-4.924 -7.496,-8.263 -0.404,-2.171 -2.489,-3.603 -4.665,-3.2 -2.172,0.405 -3.604,2.493 -3.2,4.665 1.129,6.061 6.289,11.936 12.547,14.287 1.924,0.723 3.86,1.08 5.739,1.08 3.157,0 6.152,-1.008 8.651,-2.98 1.734,-1.368 2.031,-3.883 0.663,-5.618 -1.367,-1.735 -3.883,-2.032 -5.617,-0.663 z"
id="path24"
inkscape:connector-curvature="0" />
<path
d="m 109.058,172.892 c -1.629,-1.493 -4.159,-1.385 -5.652,0.243 -1.494,1.628 -1.385,4.158 0.243,5.652 10.774,9.886 29.278,29.985 32.162,53.524 1.465,11.963 -1.974,23.543 -9.683,32.606 -3.238,3.808 -6.859,6.886 -10.763,9.15 -1.911,1.108 -2.562,3.556 -1.453,5.467 0.742,1.279 2.084,1.994 3.464,1.994 0.681,0 1.372,-0.174 2.003,-0.541 4.693,-2.722 9.014,-6.385 12.843,-10.887 9.176,-10.787 13.271,-24.552 11.53,-38.762 -3.196,-26.086 -23.109,-47.815 -34.694,-58.446 z"
id="path26"
inkscape:connector-curvature="0" />
<path
d="m 94.011,170.834 c 0.716,0.531 1.551,0.788 2.379,0.788 1.223,0 2.431,-0.56 3.216,-1.618 1.316,-1.774 0.944,-4.28 -0.831,-5.595 -1.901,-1.41 -3.876,-2.792 -5.871,-4.108 -1.844,-1.217 -4.325,-0.708 -5.542,1.135 -1.217,1.844 -0.708,4.325 1.135,5.542 1.874,1.235 3.729,2.533 5.514,3.856 z"
id="path28"
inkscape:connector-curvature="0" />
<path
d="m 151.585,173.576 c -1.26,-1.815 -3.749,-2.266 -5.564,-1.009 -1.815,1.257 -2.268,3.749 -1.012,5.564 0.312,0.451 30.974,45.477 13.988,80.185 -0.971,1.984 -0.149,4.38 1.835,5.351 0.565,0.277 1.165,0.408 1.755,0.408 1.479,0 2.901,-0.824 3.596,-2.243 7.945,-16.236 7.9,-36.706 -0.13,-59.195 -5.964,-16.7 -14.125,-28.565 -14.468,-29.061 z"
id="path30"
inkscape:connector-curvature="0" />
<path
d="m 257.729,197.605 c 2.204,-1.072 3.393,3.135 3.063,8.028 -0.148,2.204 1.518,4.112 3.722,4.26 0.092,0.006 0.183,0.009 0.273,0.009 2.086,0 3.845,-1.618 3.987,-3.73 0.482,-7.146 -1.438,-12.739 -5.267,-15.344 -2.692,-1.832 -5.965,-1.991 -9.21,-0.45 -1.996,0.948 -2.845,3.334 -1.897,5.33 0.948,1.996 3.344,2.863 5.329,1.897 z"
id="path32"
inkscape:connector-curvature="0" />
<path
d="m 219.052,227.503 c -0.246,1.928 -0.436,3.879 -0.563,5.801 -0.147,2.204 1.521,4.11 3.725,4.257 0.091,0.006 0.181,0.009 0.271,0.009 2.088,0 3.846,-1.62 3.987,-3.734 0.117,-1.762 0.291,-3.552 0.517,-5.322 0.279,-2.191 -1.271,-4.194 -3.463,-4.473 -2.187,-0.282 -4.195,1.272 -4.474,3.462 z"
id="path34"
inkscape:connector-curvature="0" />
<path
d="m 215.557,170.546 c -1.205,1.852 -0.681,4.33 1.171,5.535 0.674,0.438 1.43,0.647 2.178,0.647 1.309,0 2.59,-0.641 3.356,-1.819 11.387,-17.501 23.308,-27.803 36.441,-31.495 2.127,-0.598 3.366,-2.806 2.769,-4.933 -0.598,-2.126 -2.809,-3.368 -4.933,-2.768 -15.084,4.24 -28.491,15.634 -40.982,34.833 z"
id="path36"
inkscape:connector-curvature="0" />
<path
d="m 206.98,213.368 c 0.409,-2.171 -1.019,-4.263 -3.189,-4.672 -2.163,-0.412 -4.263,1.018 -4.672,3.189 -6.977,36.974 4.454,68.118 4.943,69.425 0.603,1.606 2.126,2.596 3.745,2.596 0.466,0 0.939,-0.082 1.4,-0.254 2.068,-0.773 3.118,-3.077 2.348,-5.146 -0.112,-0.3 -11.122,-30.441 -4.575,-65.138 z"
id="path38"
inkscape:connector-curvature="0" />
</g>
<g
id="g44"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g46"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g48"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g50"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g52"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g54"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g56"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g58"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g60"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g62"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g64"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g66"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g68"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g70"
transform="translate(-12.275,-39.769)">
</g>
<g
id="g72"
transform="translate(-12.275,-39.769)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100mm"
height="100mm"
viewBox="0 0 100 99.999999"
version="1.1"
id="svg8"
sodipodi:docname="ship.svg"
inkscape:version="0.92.4 (f8dce91, 2019-08-02)">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.0993438"
inkscape:cx="676.08563"
inkscape:cy="474.10966"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
gridtolerance="10">
<inkscape:grid
type="xygrid"
id="grid894" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(229.05372,-117.27915)">
<ellipse
ry="79.47506"
rx="48.672089"
cy="39.779182"
cx="439.0813"
id="ellipse888"
style="opacity:1;fill:#00ffff;fill-opacity:1;stroke:none;stroke-width:6.61458302;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:24.99999809;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 800 -448.82031 C 800 -448.82031 640 -342.04689 640 -92.046875 C 640 -16.101728 661.67774 51.924976 695.88672 97.775391 C 640.96482 152.90966 593.39426 234.74166 610 267.95312 C 620.00003 287.95314 720.00001 297.95311 730 287.95312 C 751.8315 266.12161 757.39662 198.03742 758.92773 149.62305 C 772.03579 155.04778 785.80002 157.95312 800 157.95312 C 814.19998 157.95312 827.96422 155.04778 841.07227 149.62305 C 842.60338 198.03742 848.1685 266.12161 870 287.95312 C 879.99999 297.95311 979.99997 287.95314 990 267.95312 C 1006.6057 234.74166 959.03518 152.90966 904.11328 97.775391 C 938.32226 51.924976 959.99999 -16.101728 960 -92.046875 C 960.00002 -342.04689 800 -448.82031 800 -448.82031 z M 800 -352.04688 C 800 -352.04688 908.96486 -279.33252 908.96484 -109.07617 C 908.96484 -15.046189 860.17918 61.179688 800 61.179688 C 739.82082 61.179688 691.03515 -15.046189 691.03516 -109.07617 C 691.03516 -279.33252 800 -352.04687 800 -352.04688 z "
transform="matrix(0.26458333,0,0,0.26458333,-229.05372,117.27915)"
id="path4600" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.04324 272.17001"
xml:space="preserve"
sodipodi:docname="uranus-with-satellite.svg"
inkscape:version="0.92.1 r15371"
width="272.04324"
height="272.17001"><metadata
id="metadata61"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs59" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview57"
showgrid="false"
inkscape:zoom="0.69664401"
inkscape:cx="-68.159453"
inkscape:cy="136.0855"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="Capa_1" />
<g
id="g24"
transform="translate(-66.724,-33.299)">
<path
d="M 298.973,73.157 C 273.271,47.454 239.096,33.299 202.746,33.299 c -36.35,0 -70.523,14.155 -96.227,39.858 -53.06,53.06 -53.06,139.394 0,192.454 25.703,25.703 59.877,39.858 96.227,39.858 36.35,0 70.524,-14.155 96.227,-39.858 53.059,-53.061 53.059,-139.395 0,-192.454 z m -5.657,186.796 c -11.681,11.681 -25.225,20.819 -39.956,27.156 17.744,-11.698 34.215,-26.208 48.558,-42.92 1.438,-1.676 1.246,-4.202 -0.43,-5.64 -1.678,-1.44 -4.202,-1.247 -5.641,0.43 -20.23,23.57 -48.084,44.664 -75.601,57.302 -5.753,0.781 -11.595,1.188 -17.501,1.188 -4.154,0 -8.276,-0.2 -12.359,-0.589 17.939,-6.343 34.995,-14.887 50.872,-25.52 1.836,-1.229 2.327,-3.714 1.098,-5.549 -1.229,-1.835 -3.712,-2.328 -5.549,-1.098 -19.625,13.143 -41.113,22.987 -63.873,29.279 -5.029,-1.193 -9.966,-2.688 -14.791,-4.477 4.071,-0.974 8.123,-2.079 12.128,-3.313 2.111,-0.651 3.296,-2.89 2.645,-5.001 -0.649,-2.11 -2.89,-3.294 -5,-2.645 -7.405,2.282 -14.973,4.095 -22.518,5.427 -11.638,-5.838 -22.419,-13.502 -31.997,-22.834 4.553,-0.896 9.091,-1.914 13.555,-3.076 2.138,-0.556 3.421,-2.74 2.864,-4.878 -0.555,-2.138 -2.736,-3.42 -4.878,-2.864 -5.959,1.55 -12.05,2.85 -18.137,3.902 C 96.417,242.502 88.55,229.31 83.208,215.361 c 7.844,-2.009 15.644,-4.451 23.246,-7.289 2.069,-0.772 3.121,-3.077 2.348,-5.146 -0.772,-2.069 -3.079,-3.122 -5.146,-2.348 -7.545,2.817 -15.292,5.233 -23.078,7.202 -1.7,-5.44 -3.033,-10.971 -3.992,-16.555 17.341,-5.604 33.99,-13.242 49.518,-22.786 1.882,-1.157 2.47,-3.62 1.313,-5.502 -1.158,-1.881 -3.62,-2.47 -5.503,-1.313 -14.584,8.964 -30.193,16.189 -46.445,21.555 -0.793,-7.386 -0.95,-14.826 -0.465,-22.234 8.314,-3.591 16.365,-7.688 23.955,-12.209 1.897,-1.13 2.521,-3.585 1.39,-5.483 -1.13,-1.898 -3.585,-2.521 -5.483,-1.39 -6.041,3.597 -12.387,6.918 -18.932,9.917 1.118,-8.127 3.015,-16.165 5.69,-23.995 12.924,-7.601 26.339,-17.69 37.186,-27.603 1.631,-1.49 1.745,-4.02 0.255,-5.651 -1.491,-1.632 -4.021,-1.745 -5.651,-0.254 -8.4,7.676 -17.365,14.679 -26.729,20.916 6.137,-13.178 14.632,-25.519 25.492,-36.379 24.192,-24.192 56.357,-37.516 90.57,-37.516 4.656,0 9.271,0.255 13.836,0.743 -1.347,4.072 -2.817,8.13 -4.393,12.113 -0.813,2.054 0.193,4.378 2.248,5.191 0.482,0.191 0.98,0.282 1.471,0.282 1.593,0 3.099,-0.958 3.721,-2.529 1.813,-4.582 3.485,-9.26 5.002,-13.947 5.613,0.961 11.128,2.297 16.52,3.984 -6.004,23.81 -15.831,46.266 -29.255,66.792 -1.209,1.849 -0.69,4.328 1.158,5.537 0.676,0.442 1.435,0.653 2.186,0.653 1.305,0 2.584,-0.638 3.352,-1.811 13.785,-21.077 23.913,-44.115 30.148,-68.536 14.147,5.434 27.287,13.409 38.866,23.679 -2.015,11.874 -5.07,23.73 -9.118,35.272 -0.731,2.084 0.365,4.367 2.45,5.099 0.438,0.154 0.885,0.227 1.324,0.227 1.651,0 3.197,-1.03 3.774,-2.677 3.599,-10.259 6.438,-20.76 8.495,-31.309 16.699,17.153 27.627,37.862 32.781,59.675 -6.798,23.85 -17.03,45.879 -30.438,65.486 -1.247,1.823 -0.779,4.313 1.044,5.56 0.69,0.472 1.477,0.699 2.254,0.699 1.276,0 2.531,-0.61 3.306,-1.743 11.018,-16.112 19.958,-33.794 26.699,-52.727 3.538,36.789 -8.748,74.828 -36.862,102.942 z"
id="path2"
inkscape:connector-curvature="0" />
<path
d="m 197.27,216.666 c -1.811,1.267 -2.251,3.761 -0.984,5.571 0.778,1.112 2.02,1.707 3.281,1.707 0.791,0 1.592,-0.235 2.289,-0.723 22.879,-16.008 42.555,-36.287 58.479,-60.273 4.438,-6.686 8.573,-13.669 12.288,-20.754 1.025,-1.957 0.271,-4.375 -1.686,-5.4 -1.952,-1.025 -4.374,-0.272 -5.4,1.685 -3.587,6.843 -7.58,13.587 -11.866,20.044 -15.37,23.149 -34.347,42.711 -56.401,58.143 z"
id="path6"
inkscape:connector-curvature="0" />
<path
d="m 164.66,235.919 c -4.826,2.292 -9.791,4.417 -14.757,6.314 -2.063,0.789 -3.098,3.101 -2.309,5.164 0.609,1.594 2.127,2.573 3.737,2.573 0.475,0 0.957,-0.085 1.427,-0.265 5.16,-1.972 10.319,-4.179 15.333,-6.561 1.996,-0.948 2.845,-3.334 1.897,-5.329 -0.946,-1.994 -3.333,-2.842 -5.328,-1.896 z"
id="path8"
inkscape:connector-curvature="0" />
<path
d="m 240.418,146.561 c 1.275,-1.804 0.846,-4.3 -0.958,-5.575 -1.803,-1.275 -4.3,-0.845 -5.575,0.958 -30.046,42.51 -72.305,73.713 -118.993,87.863 -2.114,0.641 -3.309,2.874 -2.668,4.988 0.523,1.728 2.11,2.841 3.826,2.841 0.385,0 0.775,-0.056 1.162,-0.173 48.383,-14.663 92.138,-46.946 123.206,-90.902 z"
id="path10"
inkscape:connector-curvature="0" />
<path
d="m 131.021,125.104 c 22.662,-18.894 41.814,-42.449 55.387,-68.119 1.032,-1.953 0.286,-4.373 -1.667,-5.406 -1.954,-1.035 -4.373,-0.286 -5.405,1.667 -13.09,24.758 -31.568,47.481 -53.438,65.714 -1.696,1.415 -1.926,3.937 -0.511,5.634 0.791,0.949 1.929,1.438 3.074,1.438 0.903,0 1.811,-0.304 2.56,-0.928 z"
id="path12"
inkscape:connector-curvature="0" />
<path
d="m 304.583,162.73 c 0.537,0.244 1.1,0.359 1.653,0.359 1.52,0 2.974,-0.872 3.644,-2.346 0.838,-1.843 1.658,-3.714 2.44,-5.563 0.861,-2.034 -0.091,-4.381 -2.125,-5.242 -2.035,-0.861 -4.382,0.09 -5.242,2.125 -0.755,1.784 -1.548,3.59 -2.356,5.37 -0.914,2.012 -0.025,4.383 1.986,5.297 z"
id="path14"
inkscape:connector-curvature="0" />
<path
d="m 301.081,169.845 c -1.931,-1.072 -4.365,-0.374 -5.438,1.557 -5.468,9.855 -11.719,19.443 -18.58,28.495 -25.229,33.293 -57.633,58.594 -93.705,73.166 -2.049,0.828 -3.038,3.159 -2.211,5.207 0.629,1.558 2.128,2.503 3.71,2.503 0.499,0 1.007,-0.094 1.497,-0.292 37.412,-15.114 70.983,-41.308 97.085,-75.752 7.089,-9.353 13.548,-19.26 19.2,-29.446 1.071,-1.932 0.374,-4.366 -1.558,-5.438 z"
id="path16"
inkscape:connector-curvature="0" />
<path
d="m 190.943,141.11 c -4.038,4.545 -8.354,8.994 -12.827,13.222 -1.605,1.518 -1.678,4.049 -0.16,5.655 0.787,0.833 1.846,1.252 2.908,1.252 0.985,0 1.974,-0.362 2.746,-1.093 4.643,-4.387 9.122,-9.004 13.313,-13.723 1.468,-1.652 1.318,-4.18 -0.334,-5.647 -1.651,-1.466 -4.179,-1.318 -5.646,0.334 z"
id="path18"
inkscape:connector-curvature="0" />
<path
d="m 161.323,130.713 c -1.609,1.514 -1.688,4.045 -0.174,5.654 0.787,0.837 1.85,1.26 2.915,1.26 0.982,0 1.967,-0.36 2.739,-1.086 18.801,-17.681 32.125,-35.242 40.733,-53.688 0.934,-2.001 0.068,-4.382 -1.934,-5.316 -2.001,-0.934 -4.382,-0.069 -5.316,1.933 -8.17,17.509 -20.915,34.271 -38.963,51.243 z"
id="path20"
inkscape:connector-curvature="0" />
<path
d="m 148.218,142.343 c -3.322,2.801 -6.804,5.649 -10.644,8.706 -1.729,1.376 -2.014,3.893 -0.638,5.621 0.789,0.992 1.955,1.508 3.132,1.508 0.873,0 1.752,-0.285 2.488,-0.871 3.899,-3.104 7.438,-5.999 10.817,-8.849 1.689,-1.424 1.904,-3.948 0.479,-5.637 -1.422,-1.687 -3.947,-1.902 -5.634,-0.478 z"
id="path22"
inkscape:connector-curvature="0" />
</g>
<g
id="g26"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g28"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g30"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g32"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g34"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g36"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g38"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g40"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g42"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g44"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g46"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g48"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g50"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g52"
transform="translate(-66.724,-33.299)">
</g>
<g
id="g54"
transform="translate(-66.724,-33.299)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.8 KiB

View file

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Capa_1"
x="0px"
y="0px"
viewBox="0 0 272.17001 272.17001"
xml:space="preserve"
sodipodi:docname="venus-with-satellite.svg"
width="272.17001"
height="272.17001"
inkscape:version="0.92.1 r15371"><metadata
id="metadata43"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs41" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1536"
inkscape:window-height="801"
id="namedview39"
showgrid="false"
inkscape:zoom="0.72525674"
inkscape:cx="-54.610822"
inkscape:cy="136.085"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="g6" />
<g
id="g6"
transform="translate(-53.232,-26.616)">
<path
d="m 189.317,26.616 c -75.038,0 -136.085,61.048 -136.085,136.085 0,75.037 61.047,136.085 136.085,136.085 75.038,0 136.085,-61.047 136.085,-136.085 0,-75.038 -61.048,-136.085 -136.085,-136.085 z m 114.537,78.799 c -19.285,81.007 -76.736,147.79 -154.087,179.114 -5.259,-1.711 -10.371,-3.751 -15.309,-6.102 80.857,-31.451 141.937,-101.332 162.187,-185.549 2.629,4.029 5.038,8.214 7.209,12.537 z M 163.18,139.149 c 26.371,-28.772 46.301,-63.476 57.841,-100.56 13.174,3.367 25.536,8.784 36.729,15.887 -19.382,87.483 -83.595,159.155 -168.504,188.074 -8.839,-11.054 -15.885,-23.598 -20.7,-37.19 35.734,-14.765 68.396,-37.583 94.634,-66.211 z M 66.097,197.717 C 64.659,192.664 63.525,187.485 62.714,182.201 125,152.771 174.179,99.363 198.318,34.937 c 5.041,0.352 10.001,0.997 14.865,1.918 -11.221,35.723 -30.474,69.147 -55.901,96.888 -25.304,27.609 -56.763,49.647 -91.185,63.974 z M 189.317,34.616 c 0.192,0 0.382,0.006 0.573,0.007 -23.415,60.543 -69.7,110.809 -128.17,139.196 -0.317,-3.665 -0.488,-7.372 -0.488,-11.118 0,-70.626 57.458,-128.085 128.085,-128.085 z M 94.827,249.08 c 85.048,-30.115 149.458,-102 170.022,-189.755 9.626,7.052 18.236,15.411 25.562,24.818 -18.383,87.024 -81.532,159.278 -165.428,189.276 -11.251,-6.562 -21.416,-14.787 -30.156,-24.339 z m 67.417,38.818 c 71.824,-32.367 125.65,-94.933 146.817,-170.653 4.421,11.608 7.2,24.017 8.052,36.946 -20.52,57.053 -60.724,105.217 -113.336,135.774 -4.748,0.536 -9.571,0.821 -14.46,0.821 -9.287,0 -18.342,-1.002 -27.073,-2.888 z m 63.449,-2.382 c 39.622,-27.44 71.097,-65.121 90.95,-108.895 -5.626,51.82 -42.283,94.456 -90.95,108.895 z"
id="path2"
inkscape:connector-curvature="0" />
</g>
<g
id="g8"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g10"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g12"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g14"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g16"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g18"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g20"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g22"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g24"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g26"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g28"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g30"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g32"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g34"
transform="translate(-53.232,-26.616)">
</g>
<g
id="g36"
transform="translate(-53.232,-26.616)">
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,14 @@
#ifdef GL_ES
precision mediump float;
#endif
// Passed in from the vertex shader.
varying vec2 v_texCoord;
// The texture.
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texCoord);
// gl_FragColor = vec4(0.7, 0.7, 0.0, 1.0);
}

View file

@ -0,0 +1,15 @@
#ifdef GL_ES
precision mediump float;
#endif
uniform float u_step_interval;
uniform float u_time;
uniform vec3 u_color;
uniform vec3 u_color_next;
void main() {
vec3 color = mix(u_color, u_color_next, u_time);
gl_FragColor = vec4(color, 1.0);
}

View file

@ -0,0 +1,18 @@
#ifdef GL_ES
precision mediump float;
#endif
#define PI 3.141592
uniform float u_step_interval;
uniform float u_time;
uniform bool u_vor;
varying float v_intensity;
varying float v_dist;
varying vec3 v_color;
varying vec2 v_pos;
void main() {
gl_FragColor = vec4(v_color, (1.0 - pow(1.0 - v_intensity, 1.23)) * 0.7);
}

View file

@ -0,0 +1,33 @@
#ifdef GL_ES
precision mediump float;
#endif
attribute vec2 a_position;
attribute vec2 a_texCoord;
uniform float u_time;
uniform vec4 u_viewbox; // [x, y, width, height]
uniform vec2 u_resolution;
uniform mat3 u_trans;
varying vec2 v_pos;
varying vec2 v_texCoord;
void main() {
vec3 pos = vec3(a_position, 1.0);
pos = u_trans * pos;
vec2 uv = pos.xy;
// Viewbox's center is top left, a_position's is in the center to the screen
// So translate and scale the viewbox**
uv -= u_viewbox.xy + (u_viewbox.zw * 0.5);
uv /= u_viewbox.zw * 0.5;
v_pos = (uv.xy + 1.0) * 0.5;
gl_Position = vec4(uv.xy, 0.0, 1.0);
v_texCoord = a_texCoord;
}

View file

@ -0,0 +1,36 @@
#ifdef GL_ES
precision mediump float;
#endif
attribute vec2 a_position;
attribute vec2 a_texCoord;
uniform float u_time;
uniform vec4 u_viewbox; // [x, y, width, height]
uniform vec2 u_resolution;
uniform mat3 u_trans;
uniform mat3 u_trans_next;
varying vec2 v_pos;
varying vec2 v_texCoord;
void main() {
vec3 pos = vec3(a_position, 1.0);
mat3 trans = (u_trans_next * (1.0 - u_time)) + (u_trans * u_time);
pos = trans * pos;
vec2 uv = pos.xy;
// Viewbox's center is top left, a_position's is in the center to the screen
// So translate and scale the viewbox**
uv -= u_viewbox.xy + (u_viewbox.zw * 0.5);
uv /= u_viewbox.zw * 0.5;
v_pos = (uv.xy + 1.0) * 0.5;
gl_Position = vec4(uv.xy, 0.0, 1.0);
v_texCoord = a_texCoord;
}

View file

@ -0,0 +1,43 @@
#ifdef GL_ES
precision mediump float;
#endif
attribute vec2 a_pos;
attribute vec2 a_center;
attribute float a_own;
attribute float a_intensity;
uniform vec3 u_planet_colours[$PLANETS * 2];
uniform vec4 u_viewbox; // [x, y, width, height]
uniform vec2 u_resolution;
uniform float u_time;
varying float v_intensity;
varying float v_dist;
varying vec2 v_pos;
varying vec3 v_color;
void main() {
v_intensity = a_intensity;
v_dist = distance(a_pos * u_resolution , a_center * u_resolution);
int own = int(a_own);
vec2 uv = a_pos;
// Viewbox's center is top left, a_position's is in the center to the screen
// So translate and scale the viewbox**
uv -= u_viewbox.xy + (u_viewbox.zw * 0.5);
uv /= u_viewbox.zw * 0.5;
v_pos = uv.xy;
// v_pos = (uv.xy + 1.0) * 0.5;
if (own < 0) {
v_color = vec3(0., 0., 0.);
} else {
v_color = mix(u_planet_colours[own * 2], u_planet_colours[own * 2 + 1], u_time);
}
gl_Position = vec4(uv.xy, 0.0, 1.0);
}

View file

@ -0,0 +1,47 @@
<script lang="ts">
import Visualizer from './lib/Visualizer.svelte';
</script>
<main>
<!-- <img src={logo} alt="Svelte Logo" /> -->
<!-- <h1>Hello Typescript!</h1> -->
<Visualizer />
</main>
<style>
:root {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
img {
height: 16rem;
width: 16rem;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4rem;
font-weight: 100;
line-height: 1.1;
margin: 2rem auto;
max-width: 14rem;
}
p {
max-width: 14rem;
margin: 1rem auto;
line-height: 1.35;
}
@media (min-width: 480px) {
h1 {
max-width: none;
}
p {
max-width: none;
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -0,0 +1,49 @@
<script lang="ts">
import { onMount } from 'svelte';
import * as visualizer from '../lib/visualizer/index';
onMount(() => {
visualizer.init();
fetch("match.log")
.then(response => response.text())
.then(data => visualizer.set_instance(data));
});
</script>
<div id="main" class="loading">
<canvas id="canvas" />
<div id="name" />
<div id="addbutton" class="button" />
<div id="meta">
<div id="turnCounter">0 / 0</div>
<div>
<span>Ms per frame:&nbsp;</span>
<input type="number" id="speed" value="300" />
</div>
<div class="slidecontainer">
<input
type="range"
min="0"
max="1"
value="1"
class="slider"
id="turnSlider"
/>
</div>
</div>
<div class="lds-roller">
<div />
<div />
<div />
<div />
<div />
<div />
<div />
<div />
</div>
</div>
<style scoped>
@import 'visualizer/style.css';
</style>

View file

@ -0,0 +1,25 @@
Copyright (c) 2018 Arthur Vercruysse
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View file

@ -0,0 +1 @@
Original by the amazing Arthur Vercruysse!

View file

@ -0,0 +1,102 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello wasm-pack!</title>
<link rel="stylesheet" type="text/css" href="static/res/style.css">
</head>
<body>
<input type="file" id="fileselect" style="display: none">
<div id=wrapper>
<div id="main" class="loading">
<canvas id="c"></canvas>
<div id="name"></div>
<div id="addbutton" class="button"></div>
<div id="meta">
<div id="turnCounter">
0 / 0
</div>
<div>
<span>Ms per frame:&nbsp;</span>
<input type="number" id="speed" value="100">
</div>
<div class="slidecontainer">
<input type="range" min="0" max="1" value="1" class="slider" id="turnSlider">
</div>
</div>
</div>
<div class=".options" id=options>
<div class="option">
Option one
</div>
<div class="option">
Option two
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div><div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div>
<div class="option">
Option three
</div><div class="option">
Option three
</div>
<div class="option">
Option three
</div>
</div>
</div>
<noscript>This page contains webassembly and javascript content, please enable javascript in your browser.</noscript>
<script src="bootstrap.js"></script>
<script>
const URL = window.location.origin + window.location.pathname;
const LOCATION = URL.substring(0, URL.lastIndexOf("/") + 1);
const game_location = LOCATION + "static/games/Chandra Garrett.json";
const name = "Chandra Garrett";
window.setTimeout(
() => visualizer.handle(game_location, name), 1000
)
</script>
</body>
</html>

View file

@ -0,0 +1,666 @@
import { Game } from "planetwars-rs";
// import { memory } from "planetwars-rs/planetwars_rs_bg";
// const memory = planetwars_bg.memory;
import type { Dictionary } from './webgl/util';
import type { BBox } from "./voronoi/voronoi-core";
import {
Resizer,
resizeCanvasToDisplaySize,
FPSCounter,
url_to_mesh,
Mesh,
} from "./webgl/util";
import {
Shader,
Uniform4f,
Uniform3fv,
Uniform1f,
Uniform2f,
ShaderFactory,
Uniform3f,
UniformMatrix3fv,
UniformBool,
} from "./webgl/shader";
import { Renderer } from "./webgl/renderer";
import { VertexBuffer, IndexBuffer } from "./webgl/buffer";
import { VertexBufferLayout, VertexArray } from "./webgl/vertexBufferLayout";
import { defaultLabelFactory, LabelFactory, Align, Label } from "./webgl/text";
import { VoronoiBuilder } from "./voronoi/voronoi";
// svg-mesh requires global to exist
(window as any).global = window;
function to_bbox(box: number[]): BBox {
return {
xl: box[0],
xr: box[0] + box[2],
yt: box[1],
yb: box[1] + box[3],
};
}
// function f32v(ptr: number, size: number): Float32Array {
// return new Float32Array(memory.buffer, ptr, size);
// }
// function i32v(ptr: number, size: number): Int32Array {
// return new Int32Array(memory.buffer, ptr, size);
// }
export function set_game_name(name: string) {
ELEMENTS["name"].innerHTML = name;
}
export function set_loading(loading: boolean) {
if (loading) {
if (!ELEMENTS["main"].classList.contains("loading")) {
ELEMENTS["main"].classList.add("loading");
}
} else {
ELEMENTS["main"].classList.remove("loading");
}
}
const ELEMENTS: any = {};
var CANVAS: any;
var RESOLUTION: any;
var GL: any;
var ms_per_frame: any;
const LAYERS = {
vor: -1, // Background
planet: 1,
planet_label: 2,
ship: 3,
ship_label: 4,
};
const COUNTER = new FPSCounter();
export function init() {
[
"name",
"turnCounter",
"main",
"turnSlider",
"fileselect",
"speed",
"canvas",
].forEach((n) => (ELEMENTS[n] = document.getElementById(n)));
CANVAS = ELEMENTS["canvas"];
RESOLUTION = [CANVAS.width, CANVAS.height];
ms_per_frame = parseInt(ELEMENTS["speed"].value);
GL = CANVAS.getContext("webgl");
GL.clearColor(0, 0, 0, 1);
GL.clear(GL.COLOR_BUFFER_BIT);
GL.enable(GL.BLEND);
GL.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
window.addEventListener(
"resize",
function () {
resizeCanvasToDisplaySize(CANVAS);
if (game_instance) {
game_instance.on_resize();
}
},
{ capture: false, passive: true }
);
ELEMENTS["turnSlider"].oninput = function () {
if (game_instance) {
game_instance.updateTurn(parseInt(ELEMENTS["turnSlider"].value));
}
};
ELEMENTS["speed"].onchange = function () {
ms_per_frame = parseInt(ELEMENTS["speed"].value);
};
}
export class GameInstance {
resizer: Resizer;
game: Game;
shader: Shader;
vor_shader: Shader;
image_shader: Shader;
text_factory: LabelFactory;
planet_labels: Label[];
ship_labels: Label[];
ship_ibo: IndexBuffer;
ship_vao: VertexArray;
// TODO: find a better way
max_num_ships: number;
renderer: Renderer;
planet_count: number;
vor_builder: VoronoiBuilder;
vor_counter = 3;
use_vor = true;
playing = true;
time_stopped_delta = 0;
last_time = 0;
frame = -1;
turn_count = 0;
constructor(
game: Game,
meshes: Mesh[],
ship_mesh: Mesh,
shaders: Dictionary<ShaderFactory>
) {
this.game = game;
const planets = game.get_planets();
this.planet_count = planets.length;
this.shader = shaders["normal"].create_shader(GL, {
MAX_CIRCLES: "" + planets.length,
});
this.image_shader = shaders["image"].create_shader(GL);
this.vor_shader = shaders["vor"].create_shader(GL, {
PLANETS: "" + planets.length,
});
this.text_factory = defaultLabelFactory(GL, this.image_shader);
this.planet_labels = [];
this.ship_labels = [];
this.resizer = new Resizer(CANVAS, [...game.get_viewbox()], true);
this.renderer = new Renderer();
this.game.update_turn(0);
// Setup key handling
document.addEventListener("keydown", this.handleKey.bind(this));
// List of [(x, y, r)] for all planets
this._create_voronoi(planets);
this._create_planets(planets, meshes);
// create_shipes
this.ship_ibo = new IndexBuffer(GL, ship_mesh.cells);
const ship_positions = new VertexBuffer(GL, ship_mesh.positions);
const ship_layout = new VertexBufferLayout();
ship_layout.push(GL.FLOAT, 3, 4, "a_position");
this.ship_vao = new VertexArray();
this.ship_vao.addBuffer(ship_positions, ship_layout);
this.max_num_ships = 0;
// Set slider correctly
this.turn_count = game.turn_count();
ELEMENTS["turnSlider"].max = this.turn_count - 1 + "";
}
push_state(state: string) {
this.game.push_state(state);
if (this.frame == this.turn_count - 1) {
this.playing = true;
}
// Set slider correctly
this.turn_count = this.game.turn_count();
this.updateTurnCounters();
}
_create_voronoi(planets: Float32Array) {
const planet_points = [];
for (let i = 0; i < planets.length; i += 3) {
planet_points.push({ x: -planets[i], y: -planets[i + 1] });
}
const bbox = to_bbox(this.resizer.get_viewbox());
this.vor_builder = new VoronoiBuilder(
GL,
this.vor_shader,
planet_points,
bbox
);
this.renderer.addRenderable(this.vor_builder.getRenderable(), LAYERS.vor);
}
_create_planets(planets: Float32Array, meshes: Mesh[]) {
for (let i = 0; i < this.planet_count; i++) {
{
const transform = new UniformMatrix3fv([
1,
0,
0,
0,
1,
0,
-planets[i * 3],
-planets[i * 3 + 1],
1,
]);
const indexBuffer = new IndexBuffer(
GL,
meshes[i % meshes.length].cells
);
const positionBuffer = new VertexBuffer(
GL,
meshes[i % meshes.length].positions
);
const layout = new VertexBufferLayout();
layout.push(GL.FLOAT, 3, 4, "a_position");
const vao = new VertexArray();
vao.addBuffer(positionBuffer, layout);
this.renderer.addToDraw(
indexBuffer,
vao,
this.shader,
{
u_trans: transform,
u_trans_next: transform,
},
[],
LAYERS.planet
);
}
{
const transform = new UniformMatrix3fv([
1,
0,
0,
0,
1,
0,
-planets[i * 3],
-planets[i * 3 + 1] - 1.2,
1,
]);
const label = this.text_factory.build(GL, transform);
this.planet_labels.push(label);
this.renderer.addRenderable(label.getRenderable(), LAYERS.planet_label);
}
}
}
on_resize() {
this.resizer = new Resizer(CANVAS, [...this.game.get_viewbox()], true);
const bbox = to_bbox(this.resizer.get_viewbox());
this.vor_builder.resize(GL, bbox);
}
_update_state() {
this._update_planets();
this._update_ships();
}
_update_planets() {
const colours = this.game.get_planet_colors();
const planet_ships = this.game.get_planet_ships();
this.vor_shader.uniform(GL, "u_planet_colours", new Uniform3fv(colours));
for (let i = 0; i < this.planet_count; i++) {
const u = new Uniform3f(
colours[i * 6],
colours[i * 6 + 1],
colours[i * 6 + 2]
);
this.renderer.updateUniform(
i,
(us) => (us["u_color"] = u),
LAYERS.planet
);
const u2 = new Uniform3f(
colours[i * 6 + 3],
colours[i * 6 + 4],
colours[i * 6 + 5]
);
this.renderer.updateUniform(
i,
(us) => (us["u_color_next"] = u2),
LAYERS.planet
);
this.planet_labels[i].setText(
GL,
"*" + planet_ships[i],
Align.Middle,
Align.Begin
);
}
}
_update_ships() {
const ships = this.game.get_ship_locations();
const labels = this.game.get_ship_label_locations();
const ship_counts = this.game.get_ship_counts();
const ship_colours = this.game.get_ship_colours();
for (let i = this.max_num_ships; i < ship_counts.length; i++) {
this.renderer.addToDraw(
this.ship_ibo,
this.ship_vao,
this.shader,
{},
[],
LAYERS.ship
);
const label = this.text_factory.build(GL);
this.ship_labels.push(label);
this.renderer.addRenderable(label.getRenderable(), LAYERS.ship_label);
}
if (ship_counts.length > this.max_num_ships)
this.max_num_ships = ship_counts.length;
// TODO: actually remove obsolete ships
for (let i = 0; i < this.max_num_ships; i++) {
if (i < ship_counts.length) {
this.ship_labels[i].setText(
GL,
"" + ship_counts[i],
Align.Middle,
Align.Middle
);
this.renderer.enableRenderable(i, LAYERS.ship);
this.renderer.enableRenderable(i, LAYERS.ship_label);
const u = new Uniform3f(
ship_colours[i * 3],
ship_colours[i * 3 + 1],
ship_colours[i * 3 + 2]
);
const t1 = new UniformMatrix3fv(ships.slice(i * 18, i * 18 + 9));
const t2 = new UniformMatrix3fv(ships.slice(i * 18 + 9, i * 18 + 18));
const tl1 = new UniformMatrix3fv(labels.slice(i * 18, i * 18 + 9));
const tl2 = new UniformMatrix3fv(labels.slice(i * 18 + 9, i * 18 + 18));
this.renderer.updateUniform(
i,
(us) => {
us["u_color"] = u;
us["u_color_next"] = u;
us["u_trans"] = t1;
us["u_trans_next"] = t2;
},
LAYERS.ship
);
this.renderer.updateUniform(
i,
(us) => {
us["u_trans"] = tl1;
us["u_trans_next"] = tl2;
},
LAYERS.ship_label
);
} else {
this.renderer.disableRenderable(i, LAYERS.ship);
this.renderer.disableRenderable(i, LAYERS.ship_label);
}
}
}
render(time: number) {
COUNTER.frame(time);
if (COUNTER.delta(time) < 30) {
this.vor_counter = Math.min(3, this.vor_counter + 1);
} else {
this.vor_counter = Math.max(-3, this.vor_counter - 1);
}
if (this.vor_counter < -2) {
this.use_vor = false;
}
// If not playing, still reder with different viewbox, so people can still pan etc.
if (!this.playing) {
this.last_time = time;
this.shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.vor_shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.image_shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.renderer.render(GL);
return;
}
// Check if turn is still correct
if (time > this.last_time + ms_per_frame) {
this.last_time = time;
this.updateTurn(this.frame + 1);
if (this.frame == this.turn_count - 1) {
this.playing = false;
}
}
// Do GL things
GL.bindFramebuffer(GL.FRAMEBUFFER, null);
GL.viewport(0, 0, GL.canvas.width, GL.canvas.height);
GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT);
this.vor_shader.uniform(
GL,
"u_time",
new Uniform1f((time - this.last_time) / ms_per_frame)
);
this.vor_shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.vor_shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
this.vor_shader.uniform(GL, "u_vor", new UniformBool(this.use_vor));
this.shader.uniform(
GL,
"u_time",
new Uniform1f((time - this.last_time) / ms_per_frame)
);
this.shader.uniform(
GL,
"u_mouse",
new Uniform2f(this.resizer.get_mouse_pos())
);
this.shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
this.image_shader.uniform(
GL,
"u_time",
new Uniform1f((time - this.last_time) / ms_per_frame)
);
this.image_shader.uniform(
GL,
"u_mouse",
new Uniform2f(this.resizer.get_mouse_pos())
);
this.image_shader.uniform(
GL,
"u_viewbox",
new Uniform4f(this.resizer.get_viewbox())
);
this.image_shader.uniform(GL, "u_resolution", new Uniform2f(RESOLUTION));
// Render
this.renderer.render(GL);
COUNTER.frame_end();
}
updateTurn(turn: number) {
this.frame = Math.max(0, turn);
const new_frame = this.game.update_turn(this.frame);
if (new_frame < this.frame) {
this.frame = new_frame;
this.playing = false;
} else {
this._update_state();
this.playing = true;
}
this.updateTurnCounters();
}
updateTurnCounters() {
ELEMENTS["turnCounter"].innerHTML =
this.frame + " / " + (this.turn_count - 1);
ELEMENTS["turnSlider"].value = this.frame + "";
ELEMENTS["turnSlider"].max = this.turn_count - 1 + "";
}
handleKey(event: KeyboardEvent) {
// Space
if (event.keyCode == 32) {
if (this.playing) {
this.playing = false;
} else {
this.playing = true;
}
}
// Arrow left
if (event.keyCode == 37) {
// This feels more natural than -1 what it should be, I think
this.updateTurn(this.frame - 2);
}
// Arrow right
if (event.keyCode == 39) {
this.updateTurn(this.frame + 1);
}
// d key
if (event.keyCode == 68) {
ELEMENTS["speed"].value = ms_per_frame + 10 + "";
ELEMENTS["speed"].onchange(undefined);
}
// a key
if (event.keyCode == 65) {
ELEMENTS["speed"].value = Math.max(ms_per_frame - 10, 0) + "";
ELEMENTS["speed"].onchange(undefined);
}
}
}
var game_instance: GameInstance;
var meshes: Mesh[];
var shaders: Dictionary<ShaderFactory>;
export async function set_instance(source: string): Promise<GameInstance> {
if (!meshes || !shaders) {
const mesh_promises = ["ship.svg", "earth.svg", "mars.svg", "venus.svg"]
.map((name) => "/static/res/assets/" + name)
.map(url_to_mesh);
const shader_promies = [
(async () =>
<[string, ShaderFactory]>[
"normal",
await ShaderFactory.create_factory(
"/static/shaders/frag/simple.glsl",
"/static/shaders/vert/simple.glsl"
),
])(),
(async () =>
<[string, ShaderFactory]>[
"vor",
await ShaderFactory.create_factory(
"/static/shaders/frag/vor.glsl",
"/static/shaders/vert/vor.glsl"
),
])(),
(async () =>
<[string, ShaderFactory]>[
"image",
await ShaderFactory.create_factory(
"/static/shaders/frag/image.glsl",
"/static/shaders/vert/simple.glsl"
),
])(),
];
let shaders_array: [string, ShaderFactory][];
[meshes, shaders_array] = await Promise.all([
Promise.all(mesh_promises),
Promise.all(shader_promies),
]);
shaders = {};
shaders_array.forEach(([name, fac]) => (shaders[name] = fac));
}
resizeCanvasToDisplaySize(CANVAS);
game_instance = new GameInstance(
Game.new(source),
meshes.slice(1),
meshes[0],
shaders
);
set_loading(false);
start();
return game_instance;
}
var _animating = false;
export function start() {
if (_animating) {
// already running
return;
}
_animating = true;
requestAnimationFrame(step);
}
export function stop() {
_animating = false;
}
function step(time: number) {
if (game_instance) {
game_instance.render(time);
}
if (_animating) {
requestAnimationFrame(step);
}
}

View file

@ -0,0 +1,47 @@
import { set_game_name, set_loading, set_instance } from '../index'
var game_name, game_file;
document.getElementById("addbutton").onclick = function () {
const loc = window.location;
const query = `?game=${game_file}&name=${game_name}`;
navigator.clipboard.writeText(loc.origin + loc.pathname + encodeURI(query)).then(() => {
console.log("Success");
}, () => {
console.log("Failed");
});
}
async function on_load() {
const options = document.getElementsByClassName("options");
const urlVars = new URLSearchParams(window.location.search);
if (urlVars.get("game") && urlVars.get("name")) {
console.log(urlVars.get("game") + ' ' + urlVars.get("name"))
handle(urlVars.get("game"), urlVars.get("name"))
} else if (options[0]) {
const options_div = <HTMLDivElement>options[0];
if (options_div.children[0]) {
options_div.children[0].dispatchEvent(new Event('click'));
}
}
}
window.addEventListener("load", on_load, false);
export function handle(location: string, name: string) {
game_file = location;
game_name = name;
set_loading(true);
fetch(location)
.then((r) => r.text())
.then((response) => {
set_instance(response);
set_game_name(name);
}).catch(console.error);
}
on_load();

View file

@ -0,0 +1,309 @@
* {
margin: 0;
padding: 0;
}
body {
background-color: #333;
}
p {
padding: 3px 0;
}
#wrapper {
max-height: 100%;
min-height: 100%;
width: 100%;
height: 100%;
display: flex;
}
#main {
height: 100%;
flex-grow: 1;
position: relative;
}
#name {
position: absolute;
top: 10px;
left: 10px;
color: white;
}
#meta {
padding: 10px 2%;
color: white;
position: absolute;
bottom: 0;
width: 96%;
}
.options {
background-color: black;
max-width: 300px;
width: 20%;
min-width: 150px;
height: 100%;
display: flex;
flex-direction: column;
overflow-y: auto;
}
.option {
color: white;
margin: 0 0 20px 0;
padding: 10px;
background-color: #333;
}
.option:last-child {
margin: 0;
}
.option:hover {
background-color: #777;
}
.lds-roller {
display: none;
}
.loading>.lds-roller {
display: inline-block;
}
.lds-roller {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 80px;
height: 80px;
}
.lds-roller div {
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.lds-roller div:after {
content: " ";
display: block;
position: absolute;
width: 7px;
height: 7px;
border-radius: 50%;
background: #fff;
margin: -4px 0 0 -4px;
}
.lds-roller div:nth-child(1) {
animation-delay: -0.036s;
}
.lds-roller div:nth-child(1):after {
top: 63px;
left: 63px;
}
.lds-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.lds-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.lds-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.lds-roller div:nth-child(3):after {
top: 71px;
left: 48px;
}
.lds-roller div:nth-child(4) {
animation-delay: -0.144s;
}
.lds-roller div:nth-child(4):after {
top: 72px;
left: 40px;
}
.lds-roller div:nth-child(5) {
animation-delay: -0.18s;
}
.lds-roller div:nth-child(5):after {
top: 71px;
left: 32px;
}
.lds-roller div:nth-child(6) {
animation-delay: -0.216s;
}
.lds-roller div:nth-child(6):after {
top: 68px;
left: 24px;
}
.lds-roller div:nth-child(7) {
animation-delay: -0.252s;
}
.lds-roller div:nth-child(7):after {
top: 63px;
left: 17px;
}
.lds-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.lds-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes lds-roller {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#speed {
width: 100px;
}
#canvas {
position: relative;
background-color: black;
width: 100%;
height: 100%;
}
.button {
position: absolute;
top: 10px;
right: 10px;
width: 0;
height: 0;
}
.button::before {
content: "";
display: block;
float: left;
margin: 0 -20px 0 0;
font-family: 'fontawesome';
content: "\f1e1";
transform: translate(-1em, 0px);
color: antiquewhite;
font-size: 1.5em;
}
.button:hover::before {
color: #ff7f00;
}
/* ----------------------------------------------
* Generated by Animista on 2019-9-17 14:35:13
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation slide-top
* ----------------------------------------
*/
@-webkit-keyframes slide-top {
0% {
-webkit-transform: translate(-50%, 50%);
transform: translate(-50%, 50%);
}
100% {
-webkit-transform: translate(-50%, -150%);
transform: translate(-50%, -150%);
}
}
@keyframes slide-top {
0% {
-webkit-transform: translate(-50%, 50%);
transform: translate(-50%, 50%);
}
100% {
-webkit-transform: translate(-50%, -150%);
transform: translate(-50%, -150%);
}
}
/**
* ----------------------------------------
* Copy from https://www.w3schools.com/howto/howto_js_rangeslider.asp
* ----------------------------------------
*/
.slidecontainer {
margin-top: 10px;
width: 100%;
/* Width of the outside container */
}
.slider {
-webkit-appearance: none;
width: 100%;
height: 15px;
border-radius: 5px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
border-radius: 50%;
background: #ff7000;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
border-radius: 50%;
background: #ff7000;
cursor: pointer;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius: 10px;
background-color: #444;
border-radius: 10px;
}
::-webkit-scrollbar {
width: 10px;
background-color: #444;
}
::-webkit-scrollbar-thumb {
border-radius: 10px;
background-color: #F90;
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .2) 50%, rgba(255, 255, 255, .2) 75%, transparent 75%, transparent)
}

View file

@ -0,0 +1,56 @@
declare namespace Voronoi {
class Point {
x: number;
y: number;
}
class Site {
x: number;
y: number;
voronoiId: number;
}
class Cell {
site: Site;
halfedges: HalfEdge[];
closeMe: boolean;
}
class Edge {
lSite: Site;
rSite: Site;
vb: Point;
va: Point;
}
class HalfEdge {
site: Site;
edge: Edge;
angle: number;
getStartpoint(): Point;
getEndpoint(): Point;
}
class BBox {
xl: number;
xr: number;
yt: number;
yb: number;
}
class VoronoiDiagram {
site: any;
cells: Cell[];
edges: Edge[];
vertices: Point[];
execTime: number;
}
}
declare class Voronoi {
constructor();
compute(sites: Voronoi.Point[], bbox: Voronoi.BBox): Voronoi.VoronoiDiagram;
}
export = Voronoi;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,165 @@
import type { Shader } from "../webgl/shader";
import type { BBox, Point } from "./voronoi-core";
import Voronoi from "./voronoi-core";
import { DefaultRenderable } from "../webgl/renderer";
import { IndexBuffer, VertexBuffer } from "../webgl/buffer";
import { VertexBufferLayout, VertexArray } from "../webgl/vertexBufferLayout";
function arcctg(x: number): number { return Math.PI / 2 - Math.atan(x); }
function to_key(p: Point): string {
return [p.x, p.y] + "";
}
function round_point(center: Point, point: Point, amount_fn = (b: number) => 0.7): Point {
const d = dist(center, point, true);
const x = center.x + amount_fn(d) * (point.x - center.x);
const y = center.y + amount_fn(d) * (point.y - center.y);
return { 'x': x, 'y': y };
}
function median_point(c: Point, p: Point, n: Point, d = 0.1): number[] {
const dd = 1.0 - 2 * d;
return [
dd * c.x + d * p.x + d * n.x,
dd * c.y + d * p.y + d * n.y,
]
}
function build_point_map(es: Voronoi.HalfEdge[]): (point: Point) => Point {
const mean = es.map(e => dist(e.getStartpoint(), e.getEndpoint())).reduce((a, b) => a + b, 0) / es.length;
const map = {};
for (let edge of es) {
const start = edge.getStartpoint();
const end = edge.getEndpoint();
if (dist(start, end) < 0.03 * mean) { // These points have to be merged
const middle = { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 };
map[to_key(start)] = middle;
map[to_key(end)] = middle;
}
}
return (p) => map[to_key(p)] || p;
}
function get_round_fn(dist_mean: number, amount = 0.7): (d: number) => number {
return (d) => arcctg((d - dist_mean) / dist_mean) / Math.PI + 0.6;
}
function dist(a: Point, b: Point, norm = false): number {
const dx = a.x - b.x;
const dy = a.y - b.y;
if (norm) return Math.sqrt(dx * dx + dy * dy);
return dx * dx + dy * dy;
}
export class VoronoiBuilder {
inner: DefaultRenderable;
vor: Voronoi;
planets: Point[];
constructor(gl: WebGLRenderingContext, shader: Shader, planets: Point[], bbox: BBox) {
this.vor = new Voronoi();
this.planets = planets;
const ib = new IndexBuffer(gl, []);
const vb = new VertexBuffer(gl, []);
const layout = new VertexBufferLayout();
layout.push(gl.FLOAT, 2, 4, "a_pos");
layout.push(gl.FLOAT, 2, 4, "a_center");
layout.push(gl.FLOAT, 1, 4, "a_own");
layout.push(gl.FLOAT, 1, 4, "a_intensity");
const vao = new VertexArray();
vao.addBuffer(vb, layout);
this.inner = new DefaultRenderable(ib, vao, shader, [], {});
this.resize(gl, bbox);
}
getRenderable(): DefaultRenderable {
return this.inner;
}
resize(gl: WebGLRenderingContext, bbox: BBox) {
const start = new Date().getTime();
// This voronoi sorts the planets, then owners don't align anymore
const own_map = {};
this.planets.forEach((p, i) => own_map[to_key(p)] = i);
const vor = this.vor.compute(this.planets, bbox);
const attrs = [];
const ids = [];
let vertCount = 0;
for (let i = 0; i < vor.cells.length; i++) {
const cell = vor.cells[i];
const planetId = own_map[to_key(cell.site)];
const point_map = build_point_map(cell.halfedges);
const centerId = vertCount++;
attrs.push(cell.site.x, cell.site.y);
attrs.push(cell.site.x, cell.site.y);
attrs.push(planetId);
attrs.push(1);
const dist_mean = cell.halfedges.map(e => {
const start = e.getStartpoint();
const end = e.getEndpoint();
return dist(cell.site, start, true) + dist(cell.site, { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 }, true)
}).reduce((a, b) => a + b, 0) / cell.halfedges.length / 2;
const round_fn = get_round_fn(dist_mean);
for (let edge of cell.halfedges) {
let start = point_map(edge.getStartpoint());
let end = point_map(edge.getEndpoint());
let center = { 'x': (start.x + end.x) / 2, 'y': (start.y + end.y) / 2 };
if (to_key(start) == to_key(end)) continue;
start = round_point(cell.site, start, round_fn);
center = round_point(cell.site, center, round_fn);
end = round_point(cell.site, end, round_fn);
ids.push(centerId);
ids.push(vertCount++);
attrs.push(start.x, start.y);
attrs.push(cell.site.x, cell.site.y);
attrs.push(planetId);
attrs.push(0);
ids.push(vertCount++);
attrs.push(center.x, center.y);
attrs.push(cell.site.x, cell.site.y);
attrs.push(planetId);
attrs.push(0);
ids.push(centerId);
ids.push(vertCount - 1);
ids.push(vertCount++);
attrs.push(end.x, end.y);
attrs.push(cell.site.x, cell.site.y);
attrs.push(planetId);
attrs.push(0);
}
}
this.inner.updateIndexBuffer(gl, ids);
this.inner.updateVAOBuffer(gl, 0, attrs);
console.log(`Vor things took ${new Date().getTime() - start} ms!`)
}
}
export default VoronoiBuilder;

View file

@ -0,0 +1,55 @@
export class Buffer {
buffer: WebGLBuffer;
data: any;
count: number;
type: number;
constructor(gl: WebGLRenderingContext, data: number[], type: number) {
this.buffer = gl.createBuffer();
this.type = type;
if (data)
this.updateData(gl, data);
}
_toArray(data: number[]): any {
return new Float32Array(data);
}
updateData(gl: WebGLRenderingContext, data: number[]) {
this.data = data;
this.count = data.length;
gl.bindBuffer(this.type, this.buffer);
gl.bufferData(this.type, this._toArray(data), gl.STATIC_DRAW);
}
bind(gl: WebGLRenderingContext) {
gl.bindBuffer(this.type, this.buffer);
}
getCount(): number {
return this.count;
}
}
export class VertexBuffer extends Buffer {
constructor(gl: WebGLRenderingContext, data: any) {
super(gl, data, gl.ARRAY_BUFFER);
}
_toArray(data: number[]): any {
return new Float32Array(data);
}
}
export class IndexBuffer extends Buffer {
constructor(gl: WebGLRenderingContext, data: any) {
super(gl, data, gl.ELEMENT_ARRAY_BUFFER);
}
_toArray(data: number[]): any {
return new Uint16Array(data);
}
}

View file

@ -0,0 +1,122 @@
import { Uniform4f, Uniform1f, Uniform2f, ShaderFactory, UniformMatrix3fv, Uniform3f } from './shader';
import { resizeCanvasToDisplaySize, FPSCounter, onload2promise, Resizer, url_to_mesh } from "./util";
import { VertexBuffer, IndexBuffer } from './buffer';
import { VertexArray, VertexBufferLayout } from './vertexBufferLayout';
import { Renderer } from './renderer';
import { Texture } from './texture';
const URL = window.location.origin+window.location.pathname;
const LOCATION = URL.substring(0, URL.lastIndexOf("/") + 1);
async function create_texture_from_svg(gl: WebGLRenderingContext, name: string, path: string, width: number, height: number): Promise<Texture> {
const [mesh, factory] = await Promise.all([
url_to_mesh(path),
ShaderFactory.create_factory(LOCATION + "static/shaders/frag/static_color.glsl", LOCATION + "static/shaders/vert/svg.glsl")
]);
const program = factory.create_shader(gl);
const renderer = new Renderer();
var positionBuffer = new VertexBuffer(gl, mesh.positions);
var layout = new VertexBufferLayout();
layout.push(gl.FLOAT, 3, 4, "a_position");
const vao = new VertexArray();
vao.addBuffer(positionBuffer, layout);
program.bind(gl);
vao.bind(gl, program);
var indexBuffer = new IndexBuffer(gl, mesh.cells);
indexBuffer.bind(gl);
renderer.addToDraw(indexBuffer, vao, program, {});
return Texture.fromRenderer(gl, name, width, height, renderer);
}
async function main() {
// Get A WebGL context
var canvas = <HTMLCanvasElement>document.getElementById("c");
const resolution = [canvas.width, canvas.height];
const resizer = new Resizer(canvas, [-10, -10, 20, 20], true);
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
const mesh = await url_to_mesh("static/res/images/earth.svg");
console.log(Math.max(...mesh.positions), Math.min(...mesh.positions));
const renderer = new Renderer();
const factory = await ShaderFactory.create_factory(LOCATION + "static/shaders/frag/static_color.glsl", LOCATION + "static/shaders/vert/simple.glsl");
const program = factory.create_shader(gl);
var positionBuffer = new VertexBuffer(gl, mesh.positions);
var layout = new VertexBufferLayout();
layout.push(gl.FLOAT, 3, 4, "a_position");
// layout.push(gl.FLOAT, 2, 4, "a_tex");
const vao = new VertexArray();
vao.addBuffer(positionBuffer, layout);
resizeCanvasToDisplaySize(<HTMLCanvasElement>gl.canvas);
// Tell WebGL how to convert from clip space to pixels
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Clear the canvas
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
program.bind(gl);
vao.bind(gl, program);
var indexBuffer = new IndexBuffer(gl, mesh.cells);
indexBuffer.bind(gl);
renderer.addToDraw(indexBuffer, vao, program, {});
const counter = new FPSCounter();
const step = function (time: number) {
// console.log(resizer.get_viewbox());
program.uniform(gl, "u_time", new Uniform1f(time * 0.001));
program.uniform(gl, "u_mouse", new Uniform2f(resizer.get_mouse_pos()));
program.uniform(gl, "u_viewbox", new Uniform4f(resizer.get_viewbox()));
program.uniform(gl, "u_resolution", new Uniform2f(resolution));
program.uniform(gl, "u_trans", new UniformMatrix3fv([1, 0, 0, 0, 1, 0, 0, 0, 1]));
program.uniform(gl, "u_color", new Uniform3f(1.0, 0.5, 0.0));
renderer.render(gl);
counter.frame(time);
requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
main();
document.getElementById("loader").classList.remove("loading");
// const loader = document.getElementById("loader");
// setInterval(() => {
// if (loader.classList.contains("loading")) {
// loader.classList.remove("loading")
// } else {
// loader.classList.add("loading");
// }
// }, 2000);

View file

@ -0,0 +1,157 @@
import type { IndexBuffer } from './buffer';
import type { VertexArray } from './vertexBufferLayout';
import type { Texture } from './texture';
import type { Dictionary } from './util';
import type { Shader, Uniform } from './shader';
import { Uniform1i } from './shader';
function sortedIndex(array, value) {
var low = 0,
high = array.length;
while (low < high) {
var mid = (low + high) >>> 1;
if (array[mid] < value) low = mid + 1;
else high = mid;
}
return low;
}
export interface Renderable {
getUniforms() : Dictionary<Uniform>;
render(gl: WebGLRenderingContext): void;
updateVAOBuffer(gl: WebGLRenderingContext, index: number, data: number[]);
updateIndexBuffer(gl: WebGLRenderingContext, data: number[]);
}
export class DefaultRenderable implements Renderable {
ibo: IndexBuffer;
va: VertexArray;
shader: Shader;
textures: Texture[];
uniforms: Dictionary<Uniform>;
constructor(
ibo: IndexBuffer,
va: VertexArray,
shader: Shader,
textures: Texture[],
uniforms: Dictionary<Uniform>,
) {
this.ibo = ibo;
this.va = va;
this.shader = shader;
this.textures = textures;
this.uniforms = uniforms;
}
getUniforms(): Dictionary<Uniform> {
return this.uniforms;
}
updateVAOBuffer(gl: WebGLRenderingContext, index: number, data: number[]) {
this.va.updateBuffer(gl, index, data);
}
updateIndexBuffer(gl: WebGLRenderingContext, data: number[]) {
this.ibo.updateData(gl, data);
}
render(gl: WebGLRenderingContext): void {
const indexBuffer = this.ibo;
const vertexArray = this.va;
const uniforms = this.uniforms;
const shader = this.shader;
const textures = this.textures;
let texLocation = 0;
for (let texture of textures) {
shader.uniform(gl, texture.name, new Uniform1i(texLocation));
texture.bind(gl, texLocation);
texLocation ++;
// if (texLocation > maxTextures) {
// console.error("Using too many textures, this is not supported yet\nUndefined behaviour!");
// }
}
if (vertexArray && shader && uniforms) {
for(let key in uniforms) {
shader.uniform(gl, key, uniforms[key]);
}
vertexArray.bind(gl, shader);
if (indexBuffer) {
indexBuffer.bind(gl);
gl.drawElements(gl.TRIANGLES, indexBuffer.getCount(), gl.UNSIGNED_SHORT, 0);
} else {
console.error("IndexBuffer is required to render, for now");
}
}
}
}
export class Renderer {
renderables: { [id: number] : [Renderable, boolean][]; };
renderable_layers: number[];
constructor() {
this.renderables = {};
this.renderable_layers = [];
}
updateUniform(i: number, f: (uniforms: Dictionary<Uniform>) => void, layer=0, ) {
f(this.renderables[layer][i][0].getUniforms());
}
disableRenderable(i: number, layer=0) {
this.renderables[layer][i][1] = false;
}
enableRenderable(i: number, layer=0) {
this.renderables[layer][i][1] = true;
}
addRenderable(item: Renderable, layer=0): number {
if(!this.renderables[layer]) {
const idx = sortedIndex(this.renderable_layers, layer);
this.renderable_layers.splice(idx, 0, layer);
this.renderables[layer] = [];
}
this.renderables[layer].push([item, true]);
return this.renderables[layer].length - 1;
}
addToDraw(indexBuffer: IndexBuffer, vertexArray: VertexArray, shader: Shader, uniforms?: Dictionary<Uniform>, texture?: Texture[], layer=0): number {
return this.addRenderable(
new DefaultRenderable(
indexBuffer,
vertexArray,
shader,
texture || [],
uniforms || {},
), layer
);
}
render(gl: WebGLRenderingContext, frameBuffer?: WebGLFramebuffer, width?: number, height?: number) {
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.viewport(0, 0, width || gl.canvas.width, height || gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const maxTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
for (let layer of this.renderable_layers) {
for (let [r, e] of this.renderables[layer]) {
if (!e) continue;
r.render(gl);
}
}
}
}

View file

@ -0,0 +1,327 @@
import type { Dictionary } from './util';
function error(msg: string) {
console.error(msg);
}
const defaultShaderType = [
"VERTEX_SHADER",
"FRAGMENT_SHADER"
];
/// Create Shader from Source string
function loadShader(
gl: WebGLRenderingContext,
shaderSource: string,
shaderType: number,
opt_errorCallback: any,
): WebGLShader {
var errFn = opt_errorCallback || error;
// Create the shader object
var shader = gl.createShader(shaderType);
// Load the shader source
gl.shaderSource(shader, shaderSource);
// Compile the shader
gl.compileShader(shader);
// Check the compile status
var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
// Something went wrong during compilation; get the error
var lastError = gl.getShaderInfoLog(shader);
errFn("*** Error compiling shader '" + shader + "':" + lastError);
gl.deleteShader(shader);
return null;
}
return shader;
}
/// Actually Create Program with Shader's
function createProgram(
gl: WebGLRenderingContext,
shaders: WebGLShader[],
opt_attribs: string[],
opt_locations: number[],
opt_errorCallback: any,
): WebGLProgram {
var errFn = opt_errorCallback || error;
var program = gl.createProgram();
shaders.forEach(function (shader) {
gl.attachShader(program, shader);
});
if (opt_attribs) {
opt_attribs.forEach(function (attrib, ndx) {
gl.bindAttribLocation(
program,
opt_locations ? opt_locations[ndx] : ndx,
attrib);
});
}
gl.linkProgram(program);
// Check the link status
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
// something went wrong with the link
var lastError = gl.getProgramInfoLog(program);
errFn("Error in program linking:" + lastError);
gl.deleteProgram(program);
return null;
}
return program;
}
export class ShaderFactory {
frag_source: string;
vert_source: string;
static async create_factory(frag_url: string, vert_url: string): Promise<ShaderFactory> {
const sources = await Promise.all([
fetch(frag_url).then((r) => r.text()),
fetch(vert_url).then((r) => r.text()),
]);
return new ShaderFactory(sources[0], sources[1]);
}
constructor(frag_source: string, vert_source: string ) {
this.frag_source = frag_source;
this.vert_source = vert_source;
}
create_shader(
gl: WebGLRenderingContext,
context?: Dictionary<string>,
opt_attribs?: string[],
opt_locations?: number[],
opt_errorCallback?: any,
): Shader {
let vert = this.vert_source.slice();
let frag = this.frag_source.slice();
for (let key in context) {
vert = vert.replace(new RegExp("\\$" + key, 'g'), context[key]);
frag = frag.replace(new RegExp("\\$" + key, 'g'), context[key]);
}
const shaders = [
loadShader(gl, vert, gl.VERTEX_SHADER, opt_errorCallback),
loadShader(gl, frag, gl.FRAGMENT_SHADER, opt_errorCallback),
];
return new Shader(createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback));
}
}
export class Shader {
shader: WebGLProgram;
uniformCache: Dictionary<WebGLUniformLocation>;
attribCache: Dictionary<number>;
static async createProgramFromUrls(
gl: WebGLRenderingContext,
vert_url: string,
frag_url: string,
context?: Dictionary<string>,
opt_attribs?: string[],
opt_locations?: number[],
opt_errorCallback?: any,
): Promise<Shader> {
const sources = (await Promise.all([
fetch(vert_url).then((r) => r.text()),
fetch(frag_url).then((r) => r.text()),
])).map(x => {
for (let key in context) {
x = x.replace(new RegExp("\\$" + key, 'g'), context[key]);
}
return x;
});
const shaders = [
loadShader(gl, sources[0], 35633, opt_errorCallback),
loadShader(gl, sources[1], 35632, opt_errorCallback),
];
return new Shader(createProgram(gl, shaders, opt_attribs, opt_locations, opt_errorCallback));
}
constructor(shader: WebGLProgram) {
this.shader = shader;
this.uniformCache = {};
this.attribCache = {};
}
bind(gl: WebGLRenderingContext) {
gl.useProgram(this.shader);
}
// Different locations have different types :/
getUniformLocation(gl: WebGLRenderingContext, name: string): WebGLUniformLocation {
if (this.uniformCache[name] === undefined) {
this.uniformCache[name] = gl.getUniformLocation(this.shader, name);
}
return this.uniformCache[name];
}
getAttribLocation(gl: WebGLRenderingContext, name: string): number {
if (this.attribCache[name] === undefined) {
this.attribCache[name] = gl.getAttribLocation(this.shader, name);
}
return this.attribCache[name];
}
uniform<T extends Uniform>(
gl: WebGLRenderingContext,
name: string,
uniform: T,
) {
this.bind(gl);
const location = this.getUniformLocation(gl, name);
if (location < 0) {
console.error("No location found with name " + name);
}
uniform.setUniform(gl, location);
}
clear(gl: WebGLRenderingContext) {
gl.deleteProgram(this.shader);
}
}
export interface Uniform {
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation): void;
}
export class Uniform2fv implements Uniform {
data: number[] | Float32Array;
constructor(data: number[] | Float32Array) {
this.data = data;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform2fv(location, this.data);
}
}
export class Uniform3fv implements Uniform {
data: number[] | Float32Array;
constructor(data: number[] | Float32Array) {
this.data = data;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform3fv(location, this.data);
}
}
export class Uniform3f implements Uniform {
x: number;
y: number;
z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform3f(location, this.x ,this.y, this.z);
}
}
export class Uniform1iv implements Uniform {
data: number[] | Int32List;
constructor(data: number[] | Int32List) {
this.data = data;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform1iv(location, this.data);
}
}
export class Uniform1i implements Uniform {
texture: number;
constructor(texture: number) {
this.texture = texture;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform1i(location, this.texture);
}
}
export class Uniform1f implements Uniform {
texture: number;
constructor(texture: number) {
this.texture = texture;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform1f(location, this.texture);
}
}
export class Uniform2f implements Uniform {
x: number;
y: number;
constructor(xy: number[]) {
this.x = xy[0];
this.y = xy[1];
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform2f(location, this.x, this.y);
}
}
export class Uniform4f implements Uniform {
v0: number;
v1: number;
v2: number;
v3: number;
constructor(xyzw: number[]) {
this.v0 = xyzw[0];
this.v1 = xyzw[1];
this.v2 = xyzw[2];
this.v3 = xyzw[3];
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform4f(location, this.v0, this.v1, this.v2, this.v3);
}
}
export class UniformMatrix3fv implements Uniform {
data: number[] | Float32Array;
constructor(data: number[] | Float32Array) {
this.data = data;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniformMatrix3fv(location, false, this.data);
}
}
export class UniformBool implements Uniform {
data: boolean;
constructor(data: boolean) {
this.data = data;
}
setUniform(gl: WebGLRenderingContext, location: WebGLUniformLocation) {
gl.uniform1i(location, this.data ? 1 : 0);
}
}
export default Shader;

View file

@ -0,0 +1,192 @@
import type { Dictionary } from "./util";
import type { Shader, UniformMatrix3fv } from "./shader";
import { Texture } from "./texture";
import { DefaultRenderable } from "./renderer";
import { IndexBuffer, VertexBuffer } from "./buffer";
import { VertexBufferLayout, VertexArray } from "./vertexBufferLayout";
export enum Align {
Begin,
End,
Middle,
}
export class GlypInfo {
x: number;
y: number;
width: number;
}
export class FontInfo {
letterHeight: number;
spaceWidth: number;
spacing: number;
textureWidth: number;
textureHeight: number;
glyphInfos: Dictionary<GlypInfo>;
}
export class LabelFactory {
texture: Texture;
font: FontInfo;
shader: Shader;
constructor(gl: WebGLRenderingContext, loc: string, font: FontInfo, shader: Shader) {
this.texture = Texture.fromImage(gl, loc, 'font');
this.font = font;
this.shader = shader;
}
build(gl: WebGLRenderingContext, transform?: UniformMatrix3fv): Label {
return new Label(gl, this.shader, this.texture, this.font, transform);
}
}
export class Label {
inner: DefaultRenderable;
font: FontInfo;
constructor(gl: WebGLRenderingContext, shader: Shader, tex: Texture, font: FontInfo, transform?: UniformMatrix3fv) {
this.font = font;
const uniforms = transform ? { "u_trans": transform, "u_trans_next": transform, } : {};
const ib = new IndexBuffer(gl, []);
const vb_pos = new VertexBuffer(gl, []);
const vb_tex = new VertexBuffer(gl, []);
const layout_pos = new VertexBufferLayout();
layout_pos.push(gl.FLOAT, 2, 4, "a_position");
const layout_tex = new VertexBufferLayout();
layout_tex.push(gl.FLOAT, 2, 4, "a_texCoord");
const vao = new VertexArray();
vao.addBuffer(vb_pos, layout_pos);
vao.addBuffer(vb_tex, layout_tex);
this.inner = new DefaultRenderable(ib, vao, shader, [tex], uniforms);
}
getRenderable(): DefaultRenderable {
return this.inner;
}
setText(gl: WebGLRenderingContext, text: string, h_align = Align.Begin, v_align = Align.Begin) {
const idxs = [];
const verts_pos = [];
const verts_tex = [];
const letterHeight = this.font.letterHeight / this.font.textureHeight;
let xPos = 0;
switch (h_align) {
case Align.Begin:
break;
case Align.End:
xPos = -1 * [...text].map(n => this.font.glyphInfos[n] ? this.font.glyphInfos[n].width : this.font.spaceWidth).reduce((a, b) => a + b, 0) / this.font.letterHeight;
break;
case Align.Middle:
xPos = -1 * [...text].map(n => this.font.glyphInfos[n] ? this.font.glyphInfos[n].width : this.font.spaceWidth).reduce((a, b) => a + b, 0) / this.font.letterHeight / 2;
break;
}
let yStart = 0;
switch (v_align) {
case Align.Begin:
break;
case Align.End:
yStart = 1;
break;
case Align.Middle:
yStart = 0.5;
break;
}
let j = 0;
for (let i = 0; i < text.length; i++) {
const info = this.font.glyphInfos[text[i]];
if (info) {
const dx = info.width / this.font.letterHeight;
const letterWidth = info.width / this.font.textureWidth;
const x0 = info.x / this.font.textureWidth;
const y0 = info.y / this.font.textureHeight;
verts_pos.push(xPos, yStart);
verts_pos.push(xPos + dx, yStart);
verts_pos.push(xPos, yStart-1);
verts_pos.push(xPos + dx, yStart-1);
verts_tex.push(x0, y0);
verts_tex.push(x0 + letterWidth, y0);
verts_tex.push(x0, y0 + letterHeight);
verts_tex.push(x0 + letterWidth, y0 + letterHeight);
xPos += dx;
idxs.push(j+0, j+1, j+2, j+1, j+2, j+3);
j += 4;
} else {
// Just move xPos
xPos += this.font.spaceWidth / this.font.letterHeight;
}
}
this.inner.updateIndexBuffer(gl, idxs);
this.inner.updateVAOBuffer(gl, 0, verts_pos);
this.inner.updateVAOBuffer(gl, 1, verts_tex);
}
}
export function defaultLabelFactory(gl: WebGLRenderingContext, shader: Shader): LabelFactory {
const fontInfo = {
letterHeight: 8,
spaceWidth: 8,
spacing: -1,
textureWidth: 64,
textureHeight: 40,
glyphInfos: {
'a': { x: 0, y: 0, width: 8, },
'b': { x: 8, y: 0, width: 8, },
'c': { x: 16, y: 0, width: 8, },
'd': { x: 24, y: 0, width: 8, },
'e': { x: 32, y: 0, width: 8, },
'f': { x: 40, y: 0, width: 8, },
'g': { x: 48, y: 0, width: 8, },
'h': { x: 56, y: 0, width: 8, },
'i': { x: 0, y: 8, width: 8, },
'j': { x: 8, y: 8, width: 8, },
'k': { x: 16, y: 8, width: 8, },
'l': { x: 24, y: 8, width: 8, },
'm': { x: 32, y: 8, width: 8, },
'n': { x: 40, y: 8, width: 8, },
'o': { x: 48, y: 8, width: 8, },
'p': { x: 56, y: 8, width: 8, },
'q': { x: 0, y: 16, width: 8, },
'r': { x: 8, y: 16, width: 8, },
's': { x: 16, y: 16, width: 8, },
't': { x: 24, y: 16, width: 8, },
'u': { x: 32, y: 16, width: 8, },
'v': { x: 40, y: 16, width: 8, },
'w': { x: 48, y: 16, width: 8, },
'x': { x: 56, y: 16, width: 8, },
'y': { x: 0, y: 24, width: 8, },
'z': { x: 8, y: 24, width: 8, },
'0': { x: 16, y: 24, width: 8, },
'1': { x: 24, y: 24, width: 8, },
'2': { x: 32, y: 24, width: 8, },
'3': { x: 40, y: 24, width: 8, },
'4': { x: 48, y: 24, width: 8, },
'5': { x: 56, y: 24, width: 8, },
'6': { x: 0, y: 32, width: 8, },
'7': { x: 8, y: 32, width: 8, },
'8': { x: 16, y: 32, width: 8, },
'9': { x: 24, y: 32, width: 8, },
'-': { x: 32, y: 32, width: 8, },
'*': { x: 40, y: 32, width: 8, },
'!': { x: 48, y: 32, width: 8, },
'?': { x: 56, y: 32, width: 8, },
},
};
return new LabelFactory(gl, '/static/res/assets/font.png', fontInfo, shader);
}

View file

@ -0,0 +1,106 @@
import type { Renderer } from "./renderer";
export class Texture {
texture: WebGLTexture;
width: number;
height: number;
loaded: boolean;
name: string;
static fromImage(
gl: WebGLRenderingContext,
path: string,
name: string,
): Texture {
const out = new Texture(gl, name);
const image = new Image();
image.onload = out.setImage.bind(out, gl, image);
image.onerror = error;
image.src = path;
return out;
}
static fromRenderer(
gl: WebGLRenderingContext,
name: string,
width: number,
height: number,
renderer: Renderer
): Texture {
const out = new Texture(gl, name);
out.width = width;
out.height = height;
gl.texImage2D(
gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const attachmentPoint = gl.COLOR_ATTACHMENT0;
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, out.texture, 0);
renderer.render(gl, fb, width, height);
out.loaded = true;
return out;
}
constructor(
gl: WebGLRenderingContext,
name: string,
) {
this.loaded = false;
this.name = name;
this.texture = gl.createTexture();
this.bind(gl);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA,
gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255]));
}
setImage(gl: WebGLRenderingContext, image: HTMLImageElement) {
this.bind(gl);
this.width = image.width;
this.height = image.height;
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
this.unbind(gl);
this.loaded = true;
}
bind(gl: WebGLRenderingContext, location=0) {
gl.activeTexture(gl.TEXTURE0 + location);
gl.bindTexture(gl.TEXTURE_2D, this.texture);
}
unbind(gl: WebGLRenderingContext) {
gl.bindTexture(gl.TEXTURE_2D, null);
}
getWidth(): number {
return this.width;
}
getHeight(): number {
return this.height;
}
}
function error(e: any) {
console.error("IMAGE LOAD ERROR");
console.error(e);
}

View file

@ -0,0 +1,229 @@
import { parse as parsePath } from 'extract-svg-path';
import svgMesh3d from 'svg-mesh-3d';
export interface Dictionary<T> {
[Key: string]: T;
}
interface OnLoadable {
onload: any;
}
export function onload2promise<T extends OnLoadable>(obj: T): Promise<T> {
return new Promise(resolve => {
obj.onload = () => resolve(obj);
});
}
export function resizeCanvasToDisplaySize(
canvas: HTMLCanvasElement,
multiplier?: number,
): boolean {
multiplier = multiplier || 1;
var width = canvas.clientWidth * multiplier | 0;
var height = canvas.clientHeight * multiplier | 0;
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
return true;
}
return false;
}
export class FPSCounter {
last: number;
count: number;
_delta: number;
_prev: number;
_frame_start: number;
_total_frametime: number;
constructor() {
this.last = 0;
this.count = 0;
this._delta = 0;
this._prev = 0;
}
frame(now: number) {
this._frame_start = performance.now();
this.count += 1;
this._delta = now - this._prev;
this._prev = now;
if (now - this.last > 1000) {
this.last = now;
console.log(`${this.count} fps, ${(this._total_frametime / this.count).toFixed(2)}ms avg per frame`);
this.count = 0;
this._total_frametime = 0;
}
}
frame_end() {
this._total_frametime += (performance.now() - this._frame_start);
}
delta(now: number): number {
return this._delta;
}
}
export class Resizer {
hoovering = false;
dragging = false;
mouse_pos = [0, 0];
last_drag = [0, 0];
viewbox: number[];
orig_viewbox: number[];
el_box: number[];
scaleX = 1;
scaleY = 1;
constructor(el: HTMLCanvasElement, viewbox: number[], keep_aspect_ratio=false) {
viewbox = [-viewbox[0] - viewbox[2], - viewbox[1] - viewbox[3], viewbox[2], viewbox[3]];
this.viewbox = [...viewbox];
this.el_box = [el.width, el.height];
if (keep_aspect_ratio) {
const or_width = this.viewbox[2];
const or_height = this.viewbox[3];
const width_percentage = this.viewbox[2] / el.width;
const height_percentage = this.viewbox[3] / el.height;
if (width_percentage < height_percentage) {
// width should be larger
this.viewbox[2] = height_percentage * el.width;
} else {
// height should be larger
this.viewbox[3] = width_percentage * el.height;
}
this.viewbox[0] -= (this.viewbox[2] - or_width) / 2;
this.viewbox[1] -= (this.viewbox[3] - or_height) / 2;
this.scaleX = this.viewbox[2] / this.viewbox[3];
}
this.orig_viewbox = [...this.viewbox];
el.addEventListener("mouseenter", this.mouseenter.bind(this), { capture: false, passive: true});
el.addEventListener("mouseleave", this.mouseleave.bind(this), { capture: false, passive: true});
el.addEventListener("mousemove", this.mousemove.bind(this), { capture: false, passive: true});
el.addEventListener("mousedown", this.mousedown.bind(this), { capture: false, passive: true});
el.addEventListener("mouseup", this.mouseup.bind(this), { capture: false, passive: true});
window.addEventListener('wheel', this.wheel.bind(this), { capture: false, passive: true});
}
_clip_viewbox() {
this.viewbox[0] = Math.max(this.viewbox[0], this.orig_viewbox[0]);
this.viewbox[1] = Math.max(this.viewbox[1], this.orig_viewbox[1]);
this.viewbox[0] = Math.min(this.viewbox[0] + this.viewbox[2], this.orig_viewbox[0] + this.orig_viewbox[2]) - this.viewbox[2];
this.viewbox[1] = Math.min(this.viewbox[1] + this.viewbox[3], this.orig_viewbox[1] + this.orig_viewbox[3]) - this.viewbox[3];
}
mouseenter() {
this.hoovering = true;
}
mouseleave() {
this.hoovering = false;
}
mousemove(e: MouseEvent) {
this.mouse_pos = [e.offsetX, this.el_box[1] - e.offsetY];
if (this.dragging) {
const scaleX = this.viewbox[2] / this.el_box[0];
const scaleY = this.viewbox[3] / this.el_box[1];
this.viewbox[0] += (this.last_drag[0] - this.mouse_pos[0]) * scaleX;
this.viewbox[1] += (this.last_drag[1] - this.mouse_pos[1]) * scaleY;
this.last_drag = [...this.mouse_pos];
this._clip_viewbox();
}
}
mousedown() {
this.dragging = true;
this.last_drag = [...this.mouse_pos];
}
mouseup() {
this.dragging = false;
}
wheel(e: WheelEvent) {
if (this.hoovering) {
const delta = e.deltaY > 0 ? 0.1 * this.viewbox[2] : -0.1 * this.viewbox[2];
const dx = delta * this.scaleX;
const dy = delta * this.scaleY;
const mouse_dx = this.mouse_pos[0] / this.el_box[0];
const mouse_dy = this.mouse_pos[1] / this.el_box[1];
this._zoom([dx, dy], [mouse_dx, mouse_dy]);
}
}
_zoom(deltas: number[], center: number[]) {
this.viewbox[2] += deltas[0];
this.viewbox[0] -= deltas[0] * center[0];
this.viewbox[2] = Math.min(this.viewbox[2], this.orig_viewbox[2]);
this.viewbox[3] += deltas[1];
this.viewbox[1] -= deltas[1] * center[1];
this.viewbox[3] = Math.min(this.viewbox[3], this.orig_viewbox[3]);
this._clip_viewbox();
}
get_viewbox(): number[] {
return this.viewbox;
}
get_mouse_pos(): number[] {
return this.mouse_pos;
}
}
export class Mesh {
cells: number[];
positions: number[];
constructor(mesh: any) {
this.cells = mesh.cells.flat();
this.positions = mesh.positions.flat();
}
}
export async function url_to_mesh(url: string): Promise<Mesh> {
return new Promise(function(resolve) {
fetch(url)
.then(resp => resp.text())
.then(data => {
// var div = document.createElement('div');
// div.innerHTML = data;
// var svg = div.querySelector('svg');
var svgPath = parsePath(data);
var mesh = svgMesh3d(svgPath, {
delaunay: false,
scale: 10,
});
resolve(new Mesh(mesh));
})
});
}

View file

@ -0,0 +1,115 @@
import type { VertexBuffer } from './buffer';
import type { Shader } from './shader';
export class VertexBufferElement {
type: number;
amount: number;
type_size: number;
normalized: boolean;
index: string;
constructor(
type: number,
amount: number,
type_size: number,
index: string,
normalized: boolean,
) {
this.type = type;
this.amount = amount;
this.type_size = type_size;
this.normalized = normalized;
this.index = index;
}
}
export class VertexBufferLayout {
elements: VertexBufferElement[];
stride: number;
offset: number;
constructor(offset = 0) {
this.elements = [];
this.stride = 0;
this.offset = offset;
}
// Maybe wrong normalized type
push(
type: number,
amount: number,
type_size: number,
index: string,
normalized = false,
) {
this.elements.push(new VertexBufferElement(type, amount, type_size, index, normalized));
this.stride += amount * type_size;
}
getElements(): VertexBufferElement[] {
return this.elements;
}
getStride(): number {
return this.stride;
}
}
// glEnableVertexAttribArray is to specify what location of the current program the follow data is needed
// glVertexAttribPointer tells gl that that data is at which location in the supplied data
export class VertexArray {
// There is no renderer ID, always at bind buffers and use glVertexAttribPointer
buffers: VertexBuffer[];
layouts: VertexBufferLayout[];
constructor() {
this.buffers = [];
this.layouts = [];
}
addBuffer(vb: VertexBuffer, layout: VertexBufferLayout) {
this.buffers.push(vb);
this.layouts.push(layout);
}
updateBuffer(gl: WebGLRenderingContext, index: number, data: number[]) {
this.buffers[index].updateData(gl, data);
}
/// Bind buffers providing program data
bind(gl: WebGLRenderingContext, shader: Shader) {
shader.bind(gl);
for(let i = 0; i < this.buffers.length; i ++) {
const buffer = this.buffers[i];
const layout = this.layouts[i];
buffer.bind(gl);
const elements = layout.getElements();
let offset = layout.offset;
for (let j = 0; j < elements.length; j ++) {
const element = elements[j];
const location = shader.getAttribLocation(gl, element.index);
if (location >= 0) {
gl.enableVertexAttribArray(location);
gl.vertexAttribPointer(
location, element.amount, element.type,
element.normalized, layout.stride, offset
);
}
offset += element.amount * element.type_size;
}
}
}
/// Undo bind operation
unbind(gl: WebGLRenderingContext) {
this.layouts.forEach((layout) => {
layout.getElements().forEach((_, index) => {
gl.disableVertexAttribArray(index);
});
})
}
}

View file

@ -0,0 +1,9 @@
import App from './App.svelte'
import load_wasm_module from "planetwars-rs";
load_wasm_module().then(() => {
const app = new App({
target: document.getElementById('app')
})
});

2
web/pw-frontend/src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />

View file

@ -0,0 +1,7 @@
import sveltePreprocess from 'svelte-preprocess'
export default {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: sveltePreprocess()
}

View file

@ -0,0 +1,20 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"resolveJsonModule": true,
"baseUrl": ".",
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": false,
"checkJs": false
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
}

View file

@ -0,0 +1,12 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import nodePolyfills from 'rollup-plugin-polyfill-node'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
svelte(),
nodePolyfills()
],
})