Browse Source

initial commit

master
Fr3deric 5 years ago
commit
ea65fc493b
  1. 74
      chaostest/chaostest.html
  2. 49
      chaostest/chaostest2.html
  3. 115
      chaostest/chaostest3.html
  4. 203
      lindenmayer-system/lindenmeyer-system.html
  5. 106
      lindenmayer-system/lindenmeyer-system.js
  6. 41
      paperjs_sketches.md

74
chaostest/chaostest.html

@ -0,0 +1,74 @@
<title>JavaScript <=> PaperScript example</title>
<code mode="text/html">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/paperscript" canvas="canvas">
var xstart = Math.random();
var ystart = Math.random();
var scale = 500;
var num_steps = 10;
var num_lines = 5;
var lines = [];
for(var i=0; i<num_lines; i++) {
var x = xstart + i*0.0001;
var y = ystart + i*0.0001;
var path = new Path({strokeWidth: 1, strokeColor: 'black'});
for(var s=0; s<num_steps; s++) {
x = (4*x*(1-x)) % 1;
y = (x+y) % 1;
var p = new Point(x*scale, y*scale);
path.add(p);
//console.log(p);
}
lines.push(path);
}
globals.get_svg = function() {
return project.exportSVG({asString: true});
}
</script>
<script type="text/javascript">
//document.addEventListener('DOMContentLoaded', function() {
window.globals = {}
window.onload = function() {
/*
draw();
document.getElementById('redraw').addEventListener('click', function() {
draw();
});
*/
paper.install(window);
console.log(window.globals);
document.getElementById('download-svg').addEventListener('click', function() {
var svgdata = 'data:image/svg+xml;utf8,' + encodeURIComponent(window.globals.get_svg());
var a = document.createElement('a');
a.download = 'export.svg';
a.href = svgdata;
document.body.appendChild(a);
a.click();
});
}
</script>
</head>
<body>
<button id="download-svg">download svg</button>
<canvas id="canvas" style="width: 500px; height: 500px;" resize></canvas>
</body>
</html>

49
chaostest/chaostest2.html

@ -0,0 +1,49 @@
<title>JavaScript <=> PaperScript example</title>
<code mode="text/html">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/paperscript" canvas="myCanvas">
var nx = 3;
var ny = 3;
var scale = 170;
var space = 30;
var num_steps = 10;
var num_lines = 5;
for(var xx=0; xx<nx; xx++) {
for(var yy=0; yy<nx; yy++) {
var xstart = Math.random();
var ystart = Math.random();
var lines = [];
for(var i=0; i<num_lines; i++) {
var x = xstart + i*0.0001;
var y = ystart + i*0.0001;
var path = new Path({strokeWidth: 1, strokeColor: 'black'});
for(var s=0; s<num_steps; s++) {
x = (4*x*(1-x)) % 1;
y = (x+y) % 1;
var p = new Point(x*scale + xx*(scale+space), y*scale + yy*(scale+space));
path.add(p);
console.log(p);
}
lines.push(path);
}
}
}
</script>
</head>
<body>
<canvas id="myCanvas" style="width: 600px; height: 600px;" resize></canvas>
</body>
</html>

115
chaostest/chaostest3.html

@ -0,0 +1,115 @@
<title>JavaScript <=> PaperScript example</title>
<code mode="text/html">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/paperscript" canvas="canvas">
var xstart = Math.random();
var ystart = Math.random();
//var xstart = 0.976119763841021;
//var ystart = 0.06095897568349018;
//var xstart = 0.981709002734148;
//var ystart = 0.7482912451397156;
//var xstart = 0.01408766142248663
//var ystart = 0.5826524694499656;
var scale = 500;
var num_steps = 7;
var fac = 0.0005;
var num_steps = 5;
var fac = 0.05;
var lines = [];
for(var i=0; i<2; i++) {
var x = xstart + i*fac;
var y = ystart + i*fac;
var path = new Path({strokeWidth: 1, strokeColor: 'black'});
for(var s=0; s<num_steps; s++) {
x = (4*x*(1-x)) % 1;
y = (x+y) % 1;
var p = new Point(x*scale, y*scale);
path.add(p);
console.log(p);
}
lines.push(path);
}
lines[0].strokeWidth = 5;
lines[1].strokeWidth = 0;
//lines[1].fullySelected = true;
for(var i=0; i<num_steps-1; i++) {
var o0start = lines[0].getOffsetOf(lines[0].segments[i].point);
var o0end = lines[0].getOffsetOf(lines[0].segments[i+1].point);
var o1start = lines[1].getOffsetOf(lines[1].segments[i].point);
var o1end = lines[1].getOffsetOf(lines[1].segments[i+1].point);
var num_steps2_0 = (o0end - o0start) / 7;
var num_steps2_1 = (o1end - o1start) / 7;
var num_steps2 = Math.min(num_steps2_0, num_steps2_1);
console.log(num_steps2);
for(var j=0; j<num_steps2; j++) {
var p0 = lines[0].getPointAt(o0start + (o0end-o0start) * (j/num_steps2));
var p1 = lines[1].getPointAt(o1start + (o1end-o1start) * (j/num_steps2));
var path = new Path.Line({
from: p0, to: p1,
strokeWidth: 2,
strokeColor: 'black'
});
if(path.length < 5) {
path.removeSegments();
delete path;
}
}
}
globals.get_svg = function() {
return project.exportSVG({asString: true});
}
console.log("start: ", xstart, ystart);
</script>
<script type="text/javascript">
//document.addEventListener('DOMContentLoaded', function() {
window.globals = {}
window.onload = function() {
/*
draw();
document.getElementById('redraw').addEventListener('click', function() {
draw();
});
*/
paper.install(window);
console.log(window.globals);
document.getElementById('download-svg').addEventListener('click', function() {
var svgdata = 'data:image/svg+xml;utf8,' + encodeURIComponent(window.globals.get_svg());
var a = document.createElement('a');
a.download = 'export.svg';
a.href = svgdata;
document.body.appendChild(a);
a.click();
});
}
</script>
</head>
<body>
<button id="download-svg">download svg</button>
<canvas id="canvas" style="width: 500px; height: 500px;" resize></canvas>
</body>
</html>

203
lindenmayer-system/lindenmeyer-system.html

@ -0,0 +1,203 @@
<title>JavaScript <=> PaperScript example</title>
<code mode="text/html">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="paper.js"></script>
<script type="text/javascript">
var ppp = new paper.Path();
</script>
<script type="text/javascript" src="lindenmeyer-system.js" canvas="canvas"></script>
<script type="text/paperscript" canvas="canvas">
/*
var r = generate('A'.split(''),
[
['A'.split(''), 'AB'.split('')],
//['x'.split(''), 'X'.split('')],
//['B'.split(''), 'C'.split('')]
['B'.split(''), 'A'.split('')]
]
, 4);
*/
/************************************************
* Dragon Curve
************************************************/
function dragon_curve(variant) {
project.clear();
var r = generate(
'FX'.split(''),
[
['X'.split(''), 'X+YF+'.split('')],
['Y'.split(''), '-FX-Y'.split('')]
],
12
);
if(variant == 'random-angles') {
var actions = {
'F': draw_forward(),
'-': draw_turn(-Math.PI/2.23+Math.random()),
'+': draw_turn(Math.PI/2.42+Math.random())
};
} else {
var actions = {
'F': draw_forward(),
'-': draw_turn(-Math.PI/2),
'+': draw_turn(Math.PI/2),
};
}
var p = draw(r, actions);
if(variant == 'random-angles') {
p.scale(4);
} else {
p.scale(3);
}
p.translate(new Point(200, 200));
p.strokeWidth = 1;
p.strokeColor = '#ff00ff';
}
/************************************************
* Sierpinski Triangle
************************************************/
function sierpinski2(num_defects) {
project.clear();
if(typeof num_defects == 'undefined') { num_defects = 0 };
var r = generate(
'IA'.split(''),
[
['A'.split(''), 'B-A-B'.split('')],
['B'.split(''), 'A+B+A'.split('')]
],
8
);
for(var i=0; i<num_defects; i++) {
r[Math.floor(Math.random()*r.length)] = '*';
}
var actions = {
'A': draw_forward(),
'B': draw_forward(),
'I': draw_angle_init(Math.PI/3),
'-': draw_angle_turn(-1),
'+': draw_angle_turn(1),
'*': draw_angle_add(0.001),
};
var p = draw(r, actions);
p.scale(1.5);
p.translate(new Point(150, 150));
p.strokeWidth = 1;
p.strokeColor = '#ff00ff';
}
/************************************************
* Sierpinski Triangle
************************************************/
function sierpinski() {
project.clear();
var r = generate(
'IF-G-G'.split(''),
[
['F'.split(''), 'F-G+F+G-F'.split('')],
['G'.split(''), 'GG'.split('')]
],
6
);
var p = draw(
r,
{
'F': draw_forward(),
'G': draw_forward(),
'I': draw_angle_init(2*Math.PI/3),
'-': draw_angle_turn(-1),
'+': draw_angle_turn(1),
}
);
p.scale(5);
p.translate(new Point(200, 200));
p.strokeWidth = 1;
p.strokeColor = '#ff00ff';
}
/************************************************
*
************************************************/
globals.dragon_curve = dragon_curve;
globals.sierpinski2 = sierpinski2;
globals.sierpinski = sierpinski;
globals.get_svg = function() {
return project.exportSVG({asString: true});
}
</script>
<script type="text/javascript">
//document.addEventListener('DOMContentLoaded', function() {
window.globals = {}
window.onload = function() {
/*
draw();
document.getElementById('redraw').addEventListener('click', function() {
draw();
});
*/
paper.install(window);
console.log(window.globals);
document.getElementById('download-svg').addEventListener('click', function() {
var svgdata = 'data:image/svg+xml;utf8,' + encodeURIComponent(window.globals.get_svg());
var a = document.createElement('a');
a.download = 'export.svg';
a.href = svgdata;
document.body.appendChild(a);
a.click();
});
document.getElementById('dragon-curve').addEventListener('click', function() {
window.globals.dragon_curve();
});
document.getElementById('dragon-curve-random-angles').addEventListener('click', function() {
window.globals.dragon_curve('random-angles');
});
document.getElementById('sierpinski2').addEventListener('click', function() {
window.globals.sierpinski2(0);
});
document.getElementById('sierpinski2-defects').addEventListener('click', function() {
window.globals.sierpinski2(10);
});
document.getElementById('sierpinski').addEventListener('click', function() {
window.globals.sierpinski();
});
}
</script>
</head>
<body>
<button id="download-svg">download svg</button>
<button id="dragon-curve">dragon curve</button>
<button id="dragon-curve-random-angles">dragon curve (random angles)</button>
<button id="sierpinski2">sierpinski2</button>
<button id="sierpinski2-defects">sierpinski2 (random defects)</button>
<button id="sierpinski">sierpinski</button>
<hr>
<canvas id="canvas" style="width: 500px; height: 500px;" resize></canvas>
</body>
</html>

106
lindenmayer-system/lindenmeyer-system.js

@ -0,0 +1,106 @@
function startswith(a, b) {
for(let i=0; i<b.length; i++) {
// in JS, ['X'] == 'X'
if((a[i] != b[i]) | (typeof a[i] != typeof b[i])) {
return false;
}
}
return true;
}
function generate(start, rules, iterations) {
if(iterations == 0) {
return start;
}
for(let rule of rules) {
let pos = 0;
while(pos < start.length) {
let w = start.slice(pos, pos + rule[0].length);
if(startswith(w, rule[0])) {
start.splice(pos, rule[0].length, rule[1])
pos += rule[0].length;
} else {
pos += 1;
}
}
}
// TODO find a better way
let ret = [];
for(let x of start) {
if(typeof x === 'object') {
// TODO why?
//ret.concat(x);
ret = ret.concat(x);
} else {
ret.push(x);
}
}
return generate(ret, rules, iterations - 1);
}
function draw_initstate(state) {
if(!('dir' in state)) {
state.dir = 0;//Math.PI/2;
}
}
function draw_forward() {
return function(p, state) {
draw_initstate(state);
if(p.length == 0) {
p.add(new paper.Point(0, 0));
}
var lastp = p.segments[p.segments.length - 1].point;
p.add(lastp.add(
new paper.Point(Math.sin(state.dir), Math.cos(state.dir))
));
}
}
function draw_turn(angle) {
return function(p, state) {
draw_initstate(state);
state.dir += angle;
}
}
function draw_angle_turn(fac) {
return function(p, state) {
draw_initstate(state);
state.dir += state.angle * fac;
}
}
function draw_angle_init(angle) {
return function(p, state) {
state.angle = angle;
}
}
function draw_angle_add(delta) {
return function(p, state) {
state.angle += delta;
}
}
function draw(word, actions) {
var p = new paper.Path();
var state = {};
for(let w of word) {
if(w in actions) {
actions[w](p, state);
}
}
return p;
}

41
paperjs_sketches.md

@ -0,0 +1,41 @@
## Color
* [7x7 randomly rotated squares](http://sketch.paperjs.org/#V/0.11.8/S/jVJNb8IwDP0rVqeJFEqbdWNDsJ52njSNAwfgEEoKFSWZ0gzaIf777CLU8jFpziF23nP87GTvKLGRzsAZraWNV47nxHpB8VYYUN8biOBlOFUU5emPxLDHMT6ezJcYK7mDD2FX/qeMrVDLTLIJ94DPPNimcudTmosp86WfpFn2pjNtMK119xjSalW3JdowurGM+BDKVyyMW6fjwn6qAO2EF4QXR7xo4GSEm9uCahJZRdCpsqxoV011qt6C0IPy/MD1rjNHiDCCvYrk1gzq8uQbP48FVub+c+/83GgrrGTvpNAItdAb5kIbxwpdCC+4uTV6Lcfpwq6wsUpaAA8cGqTaSxNW3ocQRRzHcg03b6wfgfO4nySt4SXPorQ8I6H1tLrVUJ7wbd2mzAPILJfNlyALglvFkiTuXxe75BGL8/+J+kPT0cXtQN8Lv/XcSLH+opTcGUxmh18=)
* [stars](http://sketch.paperjs.org/#V/0.11.8/S/rVJLT8JAEP4rk3roVjbNQq0kPA7Gs4mRI3DYtltoKLvN7gJRwn93tlJZ0XgwzmUy3zy+eR0DybciGAWzjbD5OqBBrgpn77kGudvCFAZsvJDONNWbQDtlDviAshUCUhzgmdt1/CJyy+WqFmTOKLAlhX0lDrHLizAlW8VlVdePqlYa08Kb/pANk/uwrbaQpdLE1aymbAzVBMlR9XoRHBcSUJyv6ehUJS15cqSay0JtSQS3bYMUfkIdfVfD+C3PLNekOSeVtcIervPvoAdJRCGh0GddIRMbq9VGXIYpW3HDnPxpeJa7eVBNBq26ngjZvIZIR+Dwbxy8ldAPKbhZP2jNXzFgntJ06TvzWhlRoMfqnTg7rtacfF3yfy36swVeFKTx0b+cIMUTDPAEKZ4g9Yv9doZLjP91/hOeg/BeJ3z8TAu+ady8JhjNl6d3)
* [triangles](http://sketch.paperjs.org/#V/0.11.8/S/lVNRb4IwEP4rF/ZgUcRGssyoPO15ybI9qg8FilaxJQV1zvjfd60ioA/bjqTX3tev912vnBzJttwZO58bXsYrx3NilZj1nmmQuy2EEFA6mUuzLsQ3x8DzLVBqcY1ZN4AXBC5QtMSo5Ad4Z+XK/+BxyeQy42RGPaALD/aCH3zDcpESLf1UZNmrypRGWucpGJqvY09LlSbmxHVIJ7CeDnHo9Vw4zSWgVagwqJiiZHQN3NhVakMQMVkrGCE/zlTBE9xR6h23aZvkvKIqIUtSY8beTH25OhA70UwmaktcL3C7pjoP/rO73tvUJ1KyDkPaKqnSXZRabXh9cfEoTSntNNhn4FnB77ntii5KbTegD/nk9zwmSzxq5amnVU9YFJuuoJsG1t31xQrxv/BAM/agdSfd6nH1q2c2wNbfk4+WfPwT+bEqliQkdx+LQHfGXyHSnG1yc0OFM54tzj8=)
* [fire](http://sketch.paperjs.org/#V/0.11.8/S/jVJNc4IwEP0rO/RAQIoZrNMZP3rpuTOdelQPISbKiEkbUKGO/71ZhBGLM+1yCHn79m32JSdHsZ1wRs5sK3K+cQKH6xXuD8yA2u9gCtFwvFC4zZJvYfdDSmtAS5lVQEP4qimkWh8h8pHiQR+lLOlCi9eWosQR3lm+CT8Ez5lap4LMaQB0GcAhEccQFTxbEq9DmaTpq061sWXuwyDCz63UpDYEFYspHUMxwSZQ9HoenBYKbDT5EvPlJV+28hiJJG94DsPUSu+IBy9Q9i3zhoTBtcoTtRfjK3y+/mIbc3+uW5mKoBOVk8q+HhT+xbcAaqCsAS/oVs4sThp+TbuyvNbZTJhxZrvT8NmrzGoNXMIEb6Qf2W43w/uDztjml/9SMkqp23YBRJqJRnfgo/JTR3n4D2Uh7ir/WScl5273Xuxyti86NoJtP9HyzBnNl+cf)
## Greyscale
need 7 or 9
* [7x7 randomly rotated squares](http://sketch.paperjs.org/#V/0.11.8/S/jVJRT8IwEP4rlxlDCwMqEU2Ye/LZxOiDD+JDHZ0sjNa0VTcJ/927DrIBmngvvbvva7+v124iLdcqmkWPK+WzZRRHmVlQ/Skt6I81pHCdzDVVrvhWWE6F2DVMnjtsTPa13TFYWIcw6RODw5gOQs5c58YyYtapSKC+oTbUgwGHzVwDxh6vCK8avOrgFEEJVbT6gnvpl6MHlXmp30rFWhJFIJhCe1b1G2uDYDmG+qDm8em+R4RZIMXNtXjL4Umb25HLJCqL0dX0sG+Nl16xO3JopV6YNePQx+nRYI64zluzUk/Fwi/xYo23MVwI6LDarMhZfT6BNBU4l1O4e+StKQ3NqncmQvSSY55Hb64kp+24hsHB+DIGwbtGt6BKp7pv8buWDPE/rb+kmhSXLf0b/JavVsnVO+1x0ez5ZfsD)
* [stars](http://sketch.paperjs.org/#V/0.11.8/S/rVI9b4MwEP0rJ3eIKSiiUC8hGarOlSplDBkcbAQCbGSTVm3Ef+8ZhUCjKEPVW0539/zu4/lEFG8kWZFtJbusIAHJtHDxBzegjg1sIAqTVLnQlt8SYxa6RKpybahLl5swgXKNYHS+78EpVYDmai3ilfyEd12qjr7xrlgaroRuqAePA2EAt7JeMnHYkcPhth03tD0/ymuNM1y/fwYfYi+AOICncCSyS9sZXclXXWuDhIuHcLAF1vv5NvyQuX3QraPBXW+E3WYD0bGBy9/pcYEIbosXY/gXAnYsYPt5Mau1lQIrnTnKc+HqzPHvI//XoS8jcCFoO8/+RQKGEkQoAUMJ2JzsngwTJi/rekLkg40IFKvHX3owkletW9aS1W7f/wA=)
* [supernova](http://sketch.paperjs.org/#V/0.11.8/S/pZBNC8IwDIb/SqgHu62W4hDRuZNnQfDoPNSu4phrS1cUFP+76/waoidzKcmbPH2TC1K8kmiKVqV0Yo8IEjr3+ZFbqIuzTGHEWJKpTPmKkMpJCykoeYKlLpTDC+721HKV6woHELZDBL5VgzfmSfBdK8ctvoMJTAgMCYx9q6C1s7qUc33Q/st+j7XRbzE7bbFHFSlLoJjFcdw8URTAJVPQhNfMH0ZfDNfxip+KcZTnOTafefRYZGCCkNFhR/69y7U5+tZKXhpvs0bT9eZ6Aw==)
* [random walks](http://sketch.paperjs.org/#V/0.11.8/S/pVKxboMwEP2Vk6sqpqTEQeoSoEvnSpU6lg4OOIpFsJFx2tCIf6+PgEQDmXqLfXfvPT+ffSaKl4JsyHshbLYnS5LpHPMvbqCWPwISeGIsShUW1LF0eYhpqnbaUCzybZawCJfY9buN73twThW4QERlHUuJb3jjdk+96NKpbFBbowvxog/aOMTijnWx6AEjgYGvpbL01akEhqtcl9R7QJNLmNaGYwabEk3KOGTgX6HX2BhZ7s3xPKfVoIIhd1Teh5AkwP5gO3xwAj/phfVR5TMuV2sGj91QVyEbC7cgDrWYSjb/kByPsDePHp+TDu1N3V8a0RWjuclobjBOELv5zOmzqfgctBlB3TVa9ye3RvCiwsevyebjs/0F)
* [triangles](http://sketch.paperjs.org/#V/0.11.8/S/lVJLb4MwDP4rFjs0FErRUDWpwGnnSZN2HDukkKq8EhTSdV3Ff5+TlfHoYZsPdpLPnx+xLxanNbO21kvJVHqwXCsVmb6/Uwn8WEMMge+HCdf3Nv9k+LD5eVAyv74Zs4YHBBK+F5JouIj9EIroHpXj2HBJOKD0aK7RPMIkaEa4lmtwDMzZCZ6pOhA7HGCEvLQSLcvQQ8kjM2nH5KanipwrMmBanjCc14gTMQdJeSZqYruBvdRduPAf78F3XF++J0Uc+5OW+rpbJUXJHkUlJNa4uKNGFiN2B6xq2Zw77ei7Uq1tWEET/p7HNzLJMxz7mdBdqqeCJgqMmc3FFOJ9YECtHZj8ybJfh1W/GGsc/Zx8NuTzn8i3XdEsI4192wSaDpd3JxktG/1DrbV9feu+AA==)
* [two rays](http://sketch.paperjs.org/#V/0.11.8/S/tZI/b8IwEMW/yskdkpBADYiFPxMrA1JH6OASR1gJdmQbkEB8d+4cLMHQTsWL9c6/e3dP8pVpcZBsyr5q6Xd7VrCdKUmfhAWnLhIWMOF8ttVUMFXlsDCMulTOox5HrY8HlGno68OoR3wGnx2XwxCxDmydF5ZatTzD2ijtU2KLMCF7uLVSly/Iw7cjnwQ1VMam1KQWfAZqjpvglecZXLca8ATDEdoF1/6TKy3XU1AAJ5/INnGy8PvBSmmZdjsX6BK5ZuC8NbVcmsZY5JMPHk6C7zeK+mvYlyR/Zv6HsPn7w+K/+bFS1C0NcWy6+b7dAQ==)
* [fire](http://sketch.paperjs.org/#V/0.11.8/S/pZJRT4MwEMe/ygUf1gIywiQmY/PFZxPjHsWHyoojY60WpuDCd7dXIDBJ1MR7afu/X+/+VzhZgh24tbQ2e14mO8u1ErnF8ztTII4HWEMQRrHAY5F9cn0Ofb8TZJoWRuiBtw4hZr2EwEaEwhxLaSgWqVQE0WrtR1CtUIbKcSicYgE6+nyN+brN16M8RpaSO1buPMXEVh4IhRuo55o8gzASKcpMHHk0yM2wxTZKmxX8A+6x3gNPSiZeck7OyxhAZqIkZmAHKrud1IVOqDuButObG62Tnu+wgaIjb8orEqa7+941NY81GriGFb7hPNDdzoa3F5OxlZdmeX4rc4njzS58E7PoO1WUSu75T1wDPC94339ho4OriYPwVwfMxD8cTOr/4Wa71Uuj/+pnxdn+FT9iYS0fn5ov)
* [curves](http://sketch.paperjs.org/#V/0.11.8/S/fZHNUsMgFIVf5Q4uGhpiMeqmaVe+gDNdGhdYiGGSQgaof52+u5cQndSFLJjh3HM+DsOJGHFQZE12nQr7ljCytzKe34QDr78UbOGe86o2UbBN41Eo4zkpgw/CBdSMeodHq03IoomN2VVJp+CgjLwwjegC/npr01iXxYTe8gr05ibueU7hVBvAFUetkf0H0n4g5TJiKKygrC5dn+i65Rxy0Ms7PhsOv5VFaDM6TYZwLaTMor5TrweFPdP7GJhj37NZ/7EDS5dQ+h8AXz4PFlOySNFEngN8cLZTD7a3Djsurvi4Fmg41wb/58Up0Q2R5cn66fn8DQ==)
* [cells](http://sketch.paperjs.org/#V/0.11.8/S/pVNNb4MwDP0rFjs0GYgCUlWpjF163aRJO647MJqqESFBgW6wtv99cToGVNW0D1+M/Z7jZ4fsHZkWzFk4jzmrs63jOZlaY/yaaqj4O4MEZkEQryQmMiaESURdLHeFCS1takGTX8mN0gTRNgliaG8MyTjXpbBfSTDW4Q3izQlvBjga35D7tN76OpVrVRAKtxD4c9oT0DIlay53zHbtknhyGRpZkr3Bg+KyJs01avOgtZ7GZ+Toh+SLmmZnmsrQb8BNum38trb9c230j77Rxb64HNHtBg+545KRMvRMwXAvwq9qrXK2VEJpw59cBdYm8bjNSBWxi0oSK5zC4QDEjn/KtHT0N3xd1VDNkutMMDJmofV3SRoXp/28UdL2EfXstNMwGNfTM82lv+FCfDfZ8fRp3NG8nhfN0rzE5pWzeHo+fgA=)
* [forest](http://sketch.paperjs.org/#V/0.11.8/S/lZNdb4IwFIb/ygm7sAhiQc0S0KvdbsmS7W7ugkEJRGxNYVNj+O/rqcOiwYS1SQs9z3s+etKTxeMts0LrbcPqJLdcKxEp/q85zkxI8hNLOK5oBMflTC2OY8PJWA5oOSx9XP9Maz6d3gh9IzS2VtpVnidad6KCFXC2h1dR8Jr4lIIDh/Ejbi9xnXsy5qnYEhvG4M+pC4EmjuOA2lHrRebKSdAnCWh0RpLcv8fMDBMoZtHHzFtmX6Q1RvMXfQlSk5IQ9bvYKRJLnHRKVDXI3I4M1l4AOnsuOCNK4bYOEMRPr6ql2LAnUQqpBKMHqsfoEjCRYs87rsipowiNwIWsKMvLaaaHOk1KUbE0hFp+swajFhm5rm8J1FvoDoIaOp4XpynpZNpruKpe35+L7bCHCaiGHdWbgYLJTYgGWFmxu2n3aunAWP/Eb2ppzu9AbY16kl+SxZsdcpUVfnw2vw==)
* [circles](http://sketch.paperjs.org/#V/0.11.8/S/rVTBbptAEP2VET1kiQnBWL2EECnqqYeqkXq0rWgLi1kZ71rD4kSN/O+dAWMojtoespK9zMybt+8Na795Ru6Ud+f92CqXlV7gZTbn+CARav1LQQqfoyhZGU6YZkdx3Ie1U3uK50Ms0bUNlFiZojGZ09ZAtrfaOIE+vK0M0ELlGjRg1As8taUuzeubdGVYayPah6evcA1In9gPJpjM1heYDuLT6UcWMJKwUeZZiqmAtr+orMWOCqXJ7Y5gRLbw4Za+ey72t2e3g2gez20cQLf7pyFYwrD/gkg51mmUgL6n0dE2m50lcE0SdrlOusRLqSslZFgps3El3MPijOUlw31Tl+JkxE9GFWKRYaErp1CIQ6DzVx/SB8ppk6vX74U4UJymwIVT37HbBilsjfzNRv6mI7EBXKR6PqZAohDdHZiBvubbMS4XaPn28BmnCyGX0ZpZcIRydoqZX2JKtM2mnALjM3CAZv0bY+GPmAlWEdApQc/SS8zC2qHdqi+2suzk6lPUrqtkOqpqxCn69uof7VUo81y8Y14g5Rb00M7L/w/4Dcyn8I8XFw/iLk77G/zmTy/nX+LK0H/LT1Ry27bU3t1yffwN)
* [trapezes](http://sketch.paperjs.org/#V/0.11.8/S/lZRLT8MwDMe/ilUO9MWaFnHgdUCcOCAhcdwmFNKMVeuSyU1BAvHdsfvYSsczVZU5+dn+29725hm51t6Zd7/STi292FM2Z/tZIlTFq4ZLOBHifGb4wNRrsk97s3J6Q3a6syW6xoEOZmZRG+UKa0BtbGGcjwG8zQzQQu1qNGD0C9w1V+0xr1vplpOqMH7z4e4GQkB6syAeMcpWe0yLBJT9nQUMJDxp8yD9sYDGf1Fai20olCa3a8JCKkoEkPDWR+MKN1zvTjY3KMliaPega4Mlhr0WFJbt4lKcQ3FBzaMtirYi+E5KgouEGxvBJw1Jm3oLEjeVMmaPCFL2SI47K2Nr3vS8x1kniY0GYscV2hj2joIuYxJyEKQgfjvUCIqQxx0MJC3Q8teBs3QTllMx5zg4oJwdM+k+s0RbPy3HYLYFd6jqB8DSr1D5rCKmLHEfpZeoJpVDu9LXtrRcyeGBaNZhdx8m7b6LjYKwvt5xb7phw1EDDPuA6b/cxlnLQUV+H7f8RXw5UaWtdE5XDmu9PZV57n81EBF8j2R/RtIfEDFA+Ol+gTND/ymPqOWqASvvbDp//wA=)
* [cells2](http://sketch.paperjs.org/#V/0.11.8/S/rVZLb5tAEP4rK6o2ENsE4vhiIJeceqhUqYcebCui7BJvTBbEo8GN/N87s7CYlx+VupZsMzsz+82342/8oQn/jWlL7ceO5cFWm2pBTPF5LX77Kcn4H0Y8srAspzIELIpqo61soniDR2m9axxgr9pNYi7yDBxWG7CFcaqjtfQsh5QuhMLHZGKQj7UgsNT+Hvf31f6+tY+rymgmRbbVBXsn3/FZL6dkbxhO5XZYiwMCCAsR5DwW5IXlz6mgzzJWb9KlLC9SoTJmScQDpn/z860ZRjFAkV9TX9D4DYJulWPExEu+NabENlYWliUPO1b3iuhf3XsLP2r0FRspENFJWnOYDCnimIS7C3xvMSAZZ2WegL8ooqiumId60iAjnkesDmcqoseDoouwKGNtfzyFKqzjXDyo6Pa9UYmacneO772LU4kjP5NgAPDqCHpmb5yhbyCRj2xQnvasQEFKXMtcDA7Flb1zaHBdpxPKjc8Poz64Ah+YsJaYHxlu+ovYUwKkOuRXyvydcybYHgbPrg6+HznZgmD7muD5ePDsXPBhaApUt1QXNRnhetgx/5Xnq6o9wfPZas/xPLv65DGeL518Jc9DL2hrvdadkAv6VVBW6iXxHkmJv3MVe4QCWUxQQ8swcB9AkS+jtfxbVugjTLxvsp68WawsFjkXBbvMg1TOtkFKHy1RHk7Dq5gzhgKAkY998VOrK/PgigI+AlFdy6j24Bq741Zdh2YI1ajqhF6l2B1s7VR1QHIcbnWR9YDparxL5p2xGbEcQkkcYgKjL+aB6lZU8SeeBhGDZCDjamBPj7P9rqvtgZnlabxjT3EUY9PffLLkuhnx+ckpjh9im4vWKO6IhRx3LTTNFEounJOcPON8+YnpUwrF3qoC+/8SGoK7L/gzJG+nahttudoc/gI=)
Loading…
Cancel
Save