# HG changeset patch # User Steve Losh # Date 1466870225 0 # Node ID 2d9281a1f7e7fc3d9e53f25e8d23be149fa62673 # Parent a52d61eb7e8503d968f09f35bac5b404033f7434 Finish the fucking diamond square entry already diff -r a52d61eb7e85 -r 2d9281a1f7e7 Makefile --- a/Makefile Mon Mar 07 13:44:20 2016 +0000 +++ b/Makefile Sat Jun 25 15:57:05 2016 +0000 @@ -22,7 +22,10 @@ cat $< | wisp > $@ media/js/terrain1.js: $(javascripts) - browserify media/js/wisp/terrain1.js -o $@ + browserify media/js/wisp/terrain1.js -do $@ media/js/terrain2.js: $(javascripts) - browserify media/js/wisp/terrain2.js -o $@ + browserify media/js/wisp/terrain2.js -do $@ + +media/js/terrain3.js: $(javascripts) + browserify media/js/wisp/terrain3.js -do $@ diff -r a52d61eb7e85 -r 2d9281a1f7e7 content/blog/2016/06/diamond-square.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/content/blog/2016/06/diamond-square.html Sat Jun 25 15:57:05 2016 +0000 @@ -0,0 +1,475 @@ + {% extends "_post.html" %} + + {% load mathjax %} + + {% hyde + title: "Terrain Generation with Diamond Square" + snip: "Improving on Midpoint Displacement." + created: 2016-06-27 13:45:00 + %} + + {% block extra_js %} + + + + {% endblock extra_js %} + + {% block article %} + +In the last two posts we looked at implementing the Midpoint Displacement +algorithm for procedurally generating terrain. Today we're going to look at +a similar algorithm called Diamond Square that fixes some problems with Midpoint +Displacement. + +The full series of posts so far: + +* [Midpoint Displacement](/blog/2016/02/midpoint-displacement/) +* [Recursive Midpoint Displacement](/blog/2016/03/recursive-midpoint-displacement/) +* [Diamond Square](/blog/2016/03/diamond-square/) + +Midpoint Displacement is fairly simple and pretty fast, but it suffers from some +flaws. If you look at the end result you'll probably start to notice "seams" in +the terrain that appear on perfectly square chunks. This happens because when +you're calculating the midpoints of the edges of each square you're only +averaging two sources. + +[Diamond Square][] is an algorithm that works a lot like Midpoint Displacement, +but it adds an extra step to ensure that (almost) every point uses *four* +sources of data. This reduces the visual artifacts a lot without much extra +effort. + +Let's [draw the owl][owl]. + +[Diamond Square]: https://en.wikipedia.org/wiki/Diamond-square_algorithm +[owl]: https://i.imgur.com/RadSf.jpg + +[TOC] + +## Overview + +The high-level description of Diamond Square goes something like this: + +1. Initialize the corners to random values. +2. Set the center of the heightmap to the average of the corners (plus jitter). +3. Set the midpoints of the edges of the heightmap to the average of the four + points on the "diamond" around them (plus jitter). +4. Repeat steps 2-4 on successively smaller chunks of the heightmap until you + bottom out at 3x3 chunks. + +## Initialization + +Initialization is pretty simple: + + :::clojure + (defn ds-init-corners [heightmap] + (let [last (heightmap-last-index heightmap)] + (heightmap-set! heightmap 0 0 (rand)) + (heightmap-set! heightmap 0 last (rand)) + (heightmap-set! heightmap last 0 (rand)) + (heightmap-set! heightmap last last (rand)))) + +Just set the corners to random values, exactly like we did in Midpoint +Displacement. + +
+ +## Square + +In the "square" step of Diamond Square, we take a square region of the heightmap +and set the center of it to the average of the four corners (plus jitter). + +
+           Column
+         0 1 2 3 4         0 1 2 3 4         0 1 2 3 4
+        ┌─┬─┬─┬─┬─┐       ┌─┬─┬─┬─┬─┐       ┌─┬─┬─┬─┬─┐
+      0 │1│ │ │ │8│     0 │1│ │ │ │8│     0 │1│ │ │ │8│
+        ├─┼─┼─┼─┼─┤       ├─╲─┼─┼─╱─┤       ├─╲─┼─┼─╱─┤
+      1 │ │ │ │ │ │     1 │ │╲│ │╱│ │     1 │ │╲│ │╱│ │
+    R   ├─┼─┼─┼─┼─┤       ├─┼─◢─◣─┼─┤       ├─┼─◢─◣─┼─┤
+    o 2 │ │ │◉│ │ │     2 │ │ │◉│ │ │     2 │ │ │3│ │ │
+    w   ├─┼─┼─┼─┼─┤       ├─┼─◥─◤─┼─┤       ├─┼─◥─◤─┼─┤
+      3 │ │ │ │ │ │     3 │ │╱│ │╲│ │     3 │ │╱│ │╲│ │
+        ├─┼─┼─┼─┼─┤       ├─╱─┼─┼─╲─┤       ├─╱─┼─┼─╲─┤
+      4 │0│ │ │ │3│     4 │0│ │ │ │3│     4 │0│ │ │ │3│
+        └─┴─┴─┴─┴─┘       └─┴─┴─┴─┴─┘       └─┴─┴─┴─┴─┘
+
+ +The Wikipedia article calls this the "diamond" step, but that seems backwards to +me. We're operating on a *square* region of the heightmap, so this should be +the *square* step. + +Since we're no longer working with heightmap "slices" like we were in the +previous post, we'll need a way to specify the square chunk of the heightmap +we're working on. I chose to use a center point (`x` and `y` coordinates) and +a radius: + + :::clojure + (defn ds-square [heightmap x y radius spread] + (let [new-height + (jitter + (average4 + (heightmap-get heightmap (- x radius) (- y radius)) + (heightmap-get heightmap (- x radius) (+ y radius)) + (heightmap-get heightmap (+ x radius) (- y radius)) + (heightmap-get heightmap (+ x radius) (+ y radius))) + spread)] + (heightmap-set! heightmap x y new-height))) + +
+ +## Diamond + +In the "diamond" step of Diamond Square, we take a diamond-shaped region and set +the center of it to the average of the four corners: + +
+               Column
+         0 1 2 3 4 5 6 7 8        0 1 2 3 4 5 6 7 8
+        ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐      ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐
+      0 │1│ │ │ │3│ │ │ │3│    0 │1│ │ │ │3│ │ │ │3│
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─╱─╲─┼─┼─┼─┤
+      1 │ │ │ │ │ │ │ │ │ │    1 │ │ │ │╱│ │╲│ │ │ │
+    R   ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─╱─┼─┼─╲─┼─┼─┤
+    o 2 │ │ │3│ │ │ │4│ │ │    2 │ │ │3│ │◉│ │4│ │ │
+    w   ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─╲─┼─┼─╱─┼─┼─┤
+      3 │ │ │ │ │ │ │ │ │ │    3 │ │ │ │╲│ │╱│ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─╲─╱─┼─┼─┼─┤
+      4 │5│ │ │ │5│ │ │ │5│    4 │5│ │ │ │5│ │ │ │5│
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      5 │ │ │ │ │ │ │ │ │ │    5 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      6 │ │ │7│ │ │ │6│ │ │    6 │ │ │7│ │ │ │6│ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      7 │ │ │ │ │ │ │ │ │ │    7 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      8 │9│ │ │ │7│ │ │ │7│    8 │9│ │ │ │7│ │ │ │7│
+        └─┴─┴─┴─┴─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┴─┴─┴─┴─┘
+
+               Column
+         0 1 2 3 4 5 6 7 8        0 1 2 3 4 5 6 7 8
+        ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐      ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐
+      0 │1│ │ │ │3│ │ │ │3│    0 │1│ │ │ │3│ │ │ │3│
+        ├─┼─┼─┼─╱┬╲─┼─┼─┼─┤      ├─┼─┼─┼─╱┬╲─┼─┼─┼─┤
+      1 │ │ │ │╱│││╲│ │ │ │    1 │ │ │ │╱│││╲│ │ │ │
+    R   ├─┼─┼─╱─┼▼┼─╲─┼─┼─┤      ├─┼─┼─╱─┼▼┼─╲─┼─┼─┤
+    o 2 │ │ │3├─▶◉◀─┤4│ │ │    2 │ │ │3├─▶4◀─┤4│ │ │
+    w   ├─┼─┼─╲─┼▲┼─╱─┼─┼─┤      ├─┼─┼─╲─┼▲┼─╱─┼─┼─┤
+      3 │ │ │ │╲│││╱│ │ │ │    3 │ │ │ │╲│││╱│ │ │ │
+        ├─┼─┼─┼─╲┴╱─┼─┼─┼─┤      ├─┼─┼─┼─╲┴╱─┼─┼─┼─┤
+      4 │5│ │ │ │5│ │ │ │5│    4 │5│ │ │ │5│ │ │ │5│
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      5 │ │ │ │ │ │ │ │ │ │    5 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      6 │ │ │7│ │ │ │6│ │ │    6 │ │ │7│ │ │ │6│ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      7 │ │ │ │ │ │ │ │ │ │    7 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      8 │9│ │ │ │7│ │ │ │7│    8 │9│ │ │ │7│ │ │ │7│
+        └─┴─┴─┴─┴─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┴─┴─┴─┴─┘
+
+ +First we define how do do a single diamond-shaped region. Once again we'll use +a center point and radius to specify the region inside the heightmap: + + :::clojure + (defn ds-diamond [heightmap x y radius spread] + (let [new-height + (jitter + (safe-average + (heightmap-get-safe heightmap (- x radius) y) + (heightmap-get-safe heightmap (+ x radius) y) + (heightmap-get-safe heightmap x (- y radius)) + (heightmap-get-safe heightmap x (+ y radius))) + spread)] + (heightmap-set! heightmap x y new-height))) + +
+ +## Edge Cases + +You might have noticed that we used `heightmap-get-safe` and `safe-average` in +the `ds-diamond` code. This is to handle the diamonds on the edge of the +heightmap. Those diamonds only have three points to average: + +
+           Column
+         0 1 2 3 4        0 1 2 3 4
+        ┌─┬─┬─┬─┬─┐      ┌─┬─┬─┬─┬─┐
+      0 │1│ │ │ │8│    0 │1│ │ │ │8│
+        ├─┼─┼─┼─┼─┤      ├─┼─┼─┼─╱┬╲
+      1 │ │ │ │ │ │    1 │ │ │ │╱│││╲
+    R   ├─┼─┼─┼─┼─┤      ├─┼─┼─╱─┼▼┤ ╲
+    o 2 │ │ │3│ │ │    2 │ │ │3├─▶◉◀──?
+    w   ├─┼─┼─┼─┼─┤      ├─┼─┼─╲─┼▲┤ ╱
+      3 │ │ │ │ │ │    3 │ │ │ │╲│││╱
+        ├─┼─┼─┼─┼─┤      ├─┼─┼─┼─╲┴╱
+      4 │0│ │ │ │3│    4 │0│ │ │ │3│
+        └─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┘
+
+ +So we just ignore the missing point: + + :::clojure + (defn safe-average [a b c d] + (let [total 0 count 0] + (when a (add! total a) (inc! count)) + (when b (add! total b) (inc! count)) + (when c (add! total c) (inc! count)) + (when d (add! total d) (inc! count)) + (/ total count))) + + (defn heightmap-get-safe [heightmap x y] + (let [last (heightmap-last-index heightmap)] + (when (and (<= 0 x last) + (<= 0 y last)) + (heightmap-get heightmap x y)))) + +Technically this means they have less information to work with than the rest of +the points, and you might see some slight artifacts. But in practice it's not +too bad, and it's a lot nicer than midpoint displacement where *every* line step +uses only *two* points. + +Another way to handle this is to also wrap those edge coordinates around and +pull the point from the other side of the heightmap. This is a bit more work +but gives you an extra benefit: the heightmap will be tileable. + +## Iteration + +Unfortunately we can't use recursion to iterate for diamond square like we did +for midpoint displacement. We have to interleave the diamond and square steps, +performing each round of squares on the *entire* map before moving on to a round +of diamonds. + +If we don't, bad things will happen. Let's look at an example to see why. +First we perform the initial square step: + +
+           Column
+         0 1 2 3 4        0 1 2 3 4
+        ┌─┬─┬─┬─┬─┐      ┌─┬─┬─┬─┬─┐
+      0 │1│ │ │ │8│    0 │1│ │ │ │8│
+        ├─┼─┼─┼─┼─┤      ├─╲─┼─┼─╱─┤
+      1 │ │ │ │ │ │    1 │ │╲│ │╱│ │
+    R   ├─┼─┼─┼─┼─┤      ├─┼─◢─◣─┼─┤
+    o 2 │ │ │ │ │ │    2 │ │ │3│ │ │
+    w   ├─┼─┼─┼─┼─┤      ├─┼─◥─◤─┼─┤
+      3 │ │ │ │ │ │    3 │ │╱│ │╲│ │
+        ├─┼─┼─┼─┼─┤      ├─╱─┼─┼─╲─┤
+      4 │0│ │ │ │3│    4 │0│ │ │ │3│
+        └─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┘
+
+ +That's fine. Then we recurse into the first of the four diamonds: + +
+           Column
+         0 1 2 3 4        0 1 2 3 4
+        ┌─┬─┬─┬─┬─┐      ┌─┬─┬─┬─┬─┐
+      0 │1│ │ │ │8│    0 │1├─▶4◀─┤8│
+        ├─┼─┼─┼─┼─┤      ├─╲─┼▲┼─╱─┤
+      1 │ │ │ │ │ │    1 │ │╲│││╱│ │
+    R   ├─┼─┼─┼─┼─┤      ├─┼─╲┴╱─┼─┤
+    o 2 │ │ │3│ │ │    2 │ │ │3│ │ │
+    w   ├─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┤
+      3 │ │ │ │ │ │    3 │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┤
+      4 │0│ │ │ │3│    4 │0│ │ │ │3│
+        └─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┘
+
+ +Everything's still good. Then we recurse into the square: + +
+            Column
+         0 1 2 3 4        0 1 2 3 4
+        ┌─┬─┬─┬─┬─┐      ╔═════╗─┬─┐
+      0 │1│ │4│ │8│    0 ║1│ │4║ │8│
+        ├─┼─┼─┼─┼─┤      ║─◢─◣─║─┼─┤
+      1 │ │ │ │ │ │    1 ║ │ │ ║ │ │
+    R   ├─┼─┼─┼─┼─┤      ║─◥─◤─║─┼─┤
+    o 2 │ │ │3│ │ │    2 ║?│ │3║ │ │
+    w   ├─┼─┼─┼─┼─┤      ╚═════╝─┼─┤
+      3 │ │ │ │ │ │    3 │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┤
+      4 │0│ │ │ │3│    4 │0│ │ │ │3│
+        └─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┘
+
+ +But wait, there's a corner missing! We needed to complete that left-hand +diamond step to get it, but that's still waiting on the stack for this line of +recursion to bottom out. + +### A "Strided" Iteration Construct + +So we need to use normal iteration. We can start by writing the code to do +a single round of diamonds or squares on the heightmap. First we'll make a nice +looping construct called `do-stride`: + + :::clojure + (defmacro do-stride + [varnames start-form end-form stride-form & body] + (let [stride (gensym "stride") + start (gensym "start") + end (gensym "end") + build (fn build [vars] + (if (empty? vars) + `(do ~@body) + (let [varname (first vars)] + `(loop [~varname ~start] + (when (< ~varname ~end) + ~(build (rest vars)) + (recur (+ ~varname ~stride)))))))] + ; Fix the numbers once outside the nested loops, + ; and then build the guts. + `(let [~start ~start-form + ~end ~end-form + ~stride ~stride-form] + ~(build varnames)))) + +This scary-looking macro builds the nested looping structure we'll need to +perform the iteration for our diamonds and squares. It abstracts away the +tedium of writing out nested `for` loops so we can focus on the rest of the +algorithm. + +`do-stride` takes a list of variables to bind, a number to start at, a number to +end before, and a body. For each variable it starts at `start`, runs `body`, +increments by `stride`, and loops until the value is at or above `end`. For +example: + +* `(do-stride [x] 0 5 1 (console.log x))` will log `0 1 2 3 4`. +* `(do-stride [x] 0 5 2 (console.log x))` will log `0 2 4`. +* `(do-stride [x y] 0 3 2 (console.log [x y]))` will log `[0, 0] [0, 2] [2, 0] + [2, 2]`. + +### Square Iteration + +Now that we've got this, we can iterate our square step over the heightmap for +a specific radius: + + :::clojure + (defn ds-squares [heightmap radius spread] + (do-stride [x y] radius (heightmap-resolution heightmap) (* 2 radius) + (ds-square heightmap x y radius spread))) + +We use `do-stride` to start at the radius and loop until we fall off the +heightmap, stepping by *twice* the radius each time. + +Because our heightmaps are always square we can use the same values for both +dimensions. `do-stride` can take zero or more variables and will just do the +right thing, so we don't need to worry about it. + +The stride is double the radius because as we step between squares we move over +the right half of the first *and* the left half of the next: + +
+               Column
+          0 1 2 3 4 5 6 7 8        0 1 2 3 4 5 6 7 8
+         ╔═════════╗─┬─┬─┬─┐      ╔═════════╗─┬─┬─┬─┐
+       0 ║1│ │ │ │3║ │ │ │3│    0 ║1│ │ │ │3║ │ │ │3│
+         ║─┼─┼─┼─┼─║─┼─┼─┼─┤      ║─┼─┼─┼─┼─║─┼─┼─┼─┤
+       1 ║ │ │ │ │ ║ │ │ │ │    1 ║ │ │ │ │ ║ │ │ │ │
+    R    ║─┼─┼─┼─┼─║─┼─┼─┼─┤     radius ┼─┼─║─┼─┼─┼─┤
+    o  2 ║ │ │◉│ │ ║ │◉│ │ │    2 ║◀━━▶◉◀━━━━━▶◉│ │ │
+    w    ║─┼─┼─┼─┼─║─┼─┼─┼─┤      ║─┼─┼─ stride ┼─┼─┤
+       3 ║ │ │ │ │ ║ │ │ │ │    3 ║ │ │ │ │ ║ │ │ │ │
+         ║─┼─┼─┼─┼─║─┼─┼─┼─┤      ║─┼─┼─┼─┼─║─┼─┼─┼─┤
+       4 ║5│ │ │ │5║ │ │ │5│    4 ║5│ │ │ │5║ │ │ │5│
+         ╚═════════╝─┼─┼─┼─┤      ╚═════════╝─┼─┼─┼─┤
+       5 │ │ │ │ │ │ │ │ │ │    5 │ │ │ │ │ │ │ │ │ │
+         ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+       6 │ │ │◉│ │ │ │◉│ │ │    6 │ │ │◉│ │ │ │◉│ │ │
+         ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+       7 │ │ │ │ │ │ │ │ │ │    7 │ │ │ │ │ │ │ │ │ │
+         ├─┼─┼─┼─┼─┼─┼─┼─┼─┤      ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+       8 │9│ │ │ │7│ │ │ │7│    8 │9│ │ │ │7│ │ │ │7│
+         └─┴─┴─┴─┴─┴─┴─┴─┴─┘      └─┴─┴─┴─┴─┴─┴─┴─┴─┘
+
+ +### Diamond Iteration + +The diamonds are a little more complicated. + +First of all, in the `y` dimension we need to start at `0` instead of `radius` +(these will be the top and bottom edge cases we looked at). Also, in the `x` +direction all the even iterations need to start at `radius`, while the odd +iterations should start at `0`. + +Hopefully a picture will make it a bit more clear: + +
+               Column
+         0 1 2 3 4 5 6 7 8
+        ┌─┬─┬─┬─┬─┬─┬─┬─┬─┐
+      0 │1│ │◉│ │3│ │◉│ │3│ y iteration: 0, start at x = radius
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      1 │ │ │ │ │ │ │ │ │ │
+    R   ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+    o 2 │◉│ │3│ │◉│ │4│ │◉│ y iteration: 1, start at x = 0
+    w   ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      3 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      4 │5│ │◉│ │5│ │◉│ │5│ y iteration: 2, start at x = radius
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      5 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      6 │◉│ │7│ │◉│ │6│ │◉│ y iteration: 3, start at x = 0
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      7 │ │ │ │ │ │ │ │ │ │
+        ├─┼─┼─┼─┼─┼─┼─┼─┼─┤
+      8 │9│ │◉│ │7│ │◉│ │7│ y iteration: 4, start at x = radius
+        └─┴─┴─┴─┴─┴─┴─┴─┴─┘
+
+ +The code for the diamonds is the hairiest bit of the algorithm. Make sure you +understand it before moving on. `shift` will be `radius` for even iterations +and `0` for odd ones: + + :::clojure + (defn ds-diamonds [heightmap radius spread] + (let [size (heightmap-resolution heightmap)] + (do-stride [y] 0 size radius + (let [shift (if (even? (/ y radius)) radius 0)] + (do-stride [x] shift size (* 2 radius) + (ds-diamond heightmap x y radius spread)))))) + +### Top-Level Iteration + +Finally we can put it all together. We initialize the corners and starting +values, then loop over smaller and smaller radii and just call `ds-squares` and +`ds-diamonds` to do the heavy lifting: + + :::clojure + (defn diamond-square [heightmap] + (let [initial-spread 0.3 + spread-reduction 0.5 + center (heightmap-center-index heightmap) + size (aget heightmap.shape 0)] + (ds-init-corners heightmap) + (loop [radius center + spread initial-spread] + (when (>= radius 1) + (ds-squares heightmap radius spread) + (ds-diamonds heightmap radius spread) + (recur (/ radius 2) + (* spread spread-reduction)))) + (sanitize heightmap))) + +## Result + +The end result looks like this: + +
+ +It looks a lot like the result from midpoint displacement, but without the ugly +seams around the square chunks. + +The code for these blog posts is a bit of a mess because I've been copy/pasting +to show the partially-completed demos after each step. I've created a little +[single-page demo][ymir] with completed versions of the various algorithms you +can play with, and [that code][ymir-code] should be a lot more readable than the +hacky code for these posts. + +[ymir]: http://ymir.stevelosh.com/ +[ymir-code]: http://bitbucket.org/sjl/ymir/ + + {% endblock article %} diff -r a52d61eb7e85 -r 2d9281a1f7e7 media/diamond-square.monopic Binary file media/diamond-square.monopic has changed diff -r a52d61eb7e85 -r 2d9281a1f7e7 media/js/terrain1.js --- a/media/js/terrain1.js Mon Mar 07 13:44:20 2016 +0000 +++ b/media/js/terrain1.js Sat Jun 25 15:57:05 2016 +0000 @@ -520,4 +520,5 @@ $(run); -},{}]},{},[1]); +},{}]},{},[1]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm1lZGlhL2pzL3dpc3AvYW5vbnltb3VzLndpc3AiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNDQSxJQUFLLEtBQUEsR0FBQSxPQUFBLENBQUEsS0FBQSxHQUFNLEdBQVg7QUFDQSxJQUFLLE1BQUEsR0FBQSxPQUFBLENBQUEsTUFBQSxHQUFPLEdBQVosQ0FEQTtBQUVBLElBQUssU0FBQSxHQUFBLE9BQUEsQ0FBQSxTQUFBLEcsSUFBTCxDQUZBO0FBR0EsSUFBSyxjQUFBLEdBQUEsT0FBQSxDQUFBLGNBQUEsR0FBZ0IsR0FBckIsQ0FIQTtBQUlBLElBQUssYUFBQSxHQUFBLE9BQUEsQ0FBQSxhQUFBLEdBQWUsRUFBcEIsQ0FKQTtBQUtBLElBQUssV0FBQSxHQUFBLE9BQUEsQ0FBQSxXQUFBLEdBQWEsR0FBbEIsQ0FMQTtPQUFBO09BQUE7T0FBQTtPQUFBO09BQUE7T0FBQTtBQTJDQSxJQUFNLENBQUEsR0FBQSxPQUFBLENBQUEsQ0FBQSxHQUFOLFNBQU0sQ0FBTixDQUFTLENBQVQsRUFDRTtBQUFBLFdBQUMsT0FBQSxDQUFRLEdBQVQsQ0FBYSxDQUFiO0FBQUEsQ0FERixDQTNDQTtBQStDQSxJQUFNLFFBQUEsR0FBQSxPQUFBLENBQUEsUUFBQSxHQUFOLFNBQU0sUUFBTixDQUFnQixDQUFoQixFQUFrQixDQUFsQixFQUNFO0FBQUEsV0FBRyxDQUFHLENBQUgsR0FBSyxDQUFMLENBQUgsR0FBVyxDQUFYO0FBQUEsQ0FERixDQS9DQTtBQWtEQSxJQUFNLFFBQUEsR0FBQSxPQUFBLENBQUEsUUFBQSxHQUFOLFNBQU0sUUFBTixDQUFnQixDQUFoQixFQUFrQixDQUFsQixFQUNFO0FBQUEsV0FBRyxDQUFHLENBQUgsR0FBSyxDQUFMLENBQUgsR0FBVyxDQUFYO0FBQUEsQ0FERixDQWxEQTtB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T0FBbEIsRUFGSTtBQUFBLFlBR0osT0FBQyxRQUFBLENBQVMsTUFBVixDQUFpQixLQUFqQixFQUF1QixNQUF2QixFQUhJO0FBQUEsUyxLQUFOLEMsSUFBQTtBQUFBLEtBREYsQztJQU1DLE1BQUQsRzs7Q0FyQ0YsQ0E3VUE7QUF1WEEsSUFBTSxHQUFBLEdBQUEsT0FBQSxDQUFBLEdBQUEsR0FBTixTQUFNLEdBQU4sR0FDRTtBQUFBLElBQUMsUUFBRCxDQUFXLGFBQVgsRUFBeUIsV0FBekIsRUFBc0MsQ0FBdEM7QUFBQSxJQUNDLFFBQUQsQ0FBVyxZQUFYLEVBQXdCLHNCQUF4QixFQUFpRCxDQUFqRCxFQURBO0FBQUEsSUFFQyxRQUFELENBQVcsWUFBWCxFQUF3QixzQkFBeEIsRUFBaUQsQ0FBakQsRUFGQTtBQUFBLElBR0MsUUFBRCxDQUFXLFlBQVgsRUFBd0Isc0JBQXhCLEVBQWlELENBQWpELEVBSEE7QUFBQSxJQUlDLFFBQUQsQ0FBVyxZQUFYLEVBQXdCLG9CQUF4QixFQUE4QyxDQUE5QyxFQUpBO0FBQUEsSUFLQSxPQUFDLFNBQUQsQ0FBWSxZQUFaLEVBTEE7QUFBQSxDQURGLENBdlhBO0FBbVlDLENBQUQsQ0FBRyxHQUFIIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIjsgQ29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWYgd2lkdGggNjEwKVxuKGRlZiBoZWlnaHQgNDAwKVxuKGRlZiB3aXJlZnJhbWUgdHJ1ZSlcbihkZWYgd2lyZWZyYW1lLXdpZHRoIDEuMilcbihkZWYgdGVycmFpbi1oZWlnaHQgNTApXG4oZGVmIHRlcnJhaW4tc2l6ZSAxMDApXG5cbjsgR2VuZXJhbCBVdGlsaXRpZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZtYWNybyB3aGVuIFtjb25kaXRpb24gJiBib2R5XVxuICBgKGlmIH5jb25kaXRpb25cbiAgICAgKGRvIH5AYm9keSkpKVxuXG4oZGVmbWFjcm8gZG8tdGltZXMgW3Zhcm5hbWUgbGltaXQgJiBib2R5XVxuICAobGV0IFtlbmQgKGdlbnN5bSldXG4gICAgYChsZXQgW35lbmQgfmxpbWl0XVxuICAgICAgIChsb29wIFt+dmFybmFtZSAwXVxuICAgICAgICAgKHdoZW4gKDwgfnZhcm5hbWUgfmVuZClcbiAgICAgICAgICAgfkBib2R5XG4gICAgICAgICAgIChyZWN1ciAoKyAxIH52YXJuYW1lKSkpKSkpKVxuXG4oZGVmbWFjcm8gZG8tbmVzdGVkIFt4bmFtZSB5bmFtZSB3aWR0aCAmIGJvZHldXG4gIChsZXQgW2l0ZXJhdGlvbnMgKGdlbnN5bSldXG4gICAgYChsZXQgW35pdGVyYXRpb25zIH53aWR0aF1cbiAgICAgICAoZG8tdGltZXMgfnhuYW1lIH5pdGVyYXRpb25zXG4gICAgICAgICAoZG8tdGltZXMgfnluYW1lIH5pdGVyYXRpb25zXG4gICAgICAgICAgIH5AYm9keSkpKSkpXG5cbihkZWZtYWNybyBpbmMhIFtwbGFjZV1cbiAgYChzZXQhIH5wbGFjZSAoKyB+cGxhY2UgMSkpKVxuXG4oZGVmbWFjcm8gYWRkISBbcGxhY2UgYW1vdW50XVxuICBgKHNldCEgfnBsYWNlICgrIH5wbGFjZSB+YW1vdW50KSkpXG5cbihkZWZtYWNybyB0aW1lIFsmIGJvZHldXG4gIChsZXQgW3N0YXJ0IChnZW5zeW0pXG4gICAgICAgIGVuZCAoZ2Vuc3ltKVxuICAgICAgICByZXN1bHQgKGdlbnN5bSldXG4gICAgYChsZXQgW35zdGFydCAoLmdldFRpbWUgKG5ldyBEYXRlKSlcbiAgICAgICAgICAgfnJlc3VsdCAoZG8gfkBib2R5KVxuICAgICAgICAgICB+ZW5kICguZ2V0VGltZSAobmV3IERhdGUpKV1cbiAgICAgICAobCAoKyBcIkVsYXBzZWQgdGltZTogXCIgKC0gfmVuZCB+c3RhcnQpIFwibXMuXCIpKVxuICAgICAgIH5yZXN1bHQpKSlcblxuKGRlZm4gbCBbdl1cbiAgKGNvbnNvbGUubG9nIHYpKVxuXG5cbihkZWZuIG1pZHBvaW50IFthIGJdXG4gICgvICgrIGEgYikgMikpXG5cbihkZWZuIGF2ZXJhZ2UyIFthIGJdXG4gICgvICgrIGEgYikgMikpXG5cbihkZWZuIGF2ZXJhZ2U0IFthIGIgYyBkXVxuICAoLyAoKyBhIGIgYyBkKSA0KSlcblxuKGRlZm4gc2FmZS1hdmVyYWdlIFthIGIgYyBkXVxuICAobGV0IFt0b3RhbCAwIGNvdW50IDBdXG4gICAgKHdoZW4gYSAoYWRkISB0b3RhbCBhKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gYiAoYWRkISB0b3RhbCBiKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gYyAoYWRkISB0b3RhbCBjKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gZCAoYWRkISB0b3RhbCBkKSAoaW5jISBjb3VudCkpXG4gICAgKC8gdG90YWwgY291bnQpKSlcblxuXG4oZGVmbiByYW5kIFtdXG4gIChNYXRoLnJhbmRvbSkpXG5cbihkZWZuIHJhbmQtYXJvdW5kLXplcm8gW3NwcmVhZF1cbiAgKC0gKCogc3ByZWFkIChyYW5kKSAyKSBzcHJlYWQpKVxuXG5cbihkZWZuIGppdHRlciBbdmFsdWUgc3ByZWFkXVxuICAoKyB2YWx1ZSAocmFuZC1hcm91bmQtemVybyBzcHJlYWQpKSlcblxuXG47IEhlaWdodG1hcCBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbWFjcm8gaGVpZ2h0bWFwLWdldCBbaG0geCB5XVxuICBgKGFnZXQgfmhtICgrICgqIH55ICguLXJlc29sdXRpb24gfmhtKSkgfngpKSlcblxuKGRlZm4gaGVpZ2h0bWFwLWdldC1zYWZlIFtobSB4IHldXG4gICh3aGVuIChhbmQgKDw9IDAgeCBobS5sYXN0KVxuICAgICAgICAgICAgICg8PSAwIHkgaG0ubGFzdCkpXG4gICAgKGhlaWdodG1hcC1nZXQgaG0geCB5KSkpXG5cbihkZWZtYWNybyBoZWlnaHRtYXAtc2V0ISBbaG0geCB5IHZhbF1cbiAgYChzZXQhIChoZWlnaHRtYXAtZ2V0IH5obSB+eCB+eSkgfnZhbCkpXG5cblxuKGRlZm4gbm9ybWFsaXplIFtobV1cbiAgKGxldCBbbWF4ICgtIEluZmluaXR5KVxuICAgICAgICBtaW4gSW5maW5pdHldXG4gICAgKGRvLXRpbWVzIGkgaG0ubGVuZ3RoXG4gICAgICAobGV0IFtlbCAoYWdldCBobSBpKV1cbiAgICAgICAgKHdoZW4gKDwgbWF4IGVsKSAoc2V0ISBtYXggZWwpKVxuICAgICAgICAod2hlbiAoPiBtaW4gZWwpIChzZXQhIG1pbiBlbCkpKSlcbiAgICAobGV0IFtzcGFuICgtIG1heCBtaW4pXVxuICAgICAgKGRvLXRpbWVzIGkgaG0ubGVuZ3RoXG4gICAgICAgIChzZXQhIChhZ2V0IGhtIGkpXG4gICAgICAgICAgKC8gKC0gKGFnZXQgaG0gaSkgbWluKVxuICAgICAgICAgICAgIHNwYW4pKSkpKSlcblxuKGRlZm4gemVyby1oZWlnaHRtYXAgW2hlaWdodG1hcF1cbiAgKGRvLXRpbWVzIGkgaGVpZ2h0bWFwLmxlbmd0aFxuICAgIChzZXQhIChhZ2V0IGhlaWdodG1hcCBpKSAwLjApKVxuICBoZWlnaHRtYXApXG5cbihkZWZuIG1ha2UtaGVpZ2h0bWFwIFtleHBvbmVudF1cbiAgKGxldCBbcmVzb2x1dGlvbiAoKyAxIChNYXRoLnBvdyAyIGV4cG9uZW50KSldXG4gICAgKGwgKCsgXCJDcmVhdGluZyBcIiByZXNvbHV0aW9uIFwiIGJ5IFwiIHJlc29sdXRpb24gXCIgaGVpZ2h0bWFwLi4uXCIpKVxuICAgIChkZWYgaGVpZ2h0bWFwXG4gICAgICAobmV3IEFycmF5ICgqIHJlc29sdXRpb24gcmVzb2x1dGlvbikpKVxuICAgIChzZXQhIGhlaWdodG1hcC5yZXNvbHV0aW9uIHJlc29sdXRpb24pXG4gICAgKHNldCEgaGVpZ2h0bWFwLmV4cG9uZW50IGV4cG9uZW50KVxuICAgIChzZXQhIGhlaWdodG1hcC5sYXN0ICgtIHJlc29sdXRpb24gMSkpXG4gICAgKHplcm8taGVpZ2h0bWFwIGhlaWdodG1hcCkpKVxuXG5cbjsgUmFuZG9tIE5vaXNlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIHJhbmRvbS1ub2lzZSBbaGVpZ2h0bWFwXVxuICAoZG8tdGltZXMgaSBoZWlnaHRtYXAubGVuZ3RoXG4gICAgKHNldCEgKGFnZXQgaGVpZ2h0bWFwIGkpIChyYW5kKSkpKVxuXG5cbjsgTWlkcG9pbnQgRGlzcGxhY2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1wZC1pbml0LWNvcm5lcnMgW2hlaWdodG1hcF1cbiAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwIDAgKHJhbmQpKVxuICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIDAgaGVpZ2h0bWFwLmxhc3QgKHJhbmQpKVxuICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGhlaWdodG1hcC5sYXN0IDAgKHJhbmQpKVxuICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGhlaWdodG1hcC5sYXN0IGhlaWdodG1hcC5sYXN0IChyYW5kKSkpXG5cbihkZWZuIG1wZC1kaXNwbGFjZSBbaGVpZ2h0bWFwIGx4IHJ4IGJ5IHR5IHNwcmVhZF1cbiAgKGxldCBbY3ggKG1pZHBvaW50IGx4IHJ4KVxuICAgICAgICBjeSAobWlkcG9pbnQgYnkgdHkpXG5cbiAgICAgICAgYm90dG9tLWxlZnQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIGx4IGJ5KVxuICAgICAgICBib3R0b20tcmlnaHQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHJ4IGJ5KVxuICAgICAgICB0b3AtbGVmdCAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgbHggdHkpXG4gICAgICAgIHRvcC1yaWdodCAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgcnggdHkpXG5cbiAgICAgICAgdG9wIChhdmVyYWdlMiB0b3AtbGVmdCB0b3AtcmlnaHQpXG4gICAgICAgIGxlZnQgKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IHRvcC1sZWZ0KVxuICAgICAgICBib3R0b20gKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IGJvdHRvbS1yaWdodClcbiAgICAgICAgcmlnaHQgKGF2ZXJhZ2UyIGJvdHRvbS1yaWdodCB0b3AtcmlnaHQpXG4gICAgICAgIGNlbnRlciAoYXZlcmFnZTQgdG9wIGxlZnQgYm90dG9tIHJpZ2h0KV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGN4IGJ5IChqaXR0ZXIgYm90dG9tIHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCBjeCB0eSAoaml0dGVyIHRvcCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgbHggY3kgKGppdHRlciBsZWZ0IHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCByeCBjeSAoaml0dGVyIHJpZ2h0IHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCBjeCBjeSAoaml0dGVyIGNlbnRlciBzcHJlYWQpKSkpXG5cbihkZWZuIG1pZHBvaW50LWRpc3BsYWNlbWVudCBbaGVpZ2h0bWFwXVxuICAobXBkLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gIDsgKG1wZC1kaXNwbGFjZSBoZWlnaHRtYXAgMCBoZWlnaHRtYXAubGFzdCAwIGhlaWdodG1hcC5sYXN0IDAuMSlcbiAgKGxvb3AgW2l0ZXIgMFxuICAgICAgICAgc3ByZWFkIDAuM11cbiAgICAod2hlbiAoPCBpdGVyIGhlaWdodG1hcC5leHBvbmVudClcbiAgICAgIChsZXQgW2NodW5rcyAoTWF0aC5wb3cgMiBpdGVyKVxuICAgICAgICAgICAgY2h1bmstd2lkdGggKC8gKC0gaGVpZ2h0bWFwLnJlc29sdXRpb24gMSkgY2h1bmtzKV1cbiAgICAgICAgKGRvLW5lc3RlZCB4Y2h1bmsgeWNodW5rIGNodW5rc1xuICAgICAgICAgIChsZXQgW2xlZnQteCAoKiBjaHVuay13aWR0aCB4Y2h1bmspXG4gICAgICAgICAgICAgICAgcmlnaHQteCAoKyBsZWZ0LXggY2h1bmstd2lkdGgpXG4gICAgICAgICAgICAgICAgYm90dG9tLXkgKCogY2h1bmstd2lkdGggeWNodW5rKVxuICAgICAgICAgICAgICAgIHRvcC15ICgrIGJvdHRvbS15IGNodW5rLXdpZHRoKV1cbiAgICAgICAgICAgIChtcGQtZGlzcGxhY2UgaGVpZ2h0bWFwIGxlZnQteCByaWdodC14IGJvdHRvbS15IHRvcC15IHNwcmVhZCkpKSlcbiAgICAgIChyZWN1ciAoKyAxIGl0ZXIpICgqIHNwcmVhZCAwLjUpKSkpXG4gIChub3JtYWxpemUgaGVpZ2h0bWFwKSlcblxuXG4oZGVmbiBtaWRwb2ludC1kaXNwbGFjZW1lbnQtZmluYWwgW2hlaWdodG1hcF1cbiAgKG1wZC1pbml0LWNvcm5lcnMgaGVpZ2h0bWFwKVxuICA7IChsZXQgW3NwcmVhZCBdKVxuICAobG9vcCBbaXRlciAwXG4gICAgICAgICBzcHJlYWQgKCsgMCAoLnZhbCAoJCBcIiNpbnB1dC1zdGFydGluZy1zcHJlYWRcIikpKV1cbiAgICAod2hlbiAoPCBpdGVyIGhlaWdodG1hcC5leHBvbmVudClcbiAgICAgIChsZXQgW2NodW5rcyAoTWF0aC5wb3cgMiBpdGVyKVxuICAgICAgICAgICAgY2h1bmstd2lkdGggKC8gKC0gaGVpZ2h0bWFwLnJlc29sdXRpb24gMSkgY2h1bmtzKV1cbiAgICAgICAgKGRvLW5lc3RlZCB4Y2h1bmsgeWNodW5rIGNodW5rc1xuICAgICAgICAgIChsZXQgW2xlZnQteCAoKiBjaHVuay13aWR0aCB4Y2h1bmspXG4gICAgICAgICAgICAgICAgcmlnaHQteCAoKyBsZWZ0LXggY2h1bmstd2lkdGgpXG4gICAgICAgICAgICAgICAgYm90dG9tLXkgKCogY2h1bmstd2lkdGggeWNodW5rKVxuICAgICAgICAgICAgICAgIHRvcC15ICgrIGJvdHRvbS15IGNodW5rLXdpZHRoKV1cbiAgICAgICAgICAgIChtcGQtZGlzcGxhY2UgaGVpZ2h0bWFwIGxlZnQteCByaWdodC14IGJvdHRvbS15IHRvcC15IHNwcmVhZCkpKSlcbiAgICAgIChyZWN1ciAoKyAxIGl0ZXIpICgqIHNwcmVhZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKCsgMCAoLnZhbCAoJCBcIiNpbnB1dC1zcHJlYWQtcmVkdWN0aW9uXCIpKSkpKSkpXG4gIChub3JtYWxpemUgaGVpZ2h0bWFwKSlcblxuXG4oZGVmbiBtcGQtZGlzcGxhY2UtZDIgW2hlaWdodG1hcCBseCByeCBieSB0eSBzcHJlYWRdXG4gIChsZXQgW2N4IChtaWRwb2ludCBseCByeClcbiAgICAgICAgY3kgKG1pZHBvaW50IGJ5IHR5KVxuXG4gICAgICAgIGJvdHRvbS1sZWZ0IChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCBseCBieSlcbiAgICAgICAgYm90dG9tLXJpZ2h0IChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCByeCBieSlcbiAgICAgICAgdG9wLWxlZnQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIGx4IHR5KVxuICAgICAgICB0b3AtcmlnaHQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHJ4IHR5KVxuXG4gICAgICAgIHRvcCAoYXZlcmFnZTIgdG9wLWxlZnQgdG9wLXJpZ2h0KVxuICAgICAgICBsZWZ0IChhdmVyYWdlMiBib3R0b20tbGVmdCB0b3AtbGVmdClcbiAgICAgICAgYm90dG9tIChhdmVyYWdlMiBib3R0b20tbGVmdCBib3R0b20tcmlnaHQpXG4gICAgICAgIHJpZ2h0IChhdmVyYWdlMiBib3R0b20tcmlnaHQgdG9wLXJpZ2h0KV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGN4IGJ5IChqaXR0ZXIgYm90dG9tIHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCBjeCB0eSAoaml0dGVyIHRvcCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgbHggY3kgKGppdHRlciBsZWZ0IHNwcmVhZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCByeCBjeSAoaml0dGVyIHJpZ2h0IHNwcmVhZCkpKSlcblxuKGRlZm4gbWlkcG9pbnQtZGlzcGxhY2VtZW50LWQxIFtoZWlnaHRtYXBdXG4gIChtcGQtaW5pdC1jb3JuZXJzIGhlaWdodG1hcCkpXG5cbihkZWZuIG1pZHBvaW50LWRpc3BsYWNlbWVudC1kMiBbaGVpZ2h0bWFwXVxuICAobXBkLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gIChtcGQtZGlzcGxhY2UtZDIgaGVpZ2h0bWFwXG4gICAgICAgICAgICAgICAgICAgMCBoZWlnaHRtYXAubGFzdFxuICAgICAgICAgICAgICAgICAgIDAgaGVpZ2h0bWFwLmxhc3RcbiAgICAgICAgICAgICAgICAgICAwLjEpKVxuXG4oZGVmbiBtaWRwb2ludC1kaXNwbGFjZW1lbnQtZDMgW2hlaWdodG1hcF1cbiAgKG1wZC1pbml0LWNvcm5lcnMgaGVpZ2h0bWFwKVxuICAobXBkLWRpc3BsYWNlIGhlaWdodG1hcFxuICAgICAgICAgICAgICAgIDAgaGVpZ2h0bWFwLmxhc3RcbiAgICAgICAgICAgICAgICAwIGhlaWdodG1hcC5sYXN0XG4gICAgICAgICAgICAgICAgMC4xKSlcblxuXG5cbjsgVGhyZWUuanMgSGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQgW11cbiAgKGxldCBbbGlnaHQgKG5ldyBUSFJFRS5EaXJlY3Rpb25hbExpZ2h0IDB4ZmZmZmZmIDEpXVxuICAgIChsaWdodC5wb3NpdGlvbi5zZXQgMTAwIDAgMTUwKVxuICAgIGxpZ2h0KSlcblxuKGRlZm4gbWFrZS1jYW1lcmEgW11cbiAgKGxldCBbY2FtZXJhIChuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmFcbiAgICAgICAgICAgICAgICAgICAgNTUsXG4gICAgICAgICAgICAgICAgICAgICgvIHdpZHRoIGhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgMC4xLFxuICAgICAgICAgICAgICAgICAgICAxMDAwKV1cbiAgICAoY2FtZXJhLnBvc2l0aW9uLnNldCAwIC0xMDAgMTUwKVxuICAgIGNhbWVyYSkpXG5cbihkZWZuIG1ha2UtcmVuZGVyZXIgW11cbiAgKGxldCBbcmVuZGVyZXIgKG5ldyBUSFJFRS5XZWJHTFJlbmRlcmVyIHs6YW50aWFsaWFzIGZhbHNlfSldXG4gICAgKHJlbmRlcmVyLnNldENsZWFyQ29sb3IgMHhmZmZmZmYpXG4gICAgKHJlbmRlcmVyLnNldFNpemUgd2lkdGggaGVpZ2h0KVxuICAgIChyZW5kZXJlci5zZXRQaXhlbFJhdGlvIDIpXG4gICAgcmVuZGVyZXIpKVxuXG4oZGVmbiBtYWtlLWdlb21ldHJ5IFtoZWlnaHRtYXBdXG4gIChsZXQgW2dlb21ldHJ5IChuZXcgVEhSRUUuUGxhbmVHZW9tZXRyeVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgICgtIGhlaWdodG1hcC5yZXNvbHV0aW9uIDEpXG4gICAgICAgICAgICAgICAgICAgICAgKC0gaGVpZ2h0bWFwLnJlc29sdXRpb24gMSkpXVxuICAgIChzZXQhIGdlb21ldHJ5LmR5bmFtaWMgdHJ1ZSlcbiAgICBnZW9tZXRyeSkpXG5cbihkZWZuIG1ha2UtY29udHJvbHMgW2NhbWVyYSByZW5kZXJlcl1cbiAgKGxldCBbY29udHJvbHMgKG5ldyBUSFJFRS5UcmFja2JhbGxDb250cm9scyBjYW1lcmEgcmVuZGVyZXIuZG9tRWxlbWVudCldXG4gICAgKHNldCEgY29udHJvbHMucm90YXRlU3BlZWQgMS40KVxuICAgIChzZXQhIGNvbnRyb2xzLnpvb21TcGVlZCAwLjUpXG4gICAgKHNldCEgY29udHJvbHMuc3RhdGljTW92aW5nIHRydWUpXG4gICAgKHNldCEgY29udHJvbHMuZHluYW1pY0RhbXBpbmdGYWN0b3IgMC4zKVxuICAgIGNvbnRyb2xzKSlcblxuKGRlZm4gbWFrZS1wbGFuZSBbZ2VvbWV0cnldXG4gIChsZXQgW21hdGVyaWFsIChuZXcgVEhSRUUuTWVzaExhbWJlcnRNYXRlcmlhbFxuICAgICAgICAgICAgICAgICAgICAgIHs6d2lyZWZyYW1lIHdpcmVmcmFtZVxuICAgICAgICAgICAgICAgICAgICAgICA6d2lyZWZyYW1lTGluZXdpZHRoIHdpcmVmcmFtZS13aWR0aFxuICAgICAgICAgICAgICAgICAgICAgICA6Y29sb3IgMHgwMGJiMDB9KV1cbiAgICAobmV3IFRIUkVFLk1lc2ggZ2VvbWV0cnkgbWF0ZXJpYWwpKSlcblxuXG4oZGVmbiBhdHRhY2gtdG8tZG9tIFtyZW5kZXJlciBlbC1uYW1lIHJlZnJlc2gtZm5dXG4gIChsZXQgW2NvbnRhaW5lciAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQgZWwtbmFtZSlcbiAgICAgICAgc2V0dGluZ3MgKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJkaXZcIilcbiAgICAgICAgcmVmcmVzaC1idXR0b24gKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJidXR0b25cIilcbiAgICAgICAgYnV0dG9uLXRleHQgKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlIFwiUmVmcmVzaFwiKVxuICAgICAgICBjYW5jZWwtc2Nyb2xsIChmbiBbZV0gKC5wcmV2ZW50RGVmYXVsdCBlKSldXG4gICAgKHNldCEgcmVmcmVzaC1idXR0b24ub25jbGljayByZWZyZXNoLWZuKVxuICAgIChzZXQhIHJlbmRlcmVyLmRvbUVsZW1lbnQub25tb3VzZXdoZWVsIGNhbmNlbC1zY3JvbGwpXG4gICAgKHJlbmRlcmVyLmRvbUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciBcIk1vek1vdXNlUGl4ZWxTY3JvbGxcIiBjYW5jZWwtc2Nyb2xsIGZhbHNlKVxuICAgICguYXBwZW5kQ2hpbGQgcmVmcmVzaC1idXR0b24gYnV0dG9uLXRleHQpXG4gICAgKC5hcHBlbmRDaGlsZCBjb250YWluZXIgcmVuZGVyZXIuZG9tRWxlbWVudClcbiAgICAoLmFwcGVuZENoaWxkIGNvbnRhaW5lciBzZXR0aW5ncylcbiAgICAoLmFwcGVuZENoaWxkIHNldHRpbmdzIHJlZnJlc2gtYnV0dG9uKSkpXG5cbihkZWZuIHVwZGF0ZS1nZW9tZXRyeSBbZ2VvbWV0cnkgaGVpZ2h0bWFwXVxuICAoZG8tdGltZXMgaSBnZW9tZXRyeS52ZXJ0aWNlcy5sZW5ndGhcbiAgICAoc2V0ISAoLi16IChhZ2V0IGdlb21ldHJ5LnZlcnRpY2VzIGkpKVxuICAgICAgKCogdGVycmFpbi1oZWlnaHQgKGFnZXQgaGVpZ2h0bWFwIGkpKSkpXG4gIChzZXQhIGdlb21ldHJ5LnZlcnRpY2VzTmVlZFVwZGF0ZSB0cnVlKVxuICAoZ2VvbWV0cnkuY29tcHV0ZUZhY2VOb3JtYWxzKVxuICAoZ2VvbWV0cnkuY29tcHV0ZVZlcnRleE5vcm1hbHMpXG4gIChnZW9tZXRyeS5jb21wdXRlTW9ycGhOb3JtYWxzKVxuICBnZW9tZXRyeSlcblxuXG47IE1haW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBtYWtlLWRlbW8gW2VsZW1lbnQtaWQgYWxnb3JpdGhtIHNpemVdXG4gIChkZWYgc2NlbmUgKG5ldyBUSFJFRS5TY2VuZSkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BeGlzSGVscGVyIDEwMCkpXG5cbiAgKGRlZiBjbG9jayAobmV3IFRIUkVFLkNsb2NrKSlcbiAgKGRlZiBjYW1lcmEgKG1ha2UtY2FtZXJhKSlcbiAgKGRlZiByZW5kZXJlciAobWFrZS1yZW5kZXJlcikpXG4gIChkZWYgZ2VvbWV0cnkgKG1ha2UtZ2VvbWV0cnkgKG1ha2UtaGVpZ2h0bWFwIHNpemUpKSlcblxuICAoc2NlbmUuYWRkIChtYWtlLWRpcmVjdGlvbmFsLWxpZ2h0KSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkFtYmllbnRMaWdodCAweGZmZmZmZiAwLjA1KSlcbiAgKHNjZW5lLmFkZCAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG5cbiAgKGRlZm4gcmVmcmVzaCBbXVxuICAgIChsIFwiUmVmcmVzaGluZyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XCIpXG4gICAgKGxldCBbaGVpZ2h0bWFwIChtYWtlLWhlaWdodG1hcCBzaXplKV1cbiAgICAgIChsIFwiR2VuZXJhdGluZyB0ZXJyYWluLi4uXCIpXG4gICAgICAodGltZSAoYWxnb3JpdGhtIGhlaWdodG1hcCkpXG4gICAgICAobCBcIlJlZnJlc2hpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAgICh0aW1lICh1cGRhdGUtZ2VvbWV0cnkgZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcbiAgICAgIChsIFwiRG9uZSFcIikpKVxuXG4gIChhdHRhY2gtdG8tZG9tIHJlbmRlcmVyIGVsZW1lbnQtaWQgcmVmcmVzaClcbiAgKGRlZiBjb250cm9scyAobWFrZS1jb250cm9scyBjYW1lcmEgcmVuZGVyZXIpKVxuXG4gIChkZWZuIHJlbmRlciBbXVxuICAgIChsZXQgW2RlbHRhIChjbG9jay5nZXREZWx0YSldXG4gICAgICAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIHJlbmRlcilcbiAgICAgICgudXBkYXRlIGNvbnRyb2xzIGRlbHRhKVxuICAgICAgKHJlbmRlcmVyLnJlbmRlciBzY2VuZSBjYW1lcmEpKSlcblxuICAocmVuZGVyKVxuXG4gIG5pbClcblxuKGRlZm4gbWFrZS1maW5hbCBbZWxlbWVudC1pZF1cbiAgKGRlZiBzY2VuZSAobmV3IFRIUkVFLlNjZW5lKSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkF4aXNIZWxwZXIgMTAwKSlcblxuICAoZGVmIGNsb2NrIChuZXcgVEhSRUUuQ2xvY2spKVxuICAoZGVmIGNhbWVyYSAobWFrZS1jYW1lcmEpKVxuICAoZGVmIHJlbmRlcmVyIChtYWtlLXJlbmRlcmVyKSlcbiAgKGRlZiBoZWlnaHRtYXAgKG1ha2UtaGVpZ2h0bWFwICgudmFsICgkIFwiI2lucHV0LWV4cG9uZW50XCIpKSkpXG4gIChkZWYgZ2VvbWV0cnkgKG1ha2UtZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcbiAgKGRlZiBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG5cbiAgKHNjZW5lLmFkZCAobWFrZS1kaXJlY3Rpb25hbC1saWdodCkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BbWJpZW50TGlnaHQgMHhmZmZmZmYgMC4wNSkpXG4gIChzY2VuZS5hZGQgcGxhbmUpXG5cbiAgKGRlZm4gcmVmcmVzaCBbXVxuICAgIChsIFwiUmVmcmVzaGluZyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XCIpXG4gICAgKHNjZW5lLnJlbW92ZSBwbGFuZSlcbiAgICAoc2V0ISBoZWlnaHRtYXAgKG1ha2UtaGVpZ2h0bWFwICgudmFsICgkIFwiI2lucHV0LWV4cG9uZW50XCIpKSkpXG4gICAgKHNldCEgZ2VvbWV0cnkgKG1ha2UtZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcbiAgICAoc2V0ISBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG4gICAgKHNjZW5lLmFkZCBwbGFuZSlcbiAgICAobCBcIkdlbmVyYXRpbmcgdGVycmFpbi4uLlwiKVxuICAgICh0aW1lIChtaWRwb2ludC1kaXNwbGFjZW1lbnQtZmluYWwgaGVpZ2h0bWFwKSlcbiAgICAobCBcIlJlZnJlc2hpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAodGltZSAodXBkYXRlLWdlb21ldHJ5IGdlb21ldHJ5IGhlaWdodG1hcCkpXG4gICAgKGwgXCJEb25lIVwiKSlcblxuICAoYXR0YWNoLXRvLWRvbSByZW5kZXJlciBlbGVtZW50LWlkIHJlZnJlc2gpXG4gIChkZWYgY29udHJvbHMgKG1ha2UtY29udHJvbHMgY2FtZXJhIHJlbmRlcmVyKSlcblxuICAoZGVmbiByZW5kZXIgW11cbiAgICAobGV0IFtkZWx0YSAoY2xvY2suZ2V0RGVsdGEpXVxuICAgICAgKHJlcXVlc3RBbmltYXRpb25GcmFtZSByZW5kZXIpXG4gICAgICAoLnVwZGF0ZSBjb250cm9scyBkZWx0YSlcbiAgICAgIChyZW5kZXJlci5yZW5kZXIgc2NlbmUgY2FtZXJhKSkpXG5cbiAgKHJlbmRlcilcblxuICBuaWwpXG5cblxuKGRlZm4gcnVuIFtdXG4gIChtYWtlLWRlbW8gXCJkZW1vLXJhbmRvbVwiIHJhbmRvbS1ub2lzZSA3KVxuICAobWFrZS1kZW1vIFwiZGVtby1tcGQtMVwiIG1pZHBvaW50LWRpc3BsYWNlbWVudC1kMSAyKVxuICAobWFrZS1kZW1vIFwiZGVtby1tcGQtMlwiIG1pZHBvaW50LWRpc3BsYWNlbWVudC1kMiAyKVxuICAobWFrZS1kZW1vIFwiZGVtby1tcGQtM1wiIG1pZHBvaW50LWRpc3BsYWNlbWVudC1kMyAyKVxuICAobWFrZS1kZW1vIFwiZGVtby1tcGQtNFwiIG1pZHBvaW50LWRpc3BsYWNlbWVudCAzKVxuICAobWFrZS1maW5hbCBcImRlbW8tZmluYWxcIilcbiAgOyAobWFrZS1kZW1vIFwiZGVtby1taWRwb2ludFwiIG1pZHBvaW50LWRpc3BsYWNlbWVudClcbiAgOyAobWFrZS1kZW1vIFwiZGVtby1kaWFtb25kXCIgZGlhbW9uZC1zcXVhcmUpXG5cbiAgKVxuXG4oJCBydW4pXG5cblxuOyB2aW06IGx3Kz1kby10aW1lcyBsdys9ZG8tbmVzdGVkIDpcbiJdfQ== diff -r a52d61eb7e85 -r 2d9281a1f7e7 media/js/terrain2.js --- a/media/js/terrain2.js Mon Mar 07 13:44:20 2016 +0000 +++ b/media/js/terrain2.js Sat Jun 25 15:57:05 2016 +0000 @@ -780,4 +780,5 @@ module.exports = wrappedNDArrayCtor -},{"iota-array":2,"is-buffer":3}]},{},[1]); +},{"iota-array":2,"is-buffer":3}]},{},[1]) +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm1lZGlhL2pzL3dpc3AvYW5vbnltb3VzLndpc3AiLCJub2RlX21vZHVsZXMvaW90YS1hcnJheS9pb3RhLmpzIiwibm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9uZGFycmF5L25kYXJyYXkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0lDQUEsSUFBQyxJLEdBQUQ7QUFBQSxRQUFBLEUsRUFBSSxNQUFKO0FBQUEsUUFBQSxHLEVBQUEsSyxDQUFBO0FBQUEsTTs7O0FBSUEsSUFBSyxLQUFBLEdBQUEsT0FBQSxDQUFBLEtBQUEsR0FBTSxHQUFYLEM7QUFDQSxJQUFLLE1BQUEsR0FBQSxPQUFBLENBQUEsTUFBQSxHQUFPLEdBQVosQztBQUNBLElBQUssU0FBQSxHQUFBLE9BQUEsQ0FBQSxTQUFBLEcsSUFBTCxDO0FBQ0EsSUFBSyxjQUFBLEdBQUEsT0FBQSxDQUFBLGNBQUEsR0FBZ0IsR0FBckIsQztBQUNBLElBQUssYUFBQSxHQUFBLE9BQUEsQ0FBQSxhQUFBLEdBQWUsRUFBcEIsQztBQUNBLElBQUssV0FBQSxHQUFBLE9BQUEsQ0FBQSxXQUFBLEdBQWEsR0FBbEIsQzs7OztBQW9CQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7QUFHQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7Ozs7Ozs7OztBQXdFQSxJQUFNLFFBQUEsR0FBQSxPQUFBLENBQUEsUUFBQSxHQUFOLFNBQU0sUUFBTixD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QUFELENBQVksWUFBWjtBQUFBLENBREYsQztBQUdDLENBQUQsQ0FBRyxHQUFIOzs7O0FDcFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihucyBkZW1vXG4gICg6cmVxdWlyZSBbbmRhcnJheV0pKVxuXG47IENvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmIHdpZHRoIDYxMClcbihkZWYgaGVpZ2h0IDQwMClcbihkZWYgd2lyZWZyYW1lIHRydWUpXG4oZGVmIHdpcmVmcmFtZS13aWR0aCAxLjIpXG4oZGVmIHRlcnJhaW4taGVpZ2h0IDUwKVxuKGRlZiB0ZXJyYWluLXNpemUgMTAwKVxuXG47IEdlbmVyYWwgVXRpbGl0aWVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbWFjcm8gd2hlbiBbY29uZGl0aW9uICYgYm9keV1cbiAgYChpZiB+Y29uZGl0aW9uXG4gICAgIChkbyB+QGJvZHkpKSlcblxuKGRlZm1hY3JvIHdoZW4tbm90IFtjb25kaXRpb24gJiBib2R5XVxuICBgKHdoZW4gKG5vdCB+Y29uZGl0aW9uKVxuICAgICB+QGJvZHkpKVxuXG4oZGVmbWFjcm8gLT4gWyYgb3BlcmF0aW9uc11cbiAgKHJlZHVjZVxuICAgIChmbiBbZm9ybSBvcGVyYXRpb25dXG4gICAgICAoY29ucyAoZmlyc3Qgb3BlcmF0aW9uKVxuICAgICAgICAgICAgKGNvbnMgZm9ybSAocmVzdCBvcGVyYXRpb24pKSkpXG4gICAgKGZpcnN0IG9wZXJhdGlvbnMpXG4gICAgKHJlc3Qgb3BlcmF0aW9ucykpKVxuXG5cbihkZWZuIGluYyBbeF1cbiAgKCsgeCAxKSlcblxuKGRlZm4gZGVjIFt4XVxuICAoLSB4IDEpKVxuXG5cbihkZWZtYWNybyBkby10aW1lcyBbdmFybmFtZSBsaW1pdCAmIGJvZHldXG4gIChsZXQgW2VuZCAoZ2Vuc3ltKV1cbiAgICBgKGxldCBbfmVuZCB+bGltaXRdXG4gICAgICAgKGxvb3AgW352YXJuYW1lIDBdXG4gICAgICAgICAod2hlbiAoPCB+dmFybmFtZSB+ZW5kKVxuICAgICAgICAgICB+QGJvZHlcbiAgICAgICAgICAgKHJlY3VyIChpbmMgfnZhcm5hbWUpKSkpKSkpXG5cbihkZWZtYWNybyBkby1zdHJpZGUgW3Zhcm5hbWVzIHN0YXJ0LWZvcm0gZW5kLWZvcm0gc3RyaWRlLWZvcm0gJiBib2R5XVxuICAobGV0IFtzdHJpZGUgKGdlbnN5bSBcInN0cmlkZVwiKVxuICAgICAgICBzdGFydCAoZ2Vuc3ltIFwic3RhcnRcIilcbiAgICAgICAgZW5kIChnZW5zeW0gXCJlbmRcIilcbiAgICAgICAgYnVpbGQgKGZuIGJ1aWxkIFt2YXJzXVxuICAgICAgICAgICAgICAgIChpZiAoZW1wdHk/IHZhcnMpXG4gICAgICAgICAgICAgICAgICBgKGRvIH5AYm9keSlcbiAgICAgICAgICAgICAgICAgIChsZXQgW3Zhcm5hbWUgKGZpcnN0IHZhcnMpXVxuICAgICAgICAgICAgICAgICAgICBgKGxvb3AgW352YXJuYW1lIH5zdGFydF1cbiAgICAgICAgICAgICAgICAgICAgICAgKHdoZW4gKDwgfnZhcm5hbWUgfmVuZClcbiAgICAgICAgICAgICAgICAgICAgICAgICB+KGJ1aWxkIChyZXN0IHZhcnMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgIChyZWN1ciAoKyB+dmFybmFtZSB+c3RyaWRlKSkpKSkpKV1cbiAgICA7IEZpeCB0aGUgbnVtYmVycyBvbmNlIG91dHNpZGUgdGhlIG5lc3RlZCBsb29wcyxcbiAgICA7IGFuZCB0aGVuIGJ1aWxkIHRoZSBndXRzLlxuICAgIGAobGV0IFt+c3RhcnQgfnN0YXJ0LWZvcm1cbiAgICAgICAgICAgfmVuZCB+ZW5kLWZvcm1cbiAgICAgICAgICAgfnN0cmlkZSB+c3RyaWRlLWZvcm1dXG4gICAgICAgfihidWlsZCB2YXJuYW1lcykpKSlcblxuXG4oZGVmbWFjcm8gZG8tbmRhcnJheSBbdmFycyBhcnJheS1mb3JtICYgYm9keV1cbiAgKGxldCBbYXJyYXktdmFyIChnZW5zeW0gXCJhcnJheVwiKVxuICAgICAgICBidWlsZCAoZm4gYnVpbGQgW3ZhcnMgbl1cbiAgICAgICAgICAgICAgICAoaWYgKGVtcHR5PyB2YXJzKVxuICAgICAgICAgICAgICAgICAgYChkbyB+QGJvZHkpXG4gICAgICAgICAgICAgICAgICBgKGRvLXRpbWVzIH4oZmlyc3QgdmFycykgKGFnZXQgKC4tc2hhcGUgfmFycmF5LXZhcikgfm4pXG4gICAgICAgICAgICAgICAgICAgICB+KGJ1aWxkIChyZXN0IHZhcnMpIChpbmMgbikpKSkpXVxuICAgIGAobGV0IFt+YXJyYXktdmFyIH5hcnJheS1mb3JtXVxuICAgICAgIH4oYnVpbGQgdmFycyAwKSkpKVxuXG4oZGVmbWFjcm8gZG8tbmRhcnJheS1lbCBbZWxlbWVudCBhcnJheS1mb3JtICYgYm9keV1cbiAgKGxldCBbaW5kZXggKGdlbnN5bSBcImluZGV4XCIpXG4gICAgICAgIGFycmF5IChnZW5zeW0gXCJhcnJheVwiKV1cbiAgICBgKGxldCBbfmFycmF5IH5hcnJheS1mb3JtXVxuICAgICAgIChkby10aW1lcyB+aW5kZXggKC4tbGVuZ3RoICguLWRhdGEgfmFycmF5KSlcbiAgICAgICAgIChsZXQgW35lbGVtZW50IChhZ2V0ICguLWRhdGEgfmFycmF5KSB+aW5kZXgpXVxuICAgICAgICAgICB+QGJvZHkpKSkpKVxuXG5cbihkZWZtYWNybyBpbmMhIFtwbGFjZV1cbiAgYChzZXQhIH5wbGFjZSAoaW5jIH5wbGFjZSkpKVxuXG4oZGVmbWFjcm8gYWRkISBbcGxhY2UgYW1vdW50XVxuICBgKHNldCEgfnBsYWNlICgrIH5wbGFjZSB+YW1vdW50KSkpXG5cblxuKGRlZm1hY3JvIGwgWyYgZm9ybXNdXG4gIGAoY29uc29sZS5sb2cgfkBmb3JtcykpXG5cbihkZWZtYWNybyB0aW1lIFsmIGJvZHldXG4gIChsZXQgW3N0YXJ0IChnZW5zeW0pXG4gICAgICAgIGVuZCAoZ2Vuc3ltKVxuICAgICAgICByZXN1bHQgKGdlbnN5bSldXG4gICAgYChsZXQgW35zdGFydCAoLmdldFRpbWUgKG5ldyBEYXRlKSlcbiAgICAgICAgICAgfnJlc3VsdCAoZG8gfkBib2R5KVxuICAgICAgICAgICB+ZW5kICguZ2V0VGltZSAobmV3IERhdGUpKV1cbiAgICAgICAobCAoKyBcIkVsYXBzZWQgdGltZTogXCIgKC0gfmVuZCB+c3RhcnQpIFwibXMuXCIpKVxuICAgICAgIH5yZXN1bHQpKSlcblxuXG4oZGVmbiBtaWRwb2ludCBbYSBiXVxuICAoLyAoKyBhIGIpIDIpKVxuXG4oZGVmbiBhdmVyYWdlMiBbYSBiXVxuICAoLyAoKyBhIGIpIDIpKVxuXG4oZGVmbiBhdmVyYWdlNCBbYSBiIGMgZF1cbiAgKC8gKCsgYSBiIGMgZCkgNCkpXG5cbihkZWZuIHNhZmUtYXZlcmFnZSBbYSBiIGMgZF1cbiAgKGxldCBbdG90YWwgMCBjb3VudCAwXVxuICAgICh3aGVuIGEgKGFkZCEgdG90YWwgYSkgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGIgKGFkZCEgdG90YWwgYikgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGMgKGFkZCEgdG90YWwgYykgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGQgKGFkZCEgdG90YWwgZCkgKGluYyEgY291bnQpKVxuICAgICgvIHRvdGFsIGNvdW50KSkpXG5cblxuOyBSYW5kb21uZXNzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gcmFuZCBbXVxuICAoTWF0aC5yYW5kb20pKVxuXG4oZGVmbiByYW5kLWFyb3VuZC16ZXJvIFtzcHJlYWRdXG4gICgtICgqIHNwcmVhZCAocmFuZCkgMikgc3ByZWFkKSlcblxuKGRlZm4gaml0dGVyIFt2YWx1ZSBzcHJlYWRdXG4gICgrIHZhbHVlIChyYW5kLWFyb3VuZC16ZXJvIHNwcmVhZCkpKVxuXG5cbjsgSGVpZ2h0bWFwIEhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIGhlaWdodG1hcC1yZXNvbHV0aW9uIFtoZWlnaHRtYXBdXG4gIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKSlcblxuKGRlZm4gaGVpZ2h0bWFwLWxhc3QtaW5kZXggW2hlaWdodG1hcF1cbiAgKGRlYyAoaGVpZ2h0bWFwLXJlc29sdXRpb24gaGVpZ2h0bWFwKSkpXG5cbihkZWZuIGhlaWdodG1hcC1jZW50ZXItaW5kZXggW2hlaWdodG1hcF1cbiAgKG1pZHBvaW50IDAgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCkpKVxuXG5cbihkZWZuIGhlaWdodG1hcC1nZXQgW2hlaWdodG1hcCB4IHldXG4gICguZ2V0IGhlaWdodG1hcCB4IHkpKVxuXG4oZGVmbiBoZWlnaHRtYXAtZ2V0LXNhZmUgW2hlaWdodG1hcCB4IHldXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCldXG4gICAgKHdoZW4gKGFuZCAoPD0gMCB4IGxhc3QpXG4gICAgICAgICAgICAgICAoPD0gMCB5IGxhc3QpKVxuICAgICAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkpKSlcblxuKGRlZm4gaGVpZ2h0bWFwLXNldCEgW2hlaWdodG1hcCB4IHkgdmFsXVxuICAoLnNldCBoZWlnaHRtYXAgeCB5IHZhbCkpXG5cbihkZWZuIGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIFtoZWlnaHRtYXAgeCB5IHZhbF1cbiAgKHdoZW4gKD09IDAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCB4IHkgdmFsKSkpXG5cblxuKGRlZm4gbm9ybWFsaXplIFtoZWlnaHRtYXBdXG4gIChsZXQgW21heCAoLSBJbmZpbml0eSlcbiAgICAgICAgbWluIEluZmluaXR5XVxuICAgIChkby1uZGFycmF5LWVsIGVsIGhlaWdodG1hcFxuICAgICAgKHdoZW4gKDwgbWF4IGVsKSAoc2V0ISBtYXggZWwpKVxuICAgICAgKHdoZW4gKD4gbWluIGVsKSAoc2V0ISBtaW4gZWwpKSlcbiAgICAobGV0IFtzcGFuICgtIG1heCBtaW4pXVxuICAgICAgKGRvLW5kYXJyYXkgW3ggeV0gaGVpZ2h0bWFwXG4gICAgICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5XG4gICAgICAgICAgICAgICAgICAgICAgICAoLyAoLSAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgeCB5KSBtaW4pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuKSkpKSkpXG5cblxuKGRlZm4gbWFrZS1oZWlnaHRtYXAgW2V4cG9uZW50XVxuICAobGV0IFtyZXNvbHV0aW9uICgrIChNYXRoLnBvdyAyIGV4cG9uZW50KSAxKV1cbiAgICAobGV0IFtoZWlnaHRtYXAgKG5kYXJyYXkgKG5ldyBGbG9hdDY0QXJyYXkgKCogcmVzb2x1dGlvbiByZXNvbHV0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Jlc29sdXRpb24gcmVzb2x1dGlvbl0pXVxuICAgICAgKHNldCEgaGVpZ2h0bWFwLmV4cG9uZW50IGV4cG9uZW50KVxuICAgICAgKHNldCEgaGVpZ2h0bWFwLnJlc29sdXRpb24gcmVzb2x1dGlvbilcbiAgICAgIChzZXQhIGhlaWdodG1hcC5sYXN0IChkZWMgcmVzb2x1dGlvbikpXG4gICAgICBoZWlnaHRtYXApKSlcblxuXG4oZGVmbiB0b3AtbGVmdC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyAwIDApXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIHRvcC1yaWdodC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyBjZW50ZXIgMClcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuKGRlZm4gYm90dG9tLWxlZnQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gMCBjZW50ZXIpXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIGJvdHRvbS1yaWdodC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyBjZW50ZXIgY2VudGVyKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG5cbjsgTWlkcG9pbnQgRGlzcGxhY2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1wZC1pbml0LWNvcm5lcnMgW2hlaWdodG1hcF1cbiAgKGxldCBbbGFzdCAoaGVpZ2h0bWFwLWxhc3QtaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIDAgICAgMCAgICAocmFuZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwICAgIGxhc3QgKHJhbmQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgbGFzdCAwICAgIChyYW5kKSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGxhc3QgbGFzdCAocmFuZCkpKSlcblxuKGRlZm4gbXBkLWRpc3BsYWNlIFtoZWlnaHRtYXAgc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb25dXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcClcbiAgICAgICAgYyAobWlkcG9pbnQgMCBsYXN0KVxuXG4gICAgICAgIGJvdHRvbS1sZWZ0ICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgMCAgICAwKVxuICAgICAgICBib3R0b20tcmlnaHQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIGxhc3QgMClcbiAgICAgICAgdG9wLWxlZnQgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCAwICAgIGxhc3QpXG4gICAgICAgIHRvcC1yaWdodCAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgbGFzdCBsYXN0KVxuXG4gICAgICAgIHRvcCAgICAoYXZlcmFnZTIgdG9wLWxlZnQgdG9wLXJpZ2h0KVxuICAgICAgICBsZWZ0ICAgKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IHRvcC1sZWZ0KVxuICAgICAgICBib3R0b20gKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IGJvdHRvbS1yaWdodClcbiAgICAgICAgcmlnaHQgIChhdmVyYWdlMiBib3R0b20tcmlnaHQgdG9wLXJpZ2h0KVxuICAgICAgICBjZW50ZXIgKGF2ZXJhZ2U0IHRvcCBsZWZ0IGJvdHRvbSByaWdodClcblxuICAgICAgICBuZXh0LXNwcmVhZCAoKiBzcHJlYWQgc3ByZWFkLXJlZHVjdGlvbildXG4gICAgKGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIGhlaWdodG1hcCBjICAgIDAgICAgKGppdHRlciBib3R0b20gc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIGMgICAgbGFzdCAoaml0dGVyIHRvcCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBoZWlnaHRtYXAgMCAgICBjICAgIChqaXR0ZXIgbGVmdCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBoZWlnaHRtYXAgbGFzdCBjICAgIChqaXR0ZXIgcmlnaHQgc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIGMgICAgYyAgICAoaml0dGVyIGNlbnRlciBzcHJlYWQpKVxuICAgICh3aGVuLW5vdCAoPT0gMyAoaGVpZ2h0bWFwLXJlc29sdXRpb24gaGVpZ2h0bWFwKSlcbiAgICAgIChtcGQtZGlzcGxhY2UgKHRvcC1sZWZ0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXG4gICAgICAobXBkLWRpc3BsYWNlICh0b3AtcmlnaHQtY29ybmVyIGhlaWdodG1hcCkgbmV4dC1zcHJlYWQgc3ByZWFkLXJlZHVjdGlvbilcbiAgICAgIChtcGQtZGlzcGxhY2UgKGJvdHRvbS1sZWZ0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXG4gICAgICAobXBkLWRpc3BsYWNlIChib3R0b20tcmlnaHQtY29ybmVyIGhlaWdodG1hcCkgbmV4dC1zcHJlYWQgc3ByZWFkLXJlZHVjdGlvbikpKSlcblxuKGRlZm4gbWlkcG9pbnQtZGlzcGxhY2VtZW50IFtoZWlnaHRtYXBdXG4gIChsZXQgW2luaXRpYWwtc3ByZWFkIDAuMyBcbiAgICAgICAgc3ByZWFkLXJlZHVjdGlvbiAwLjU1XVxuICAgIChtcGQtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgICAobXBkLWRpc3BsYWNlIGhlaWdodG1hcCBpbml0aWFsLXNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uKVxuICAgIChub3JtYWxpemUgaGVpZ2h0bWFwKSkpXG5cblxuOyBUaHJlZS5qcyBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gbWFrZS1kaXJlY3Rpb25hbC1saWdodCBbXVxuICAobGV0IFtsaWdodCAobmV3IFRIUkVFLkRpcmVjdGlvbmFsTGlnaHQgMHhmZmZmZmYgMSldXG4gICAgKGxpZ2h0LnBvc2l0aW9uLnNldCAxMDAgMCAxNTApXG4gICAgbGlnaHQpKVxuXG4oZGVmbiBtYWtlLWNhbWVyYSBbXVxuICAobGV0IFtjYW1lcmEgKG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYVxuICAgICAgICAgICAgICAgICAgICA1NSxcbiAgICAgICAgICAgICAgICAgICAgKC8gd2lkdGggaGVpZ2h0KVxuICAgICAgICAgICAgICAgICAgICAwLjEsXG4gICAgICAgICAgICAgICAgICAgIDEwMDApXVxuICAgIChjYW1lcmEucG9zaXRpb24uc2V0IDAgLTEwMCAxNTApXG4gICAgY2FtZXJhKSlcblxuKGRlZm4gbWFrZS1yZW5kZXJlciBbXVxuICAobGV0IFtyZW5kZXJlciAobmV3IFRIUkVFLldlYkdMUmVuZGVyZXIgezphbnRpYWxpYXMgZmFsc2V9KV1cbiAgICAocmVuZGVyZXIuc2V0Q2xlYXJDb2xvciAweGZmZmZmZilcbiAgICAocmVuZGVyZXIuc2V0U2l6ZSB3aWR0aCBoZWlnaHQpXG4gICAgKHJlbmRlcmVyLnNldFBpeGVsUmF0aW8gMilcbiAgICByZW5kZXJlcikpXG5cbihkZWZuIG1ha2UtZ2VvbWV0cnkgW2hlaWdodG1hcF1cbiAgKGxldCBbcmVzb2x1dGlvbiAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMClcbiAgICAgICAgZ2VvbWV0cnkgKG5ldyBUSFJFRS5QbGFuZUdlb21ldHJ5XG4gICAgICAgICAgICAgICAgICAgICAgdGVycmFpbi1zaXplXG4gICAgICAgICAgICAgICAgICAgICAgdGVycmFpbi1zaXplXG4gICAgICAgICAgICAgICAgICAgICAgKC0gcmVzb2x1dGlvbiAxKVxuICAgICAgICAgICAgICAgICAgICAgICgtIHJlc29sdXRpb24gMSkpXVxuICAgIGdlb21ldHJ5KSlcblxuKGRlZm4gbWFrZS1jb250cm9scyBbY2FtZXJhIHJlbmRlcmVyXVxuICAobGV0IFtjb250cm9scyAobmV3IFRIUkVFLlRyYWNrYmFsbENvbnRyb2xzIGNhbWVyYSByZW5kZXJlci5kb21FbGVtZW50KV1cbiAgICAoc2V0ISBjb250cm9scy5yb3RhdGVTcGVlZCAxLjQpXG4gICAgKHNldCEgY29udHJvbHMuem9vbVNwZWVkIDAuNSlcbiAgICAoc2V0ISBjb250cm9scy5zdGF0aWNNb3ZpbmcgdHJ1ZSlcbiAgICAoc2V0ISBjb250cm9scy5keW5hbWljRGFtcGluZ0ZhY3RvciAwLjMpXG4gICAgY29udHJvbHMpKVxuXG4oZGVmbiBtYWtlLXBsYW5lIFtnZW9tZXRyeV1cbiAgKGxldCBbbWF0ZXJpYWwgKG5ldyBUSFJFRS5NZXNoTGFtYmVydE1hdGVyaWFsXG4gICAgICAgICAgICAgICAgICAgICAgezp3aXJlZnJhbWUgd2lyZWZyYW1lXG4gICAgICAgICAgICAgICAgICAgICAgIDp3aXJlZnJhbWVMaW5ld2lkdGggd2lyZWZyYW1lLXdpZHRoXG4gICAgICAgICAgICAgICAgICAgICAgIDpjb2xvciAweDAwYmIwMH0pXVxuICAgIChuZXcgVEhSRUUuTWVzaCBnZW9tZXRyeSBtYXRlcmlhbCkpKVxuXG5cbihkZWZuIGF0dGFjaC10by1kb20gW3JlbmRlcmVyIGVsLW5hbWUgcmVmcmVzaC1mbl1cbiAgKGxldCBbY29udGFpbmVyIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCBlbC1uYW1lKVxuICAgICAgICBzZXR0aW5ncyAoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImRpdlwiKVxuICAgICAgICByZWZyZXNoLWJ1dHRvbiAoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImJ1dHRvblwiKVxuICAgICAgICBidXR0b24tdGV4dCAoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUgXCJSZWZyZXNoXCIpXG4gICAgICAgIGNhbmNlbC1zY3JvbGwgKGZuIFtlXSAoLnByZXZlbnREZWZhdWx0IGUpKV1cbiAgICAoc2V0ISByZWZyZXNoLWJ1dHRvbi5vbmNsaWNrIHJlZnJlc2gtZm4pXG4gICAgKHNldCEgcmVuZGVyZXIuZG9tRWxlbWVudC5vbm1vdXNld2hlZWwgY2FuY2VsLXNjcm9sbClcbiAgICAocmVuZGVyZXIuZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyIFwiTW96TW91c2VQaXhlbFNjcm9sbFwiIGNhbmNlbC1zY3JvbGwgZmFsc2UpXG4gICAgKC5hcHBlbmRDaGlsZCByZWZyZXNoLWJ1dHRvbiBidXR0b24tdGV4dClcbiAgICAoLmFwcGVuZENoaWxkIGNvbnRhaW5lciByZW5kZXJlci5kb21FbGVtZW50KVxuICAgICguYXBwZW5kQ2hpbGQgY29udGFpbmVyIHNldHRpbmdzKVxuICAgICguYXBwZW5kQ2hpbGQgc2V0dGluZ3MgcmVmcmVzaC1idXR0b24pKSlcblxuXG4oZGVmbiB1cGRhdGUtZ2VvbWV0cnkgW2dlb21ldHJ5IGhlaWdodG1hcF1cbiAgKGxvb3AgW2kgMF1cbiAgICAoaWYgKDwgaSBnZW9tZXRyeS52ZXJ0aWNlcy5sZW5ndGgpXG4gICAgICAoZG8gKHNldCEgKC4teiAoYWdldCBnZW9tZXRyeS52ZXJ0aWNlcyBpKSlcbiAgICAgICAgICAgICAgICAoKiB0ZXJyYWluLWhlaWdodCAoYWdldCAoLi1kYXRhIGhlaWdodG1hcCkgaSkpKVxuICAgICAgICAocmVjdXIgKCsgaSAxKSkpKSlcbiAgKGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKVxuICBnZW9tZXRyeSlcblxuXG47IE1haW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBtYWtlLWZpbmFsIFtlbGVtZW50LWlkXVxuICAoZGVmIHNjZW5lIChuZXcgVEhSRUUuU2NlbmUpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQXhpc0hlbHBlciAxMDApKVxuXG4gIChkZWYgY2xvY2sgKG5ldyBUSFJFRS5DbG9jaykpXG4gIChkZWYgY2FtZXJhIChtYWtlLWNhbWVyYSkpXG4gIChkZWYgcmVuZGVyZXIgKG1ha2UtcmVuZGVyZXIpKVxuXG4gIChkZWYgZ2VvbWV0cnkpXG4gIChkZWYgcGxhbmUpXG5cbiAgKHNjZW5lLmFkZCAobWFrZS1kaXJlY3Rpb25hbC1saWdodCkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BbWJpZW50TGlnaHQgMHhmZmZmZmYgMC4wNSkpXG5cbiAgKGRlZm4gcmVmcmVzaCBbXVxuICAgIChsZXQgW2hlaWdodG1hcCAobWFrZS1oZWlnaHRtYXAgNildXG4gICAgICAobCBcIkdlbmVyYXRpbmcgdGVycmFpbi4uLlwiKVxuICAgICAgKHRpbWUgKG1pZHBvaW50LWRpc3BsYWNlbWVudCBoZWlnaHRtYXApKVxuXG4gICAgICAobCBcIlJlYnVpbGRpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAgICh0aW1lXG4gICAgICAgIChzZXQhIGdlb21ldHJ5IChtYWtlLWdlb21ldHJ5IGhlaWdodG1hcCkpXG4gICAgICAgICh1cGRhdGUtZ2VvbWV0cnkgZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIHBsYW5lLi4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2NlbmUucmVtb3ZlIHBsYW5lKVxuICAgICAgICAoc2V0ISBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG4gICAgICAgIChzY2VuZS5hZGQgcGxhbmUpKSkpXG5cbiAgKGF0dGFjaC10by1kb20gcmVuZGVyZXIgZWxlbWVudC1pZCByZWZyZXNoKVxuICAoZGVmIGNvbnRyb2xzIChtYWtlLWNvbnRyb2xzIGNhbWVyYSByZW5kZXJlcikpXG5cbiAgKGRlZm4gcmVuZGVyIFtdXG4gICAgKGxldCBbZGVsdGEgKGNsb2NrLmdldERlbHRhKV1cbiAgICAgIChyZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcmVuZGVyKVxuICAgICAgKC51cGRhdGUgY29udHJvbHMgZGVsdGEpXG4gICAgICAocmVuZGVyZXIucmVuZGVyIHNjZW5lIGNhbWVyYSkpKVxuXG4gIChyZWZyZXNoKVxuICAocmVuZGVyKVxuXG4gIG5pbClcblxuKGRlZm4gcnVuIFtdXG4gIChtYWtlLWZpbmFsIFwiZGVtby1maW5hbFwiKSlcblxuKCQgcnVuKVxuXG5cbjsgdmltOiBsdys9ZG8tdGltZXMgbHcrPWRvLW5lc3RlZCA6XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5mdW5jdGlvbiBpb3RhKG4pIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShuKVxuICBmb3IodmFyIGk9MDsgaTxuOyArK2kpIHtcbiAgICByZXN1bHRbaV0gPSBpXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlvdGEiLCIvKipcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgQnVmZmVyXG4gKlxuICogQXV0aG9yOiAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBMaWNlbnNlOiAgTUlUXG4gKlxuICogYG5wbSBpbnN0YWxsIGlzLWJ1ZmZlcmBcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuICEhKG9iaiAhPSBudWxsICYmXG4gICAgKG9iai5faXNCdWZmZXIgfHwgLy8gRm9yIFNhZmFyaSA1LTcgKG1pc3NpbmcgT2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3RvcilcbiAgICAgIChvYmouY29uc3RydWN0b3IgJiZcbiAgICAgIHR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKVxuICAgICkpXG59XG4iLCJ2YXIgaW90YSA9IHJlcXVpcmUoXCJpb3RhLWFycmF5XCIpXG52YXIgaXNCdWZmZXIgPSByZXF1aXJlKFwiaXMtYnVmZmVyXCIpXG5cbnZhciBoYXNUeXBlZEFycmF5cyAgPSAoKHR5cGVvZiBGbG9hdDY0QXJyYXkpICE9PSBcInVuZGVmaW5lZFwiKVxuXG5mdW5jdGlvbiBjb21wYXJlMXN0KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdXG59XG5cbmZ1bmN0aW9uIG9yZGVyKCkge1xuICB2YXIgc3RyaWRlID0gdGhpcy5zdHJpZGVcbiAgdmFyIHRlcm1zID0gbmV3IEFycmF5KHN0cmlkZS5sZW5ndGgpXG4gIHZhciBpXG4gIGZvcihpPTA7IGk8dGVybXMubGVuZ3RoOyArK2kpIHtcbiAgICB0ZXJtc1tpXSA9IFtNYXRoLmFicyhzdHJpZGVbaV0pLCBpXVxuICB9XG4gIHRlcm1zLnNvcnQoY29tcGFyZTFzdClcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSh0ZXJtcy5sZW5ndGgpXG4gIGZvcihpPTA7IGk8cmVzdWx0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmVzdWx0W2ldID0gdGVybXNbaV1bMV1cbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVDb25zdHJ1Y3RvcihkdHlwZSwgZGltZW5zaW9uKSB7XG4gIHZhciBjbGFzc05hbWUgPSBbXCJWaWV3XCIsIGRpbWVuc2lvbiwgXCJkXCIsIGR0eXBlXS5qb2luKFwiXCIpXG4gIGlmKGRpbWVuc2lvbiA8IDApIHtcbiAgICBjbGFzc05hbWUgPSBcIlZpZXdfTmlsXCIgKyBkdHlwZVxuICB9XG4gIHZhciB1c2VHZXR0ZXJzID0gKGR0eXBlID09PSBcImdlbmVyaWNcIilcblxuICBpZihkaW1lbnNpb24gPT09IC0xKSB7XG4gICAgLy9TcGVjaWFsIGNhc2UgZm9yIHRyaXZpYWwgYXJyYXlzXG4gICAgdmFyIGNvZGUgPVxuICAgICAgXCJmdW5jdGlvbiBcIitjbGFzc05hbWUrXCIoYSl7dGhpcy5kYXRhPWE7fTtcXFxudmFyIHByb3RvPVwiK2NsYXNzTmFtZStcIi5wcm90b3R5cGU7XFxcbnByb3RvLmR0eXBlPSdcIitkdHlwZStcIic7XFxcbnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIC0xfTtcXFxucHJvdG8uc2l6ZT0wO1xcXG5wcm90by5kaW1lbnNpb249LTE7XFxcbnByb3RvLnNoYXBlPXByb3RvLnN0cmlkZT1wcm90by5vcmRlcj1bXTtcXFxucHJvdG8ubG89cHJvdG8uaGk9cHJvdG8udHJhbnNwb3NlPXByb3RvLnN0ZXA9XFxcbmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhKTt9O1xcXG5wcm90by5nZXQ9cHJvdG8uc2V0PWZ1bmN0aW9uKCl7fTtcXFxucHJvdG8ucGljaz1mdW5jdGlvbigpe3JldHVybiBudWxsfTtcXFxucmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF9cIitjbGFzc05hbWUrXCIoYSl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIoYSk7fVwiXG4gICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbihjb2RlKVxuICAgIHJldHVybiBwcm9jZWR1cmUoKVxuICB9IGVsc2UgaWYoZGltZW5zaW9uID09PSAwKSB7XG4gICAgLy9TcGVjaWFsIGNhc2UgZm9yIDBkIGFycmF5c1xuICAgIHZhciBjb2RlID1cbiAgICAgIFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiKGEsZCkge1xcXG50aGlzLmRhdGEgPSBhO1xcXG50aGlzLm9mZnNldCA9IGRcXFxufTtcXFxudmFyIHByb3RvPVwiK2NsYXNzTmFtZStcIi5wcm90b3R5cGU7XFxcbnByb3RvLmR0eXBlPSdcIitkdHlwZStcIic7XFxcbnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub2Zmc2V0fTtcXFxucHJvdG8uZGltZW5zaW9uPTA7XFxcbnByb3RvLnNpemU9MTtcXFxucHJvdG8uc2hhcGU9XFxcbnByb3RvLnN0cmlkZT1cXFxucHJvdG8ub3JkZXI9W107XFxcbnByb3RvLmxvPVxcXG5wcm90by5oaT1cXFxucHJvdG8udHJhbnNwb3NlPVxcXG5wcm90by5zdGVwPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9jb3B5KCkge1xcXG5yZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsdGhpcy5vZmZzZXQpXFxcbn07XFxcbnByb3RvLnBpY2s9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3BpY2soKXtcXFxucmV0dXJuIFRyaXZpYWxBcnJheSh0aGlzLmRhdGEpO1xcXG59O1xcXG5wcm90by52YWx1ZU9mPXByb3RvLmdldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfZ2V0KCl7XFxcbnJldHVybiBcIisodXNlR2V0dGVycyA/IFwidGhpcy5kYXRhLmdldCh0aGlzLm9mZnNldClcIiA6IFwidGhpcy5kYXRhW3RoaXMub2Zmc2V0XVwiKStcblwifTtcXFxucHJvdG8uc2V0PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9zZXQodil7XFxcbnJldHVybiBcIisodXNlR2V0dGVycyA/IFwidGhpcy5kYXRhLnNldCh0aGlzLm9mZnNldCx2KVwiIDogXCJ0aGlzLmRhdGFbdGhpcy5vZmZzZXRdPXZcIikrXCJcXFxufTtcXFxucmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF9cIitjbGFzc05hbWUrXCIoYSxiLGMsZCl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIoYSxkKX1cIlxuICAgIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oXCJUcml2aWFsQXJyYXlcIiwgY29kZSlcbiAgICByZXR1cm4gcHJvY2VkdXJlKENBQ0hFRF9DT05TVFJVQ1RPUlNbZHR5cGVdWzBdKVxuICB9XG5cbiAgdmFyIGNvZGUgPSBbXCIndXNlIHN0cmljdCdcIl1cblxuICAvL0NyZWF0ZSBjb25zdHJ1Y3RvciBmb3Igdmlld1xuICB2YXIgaW5kaWNlcyA9IGlvdGEoZGltZW5zaW9uKVxuICB2YXIgYXJncyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwiaVwiK2kgfSlcbiAgdmFyIGluZGV4X3N0ciA9IFwidGhpcy5vZmZzZXQrXCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICAgIHJldHVybiBcInRoaXMuc3RyaWRlW1wiICsgaSArIFwiXSppXCIgKyBpXG4gICAgICB9KS5qb2luKFwiK1wiKVxuICB2YXIgc2hhcGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJiXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpXG4gIHZhciBzdHJpZGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJjXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpXG4gIGNvZGUucHVzaChcbiAgICBcImZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIihhLFwiICsgc2hhcGVBcmcgKyBcIixcIiArIHN0cmlkZUFyZyArIFwiLGQpe3RoaXMuZGF0YT1hXCIsXG4gICAgICBcInRoaXMuc2hhcGU9W1wiICsgc2hhcGVBcmcgKyBcIl1cIixcbiAgICAgIFwidGhpcy5zdHJpZGU9W1wiICsgc3RyaWRlQXJnICsgXCJdXCIsXG4gICAgICBcInRoaXMub2Zmc2V0PWR8MH1cIixcbiAgICBcInZhciBwcm90bz1cIitjbGFzc05hbWUrXCIucHJvdG90eXBlXCIsXG4gICAgXCJwcm90by5kdHlwZT0nXCIrZHR5cGUrXCInXCIsXG4gICAgXCJwcm90by5kaW1lbnNpb249XCIrZGltZW5zaW9uKVxuXG4gIC8vdmlldy5zaXplOlxuICBjb2RlLnB1c2goXCJPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sJ3NpemUnLHtnZXQ6ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3NpemUoKXtcXFxucmV0dXJuIFwiK2luZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwidGhpcy5zaGFwZVtcIitpK1wiXVwiIH0pLmpvaW4oXCIqXCIpLFxuXCJ9fSlcIilcblxuICAvL3ZpZXcub3JkZXI6XG4gIGlmKGRpbWVuc2lvbiA9PT0gMSkge1xuICAgIGNvZGUucHVzaChcInByb3RvLm9yZGVyPVswXVwiKVxuICB9IGVsc2Uge1xuICAgIGNvZGUucHVzaChcIk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm90bywnb3JkZXInLHtnZXQ6XCIpXG4gICAgaWYoZGltZW5zaW9uIDwgNCkge1xuICAgICAgY29kZS5wdXNoKFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX29yZGVyKCl7XCIpXG4gICAgICBpZihkaW1lbnNpb24gPT09IDIpIHtcbiAgICAgICAgY29kZS5wdXNoKFwicmV0dXJuIChNYXRoLmFicyh0aGlzLnN0cmlkZVswXSk+TWF0aC5hYnModGhpcy5zdHJpZGVbMV0pKT9bMSwwXTpbMCwxXX19KVwiKVxuICAgICAgfSBlbHNlIGlmKGRpbWVuc2lvbiA9PT0gMykge1xuICAgICAgICBjb2RlLnB1c2goXG5cInZhciBzMD1NYXRoLmFicyh0aGlzLnN0cmlkZVswXSksczE9TWF0aC5hYnModGhpcy5zdHJpZGVbMV0pLHMyPU1hdGguYWJzKHRoaXMuc3RyaWRlWzJdKTtcXFxuaWYoczA+czEpe1xcXG5pZihzMT5zMil7XFxcbnJldHVybiBbMiwxLDBdO1xcXG59ZWxzZSBpZihzMD5zMil7XFxcbnJldHVybiBbMSwyLDBdO1xcXG59ZWxzZXtcXFxucmV0dXJuIFsxLDAsMl07XFxcbn1cXFxufWVsc2UgaWYoczA+czIpe1xcXG5yZXR1cm4gWzIsMCwxXTtcXFxufWVsc2UgaWYoczI+czEpe1xcXG5yZXR1cm4gWzAsMSwyXTtcXFxufWVsc2V7XFxcbnJldHVybiBbMCwyLDFdO1xcXG59fX0pXCIpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUucHVzaChcIk9SREVSfSlcIilcbiAgICB9XG4gIH1cblxuICAvL3ZpZXcuc2V0KGkwLCAuLi4sIHYpOlxuICBjb2RlLnB1c2goXG5cInByb3RvLnNldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfc2V0KFwiK2FyZ3Muam9pbihcIixcIikrXCIsdil7XCIpXG4gIGlmKHVzZUdldHRlcnMpIHtcbiAgICBjb2RlLnB1c2goXCJyZXR1cm4gdGhpcy5kYXRhLnNldChcIitpbmRleF9zdHIrXCIsdil9XCIpXG4gIH0gZWxzZSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YVtcIitpbmRleF9zdHIrXCJdPXZ9XCIpXG4gIH1cblxuICAvL3ZpZXcuZ2V0KGkwLCAuLi4pOlxuICBjb2RlLnB1c2goXCJwcm90by5nZXQ9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2dldChcIithcmdzLmpvaW4oXCIsXCIpK1wiKXtcIilcbiAgaWYodXNlR2V0dGVycykge1xuICAgIGNvZGUucHVzaChcInJldHVybiB0aGlzLmRhdGEuZ2V0KFwiK2luZGV4X3N0citcIil9XCIpXG4gIH0gZWxzZSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YVtcIitpbmRleF9zdHIrXCJdfVwiKVxuICB9XG5cbiAgLy92aWV3LmluZGV4OlxuICBjb2RlLnB1c2goXG4gICAgXCJwcm90by5pbmRleD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfaW5kZXgoXCIsIGFyZ3Muam9pbigpLCBcIil7cmV0dXJuIFwiK2luZGV4X3N0citcIn1cIilcblxuICAvL3ZpZXcuaGkoKTpcbiAgY29kZS5wdXNoKFwicHJvdG8uaGk9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2hpKFwiK2FyZ3Muam9pbihcIixcIikrXCIpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSxcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gW1wiKHR5cGVvZiBpXCIsaSxcIiE9PSdudW1iZXInfHxpXCIsaSxcIjwwKT90aGlzLnNoYXBlW1wiLCBpLCBcIl06aVwiLCBpLFwifDBcIl0uam9pbihcIlwiKVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcInRoaXMuc3RyaWRlW1wiK2kgKyBcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLHRoaXMub2Zmc2V0KX1cIilcblxuICAvL3ZpZXcubG8oKTpcbiAgdmFyIGFfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwiYVwiK2krXCI9dGhpcy5zaGFwZVtcIitpK1wiXVwiIH0pXG4gIHZhciBjX3ZhcnMgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBcImNcIitpK1wiPXRoaXMuc3RyaWRlW1wiK2krXCJdXCIgfSlcbiAgY29kZS5wdXNoKFwicHJvdG8ubG89ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2xvKFwiK2FyZ3Muam9pbihcIixcIikrXCIpe3ZhciBiPXRoaXMub2Zmc2V0LGQ9MCxcIithX3ZhcnMuam9pbihcIixcIikrXCIsXCIrY192YXJzLmpvaW4oXCIsXCIpKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGNvZGUucHVzaChcblwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicmJmlcIitpK1wiPj0wKXtcXFxuZD1pXCIraStcInwwO1xcXG5iKz1jXCIraStcIipkO1xcXG5hXCIraStcIi09ZH1cIilcbiAgfVxuICBjb2RlLnB1c2goXCJyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYVwiK2lcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJjXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLGIpfVwiKVxuXG4gIC8vdmlldy5zdGVwKCk6XG4gIGNvZGUucHVzaChcInByb3RvLnN0ZXA9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3N0ZXAoXCIrYXJncy5qb2luKFwiLFwiKStcIil7dmFyIFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImFcIitpK1wiPXRoaXMuc2hhcGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImJcIitpK1wiPXRoaXMuc3RyaWRlW1wiK2krXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIixjPXRoaXMub2Zmc2V0LGQ9MCxjZWlsPU1hdGguY2VpbFwiKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGNvZGUucHVzaChcblwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicpe1xcXG5kPWlcIitpK1wifDA7XFxcbmlmKGQ8MCl7XFxcbmMrPWJcIitpK1wiKihhXCIraStcIi0xKTtcXFxuYVwiK2krXCI9Y2VpbCgtYVwiK2krXCIvZClcXFxufWVsc2V7XFxcbmFcIitpK1wiPWNlaWwoYVwiK2krXCIvZClcXFxufVxcXG5iXCIraStcIio9ZFxcXG59XCIpXG4gIH1cbiAgY29kZS5wdXNoKFwicmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImFcIiArIGlcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJiXCIgKyBpXG4gICAgfSkuam9pbihcIixcIikrXCIsYyl9XCIpXG5cbiAgLy92aWV3LnRyYW5zcG9zZSgpOlxuICB2YXIgdFNoYXBlID0gbmV3IEFycmF5KGRpbWVuc2lvbilcbiAgdmFyIHRTdHJpZGUgPSBuZXcgQXJyYXkoZGltZW5zaW9uKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIHRTaGFwZVtpXSA9IFwiYVtpXCIraStcIl1cIlxuICAgIHRTdHJpZGVbaV0gPSBcImJbaVwiK2krXCJdXCJcbiAgfVxuICBjb2RlLnB1c2goXCJwcm90by50cmFuc3Bvc2U9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3RyYW5zcG9zZShcIithcmdzK1wiKXtcIitcbiAgICBhcmdzLm1hcChmdW5jdGlvbihuLGlkeCkgeyByZXR1cm4gbiArIFwiPShcIiArIG4gKyBcIj09PXVuZGVmaW5lZD9cIiArIGlkeCArIFwiOlwiICsgbiArIFwifDApXCJ9KS5qb2luKFwiO1wiKSxcbiAgICBcInZhciBhPXRoaXMuc2hhcGUsYj10aGlzLnN0cmlkZTtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrdFNoYXBlLmpvaW4oXCIsXCIpK1wiLFwiK3RTdHJpZGUuam9pbihcIixcIikrXCIsdGhpcy5vZmZzZXQpfVwiKVxuXG4gIC8vdmlldy5waWNrKCk6XG4gIGNvZGUucHVzaChcInByb3RvLnBpY2s9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3BpY2soXCIrYXJncytcIil7dmFyIGE9W10sYj1bXSxjPXRoaXMub2Zmc2V0XCIpXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgY29kZS5wdXNoKFwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicmJmlcIitpK1wiPj0wKXtjPShjK3RoaXMuc3RyaWRlW1wiK2krXCJdKmlcIitpK1wiKXwwfWVsc2V7YS5wdXNoKHRoaXMuc2hhcGVbXCIraStcIl0pO2IucHVzaCh0aGlzLnN0cmlkZVtcIitpK1wiXSl9XCIpXG4gIH1cbiAgY29kZS5wdXNoKFwidmFyIGN0b3I9Q1RPUl9MSVNUW2EubGVuZ3RoKzFdO3JldHVybiBjdG9yKHRoaXMuZGF0YSxhLGIsYyl9XCIpXG5cbiAgLy9BZGQgcmV0dXJuIHN0YXRlbWVudFxuICBjb2RlLnB1c2goXCJyZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0X1wiK2NsYXNzTmFtZStcIihkYXRhLHNoYXBlLHN0cmlkZSxvZmZzZXQpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKGRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwic2hhcGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcInN0cmlkZVtcIitpK1wiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsb2Zmc2V0KX1cIilcblxuICAvL0NvbXBpbGUgcHJvY2VkdXJlXG4gIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oXCJDVE9SX0xJU1RcIiwgXCJPUkRFUlwiLCBjb2RlLmpvaW4oXCJcXG5cIikpXG4gIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV0sIG9yZGVyKVxufVxuXG5mdW5jdGlvbiBhcnJheURUeXBlKGRhdGEpIHtcbiAgaWYoaXNCdWZmZXIoZGF0YSkpIHtcbiAgICByZXR1cm4gXCJidWZmZXJcIlxuICB9XG4gIGlmKGhhc1R5cGVkQXJyYXlzKSB7XG4gICAgc3dpdGNoKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkYXRhKSkge1xuICAgICAgY2FzZSBcIltvYmplY3QgRmxvYXQ2NEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJmbG9hdDY0XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEZsb2F0MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiZmxvYXQzMlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBJbnQ4QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImludDhcIlxuICAgICAgY2FzZSBcIltvYmplY3QgSW50MTZBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiaW50MTZcIlxuICAgICAgY2FzZSBcIltvYmplY3QgSW50MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiaW50MzJcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDhBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDhcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDE2QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcInVpbnQxNlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBVaW50MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDMyXCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJ1aW50OF9jbGFtcGVkXCJcbiAgICB9XG4gIH1cbiAgaWYoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgIHJldHVybiBcImFycmF5XCJcbiAgfVxuICByZXR1cm4gXCJnZW5lcmljXCJcbn1cblxudmFyIENBQ0hFRF9DT05TVFJVQ1RPUlMgPSB7XG4gIFwiZmxvYXQzMlwiOltdLFxuICBcImZsb2F0NjRcIjpbXSxcbiAgXCJpbnQ4XCI6W10sXG4gIFwiaW50MTZcIjpbXSxcbiAgXCJpbnQzMlwiOltdLFxuICBcInVpbnQ4XCI6W10sXG4gIFwidWludDE2XCI6W10sXG4gIFwidWludDMyXCI6W10sXG4gIFwiYXJyYXlcIjpbXSxcbiAgXCJ1aW50OF9jbGFtcGVkXCI6W10sXG4gIFwiYnVmZmVyXCI6W10sXG4gIFwiZ2VuZXJpY1wiOltdXG59XG5cbjsoZnVuY3Rpb24oKSB7XG4gIGZvcih2YXIgaWQgaW4gQ0FDSEVEX0NPTlNUUlVDVE9SUykge1xuICAgIENBQ0hFRF9DT05TVFJVQ1RPUlNbaWRdLnB1c2goY29tcGlsZUNvbnN0cnVjdG9yKGlkLCAtMSkpXG4gIH1cbn0pO1xuXG5mdW5jdGlvbiB3cmFwcGVkTkRBcnJheUN0b3IoZGF0YSwgc2hhcGUsIHN0cmlkZSwgb2Zmc2V0KSB7XG4gIGlmKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBjdG9yID0gQ0FDSEVEX0NPTlNUUlVDVE9SUy5hcnJheVswXVxuICAgIHJldHVybiBjdG9yKFtdKVxuICB9IGVsc2UgaWYodHlwZW9mIGRhdGEgPT09IFwibnVtYmVyXCIpIHtcbiAgICBkYXRhID0gW2RhdGFdXG4gIH1cbiAgaWYoc2hhcGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHNoYXBlID0gWyBkYXRhLmxlbmd0aCBdXG4gIH1cbiAgdmFyIGQgPSBzaGFwZS5sZW5ndGhcbiAgaWYoc3RyaWRlID09PSB1bmRlZmluZWQpIHtcbiAgICBzdHJpZGUgPSBuZXcgQXJyYXkoZClcbiAgICBmb3IodmFyIGk9ZC0xLCBzej0xOyBpPj0wOyAtLWkpIHtcbiAgICAgIHN0cmlkZVtpXSA9IHN6XG4gICAgICBzeiAqPSBzaGFwZVtpXVxuICAgIH1cbiAgfVxuICBpZihvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIG9mZnNldCA9IDBcbiAgICBmb3IodmFyIGk9MDsgaTxkOyArK2kpIHtcbiAgICAgIGlmKHN0cmlkZVtpXSA8IDApIHtcbiAgICAgICAgb2Zmc2V0IC09IChzaGFwZVtpXS0xKSpzdHJpZGVbaV1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGR0eXBlID0gYXJyYXlEVHlwZShkYXRhKVxuICB2YXIgY3Rvcl9saXN0ID0gQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV1cbiAgd2hpbGUoY3Rvcl9saXN0Lmxlbmd0aCA8PSBkKzEpIHtcbiAgICBjdG9yX2xpc3QucHVzaChjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGN0b3JfbGlzdC5sZW5ndGgtMSkpXG4gIH1cbiAgdmFyIGN0b3IgPSBjdG9yX2xpc3RbZCsxXVxuICByZXR1cm4gY3RvcihkYXRhLCBzaGFwZSwgc3RyaWRlLCBvZmZzZXQpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHBlZE5EQXJyYXlDdG9yXG4iXX0= diff -r a52d61eb7e85 -r 2d9281a1f7e7 media/js/terrain3.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/media/js/terrain3.js Sat Jun 25 15:57:05 2016 +0000 @@ -0,0 +1,951 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o elø1 ? (function () { + return minø1 = elø1; + })() : void 0; + }.call(this)); + return loop[0] = inc(index1ø1), loop; + })() : void 0; + } while (index1ø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this)); + return function () { + var spanø1 = maxø1 - minø1; + return function () { + var array4ø1 = heightmap; + return function () { + var G__5ø1 = array4ø1.shape[0]; + return function loop() { + var recur = loop; + var xø1 = 0; + do { + recur = xø1 < G__5ø1 ? (function () { + (function () { + var G__6ø1 = array4ø1.shape[1]; + return function loop() { + var recur = loop; + var yø1 = 0; + do { + recur = yø1 < G__6ø1 ? (function () { + (function () { + return heightmapSet(heightmap, xø1, yø1, (heightmapGet(heightmap, xø1, yø1) - minø1) / spanø1); + })(); + return loop[0] = inc(yø1), loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this)); + return loop[0] = inc(xø1), loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); + }.call(this); + }.call(this); +}; +var makeHeightmap = exports.makeHeightmap = function makeHeightmap(exponent) { + return function () { + var resolutionø1 = Math.pow(2, exponent) + 1; + return function () { + var heightmapø1 = ndarray(new Float64Array(resolutionø1 * resolutionø1), [ + resolutionø1, + resolutionø1 + ]); + heightmapø1.exponent = exponent; + heightmapø1.resolution = resolutionø1; + heightmapø1.last = dec(resolutionø1); + return heightmapø1; + }.call(this); + }.call(this); +}; +var topLeftCorner = exports.topLeftCorner = function topLeftCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(0, 0).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var topRightCorner = exports.topRightCorner = function topRightCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(centerø1, 0).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var bottomLeftCorner = exports.bottomLeftCorner = function bottomLeftCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(0, centerø1).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var bottomRightCorner = exports.bottomRightCorner = function bottomRightCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(centerø1, centerø1).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var dsInitCorners = exports.dsInitCorners = function dsInitCorners(heightmap) { + return function () { + var lastø1 = heightmapLastIndex(heightmap); + heightmapSet(heightmap, 0, 0, rand()); + heightmapSet(heightmap, 0, lastø1, rand()); + heightmapSet(heightmap, lastø1, 0, rand()); + return heightmapSet(heightmap, lastø1, lastø1, rand()); + }.call(this); +}; +var dsSquare = exports.dsSquare = function dsSquare(heightmap, x, y, radius, spread) { + return function () { + var newHeightø1 = jitter(average4(heightmapGet(heightmap, x - radius, y - radius), heightmapGet(heightmap, x - radius, y + radius), heightmapGet(heightmap, x + radius, y - radius), heightmapGet(heightmap, x + radius, y + radius)), spread); + return heightmapSet(heightmap, x, y, newHeightø1); + }.call(this); +}; +var dsDiamond = exports.dsDiamond = function dsDiamond(heightmap, x, y, radius, spread) { + return function () { + var newHeightø1 = jitter(safeAverage(heightmapGetSafe(heightmap, x - radius, y), heightmapGetSafe(heightmap, x + radius, y), heightmapGetSafe(heightmap, x, y - radius), heightmapGetSafe(heightmap, x, y + radius)), spread); + return heightmapSet(heightmap, x, y, newHeightø1); + }.call(this); +}; +var dsSquares = exports.dsSquares = function dsSquares(heightmap, radius, spread) { + return function () { + var start8ø1 = radius; + var end9ø1 = heightmapResolution(heightmap); + var stride7ø1 = 2 * radius; + return function loop() { + var recur = loop; + var xø1 = start8ø1; + do { + recur = xø1 < end9ø1 ? (function () { + (function loop() { + var recur = loop; + var yø1 = start8ø1; + do { + recur = yø1 < end9ø1 ? (function () { + (function () { + return dsSquare(heightmap, xø1, yø1, radius, spread); + })(); + return loop[0] = yø1 + stride7ø1, loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this)); + return loop[0] = xø1 + stride7ø1, loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); +}; +var dsDiamonds = exports.dsDiamonds = function dsDiamonds(heightmap, radius, spread) { + return function () { + var sizeø1 = heightmapResolution(heightmap); + return function () { + var start11ø1 = 0; + var end12ø1 = sizeø1; + var stride10ø1 = radius; + return function loop() { + var recur = loop; + var yø1 = start11ø1; + do { + recur = yø1 < end12ø1 ? (function () { + (function () { + return function () { + var shiftø1 = isEven(yø1 / radius) ? radius : 0; + return function () { + var start14ø1 = shiftø1; + var end15ø1 = sizeø1; + var stride13ø1 = 2 * radius; + return function loop() { + var recur = loop; + var xø1 = start14ø1; + do { + recur = xø1 < end15ø1 ? (function () { + (function () { + return dsDiamond(heightmap, xø1, yø1, radius, spread); + })(); + return loop[0] = xø1 + stride13ø1, loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); + })(); + return loop[0] = yø1 + stride10ø1, loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); +}; +var diamondSquare = exports.diamondSquare = function diamondSquare(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + (function loop() { + var recur = loop; + var radiusø1 = centerø1; + var spreadø1 = initialSpreadø1; + do { + recur = radiusø1 >= 1 ? (function () { + dsSquares(heightmap, radiusø1, spreadø1); + dsDiamonds(heightmap, radiusø1, spreadø1); + return loop[0] = radiusø1 / 2, loop[1] = spreadø1 * spreadReductionø1, loop; + })() : void 0; + } while (radiusø1 = loop[0], spreadø1 = loop[1], recur === loop); + return recur; + }.call(this)); + return normalize(heightmap); + }.call(this); +}; +var diamondSquare1 = exports.diamondSquare1 = function diamondSquare1(heightmap) { + dsInitCorners(heightmap); + return normalize(heightmap); +}; +var diamondSquare2 = exports.diamondSquare2 = function diamondSquare2(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + dsSquares(heightmap, centerø1, initialSpreadø1); + return normalize(heightmap); + }.call(this); +}; +var diamondSquare3 = exports.diamondSquare3 = function diamondSquare3(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + dsSquares(heightmap, centerø1, initialSpreadø1); + dsDiamonds(heightmap, centerø1, initialSpreadø1); + dsSquares(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø1); + dsDiamonds(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø1); + return normalize(heightmap); + }.call(this); +}; +var makeDirectionalLight = exports.makeDirectionalLight = function makeDirectionalLight() { + return function () { + var lightø1 = new THREE.DirectionalLight(16777215, 1); + lightø1.position.set(100, 0, 150); + return lightø1; + }.call(this); +}; +var makeCamera = exports.makeCamera = function makeCamera() { + return function () { + var cameraø1 = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000); + cameraø1.position.set(0, -100, 150); + return cameraø1; + }.call(this); +}; +var makeRenderer = exports.makeRenderer = function makeRenderer() { + return function () { + var rendererø1 = new THREE.WebGLRenderer({ 'antialias': false }); + rendererø1.setClearColor(16777215); + rendererø1.setSize(width, height); + rendererø1.setPixelRatio(2); + return rendererø1; + }.call(this); +}; +var makeGeometry = exports.makeGeometry = function makeGeometry(heightmap) { + return function () { + var resolutionø1 = heightmap.shape[0]; + var geometryø1 = new THREE.PlaneGeometry(terrainSize, terrainSize, resolutionø1 - 1, resolutionø1 - 1); + return geometryø1; + }.call(this); +}; +var makeControls = exports.makeControls = function makeControls(camera, renderer) { + return function () { + var controlsø1 = new THREE.TrackballControls(camera, renderer.domElement); + controlsø1.rotateSpeed = 1.4; + controlsø1.zoomSpeed = 0.5; + controlsø1.staticMoving = true; + controlsø1.dynamicDampingFactor = 0.3; + return controlsø1; + }.call(this); +}; +var makePlane = exports.makePlane = function makePlane(geometry) { + return function () { + var materialø1 = new THREE.MeshLambertMaterial({ + 'wireframe': wireframe, + 'wireframeLinewidth': wireframeWidth, + 'color': 47872 + }); + return new THREE.Mesh(geometry, materialø1); + }.call(this); +}; +var attachToDom = exports.attachToDom = function attachToDom(renderer, elName, refreshFn) { + return function () { + var containerø1 = document.getElementById(elName); + var settingsø1 = document.createElement('div'); + var refreshButtonø1 = document.createElement('button'); + var buttonTextø1 = document.createTextNode('Refresh'); + var cancelScrollø1 = function (e) { + return e.preventDefault(); + }; + refreshButtonø1.onclick = refreshFn; + renderer.domElement.onmousewheel = cancelScrollø1; + renderer.domElement.addEventListener('MozMousePixelScroll', cancelScrollø1, false); + refreshButtonø1.appendChild(buttonTextø1); + containerø1.appendChild(renderer.domElement); + containerø1.appendChild(settingsø1); + return settingsø1.appendChild(refreshButtonø1); + }.call(this); +}; +var updateGeometry = exports.updateGeometry = function updateGeometry(geometry, heightmap) { + (function loop() { + var recur = loop; + var iø1 = 0; + do { + recur = iø1 < geometry.vertices.length ? (function () { + geometry.vertices[iø1].z = terrainHeight * heightmap.data[iø1]; + return loop[0] = iø1 + 1, loop; + })() : void 0; + } while (iø1 = loop[0], recur === loop); + return recur; + }.call(this)); + geometry.computeVertexNormals(); + return geometry; +}; +var makeDemo = exports.makeDemo = function makeDemo(elementId, algorithm, size) { + var scene = new THREE.Scene(); + scene.add(new THREE.AxisHelper(100)); + var clock = new THREE.Clock(); + var camera = makeCamera(); + var renderer = makeRenderer(); + var geometry = void 0; + var plane = void 0; + scene.add(makeDirectionalLight()); + scene.add(new THREE.AmbientLight(16777215, 0.05)); + var refresh = function refresh() { + return function () { + var heightmapø1 = makeHeightmap(size); + console.log('Generating terrain...'); + (function () { + var G__16ø1 = new Date().getTime(); + var G__18ø1 = (function () { + return algorithm(heightmapø1); + })(); + var G__17ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__17ø1 - G__16ø1) + 'ms.'); + return G__18ø1; + }.call(this)); + console.log('Rebuilding geometry...'); + (function () { + var G__19ø1 = new Date().getTime(); + var G__21ø1 = (function () { + geometry = makeGeometry(heightmapø1); + return updateGeometry(geometry, heightmapø1); + })(); + var G__20ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__20ø1 - G__19ø1) + 'ms.'); + return G__21ø1; + }.call(this)); + console.log('Rebuilding plane...'); + return function () { + var G__22ø1 = new Date().getTime(); + var G__24ø1 = (function () { + scene.remove(plane); + plane = makePlane(geometry); + return scene.add(plane); + })(); + var G__23ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__23ø1 - G__22ø1) + 'ms.'); + return G__24ø1; + }.call(this); + }.call(this); + }; + attachToDom(renderer, elementId, refresh); + var controls = makeControls(camera, renderer); + var render = function render() { + return function () { + var deltaø1 = clock.getDelta(); + requestAnimationFrame(render); + controls.update(deltaø1); + return renderer.render(scene, camera); + }.call(this); + }; + refresh(); + render(); + return void 0; +}; +var makeFinal = exports.makeFinal = function makeFinal(elementId) { + var scene = new THREE.Scene(); + scene.add(new THREE.AxisHelper(100)); + var clock = new THREE.Clock(); + var camera = makeCamera(); + var renderer = makeRenderer(); + var geometry = void 0; + var plane = void 0; + scene.add(makeDirectionalLight()); + scene.add(new THREE.AmbientLight(16777215, 0.05)); + var refresh = function refresh() { + return function () { + var heightmapø1 = makeHeightmap(6); + console.log('Generating terrain...'); + (function () { + var G__25ø1 = new Date().getTime(); + var G__27ø1 = (function () { + return diamondSquare(heightmapø1); + })(); + var G__26ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__26ø1 - G__25ø1) + 'ms.'); + return G__27ø1; + }.call(this)); + console.log('Rebuilding geometry...'); + (function () { + var G__28ø1 = new Date().getTime(); + var G__30ø1 = (function () { + geometry = makeGeometry(heightmapø1); + return updateGeometry(geometry, heightmapø1); + })(); + var G__29ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__29ø1 - G__28ø1) + 'ms.'); + return G__30ø1; + }.call(this)); + console.log('Rebuilding plane...'); + return function () { + var G__31ø1 = new Date().getTime(); + var G__33ø1 = (function () { + scene.remove(plane); + plane = makePlane(geometry); + return scene.add(plane); + })(); + var G__32ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__32ø1 - G__31ø1) + 'ms.'); + return G__33ø1; + }.call(this); + }.call(this); + }; + attachToDom(renderer, elementId, refresh); + var controls = makeControls(camera, renderer); + var render = function render() { + return function () { + var deltaø1 = clock.getDelta(); + requestAnimationFrame(render); + controls.update(deltaø1); + return renderer.render(scene, camera); + }.call(this); + }; + refresh(); + render(); + return void 0; +}; +var run = exports.run = function run() { + makeDemo('demo-1', diamondSquare1, 2); + makeDemo('demo-2', diamondSquare2, 4); + makeDemo('demo-3', diamondSquare3, 4); + return makeFinal('demo-final'); +}; +$(run); + + +},{"ndarray":4}],2:[function(require,module,exports){ +"use strict" + +function iota(n) { + var result = new Array(n) + for(var i=0; i + * License: MIT + * + * `npm install is-buffer` + */ + +module.exports = function (obj) { + return !!(obj != null && + (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor) + (obj.constructor && + typeof obj.constructor.isBuffer === 'function' && + obj.constructor.isBuffer(obj)) + )) +} + +},{}],4:[function(require,module,exports){ +var iota = require("iota-array") +var isBuffer = require("is-buffer") + +var hasTypedArrays = ((typeof Float64Array) !== "undefined") + +function compare1st(a, b) { + return a[0] - b[0] +} + +function order() { + var stride = this.stride + var terms = new Array(stride.length) + var i + for(i=0; iMath.abs(this.stride[1]))?[1,0]:[0,1]}})") + } else if(dimension === 3) { + code.push( +"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\ +if(s0>s1){\ +if(s1>s2){\ +return [2,1,0];\ +}else if(s0>s2){\ +return [1,2,0];\ +}else{\ +return [1,0,2];\ +}\ +}else if(s0>s2){\ +return [2,0,1];\ +}else if(s2>s1){\ +return [0,1,2];\ +}else{\ +return [0,2,1];\ +}}})") + } + } else { + code.push("ORDER})") + } + } + + //view.set(i0, ..., v): + code.push( +"proto.set=function "+className+"_set("+args.join(",")+",v){") + if(useGetters) { + code.push("return this.data.set("+index_str+",v)}") + } else { + code.push("return this.data["+index_str+"]=v}") + } + + //view.get(i0, ...): + code.push("proto.get=function "+className+"_get("+args.join(",")+"){") + if(useGetters) { + code.push("return this.data.get("+index_str+")}") + } else { + code.push("return this.data["+index_str+"]}") + } + + //view.index: + code.push( + "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}") + + //view.hi(): + code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+ + indices.map(function(i) { + return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("") + }).join(",")+","+ + indices.map(function(i) { + return "this.stride["+i + "]" + }).join(",")+",this.offset)}") + + //view.lo(): + var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" }) + var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" }) + code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(",")) + for(var i=0; i=0){\ +d=i"+i+"|0;\ +b+=c"+i+"*d;\ +a"+i+"-=d}") + } + code.push("return new "+className+"(this.data,"+ + indices.map(function(i) { + return "a"+i + }).join(",")+","+ + indices.map(function(i) { + return "c"+i + }).join(",")+",b)}") + + //view.step(): + code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+ + indices.map(function(i) { + return "a"+i+"=this.shape["+i+"]" + }).join(",")+","+ + indices.map(function(i) { + return "b"+i+"=this.stride["+i+"]" + }).join(",")+",c=this.offset,d=0,ceil=Math.ceil") + for(var i=0; i=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}") + } + code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}") + + //Add return statement + code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+ + indices.map(function(i) { + return "shape["+i+"]" + }).join(",")+","+ + indices.map(function(i) { + return "stride["+i+"]" + }).join(",")+",offset)}") + + //Compile procedure + var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n")) + return procedure(CACHED_CONSTRUCTORS[dtype], order) +} + +function arrayDType(data) { + if(isBuffer(data)) { + return "buffer" + } + if(hasTypedArrays) { + switch(Object.prototype.toString.call(data)) { + case "[object Float64Array]": + return "float64" + case "[object Float32Array]": + return "float32" + case "[object Int8Array]": + return "int8" + case "[object Int16Array]": + return "int16" + case "[object Int32Array]": + return "int32" + case "[object Uint8Array]": + return "uint8" + case "[object Uint16Array]": + return "uint16" + case "[object Uint32Array]": + return "uint32" + case "[object Uint8ClampedArray]": + return "uint8_clamped" + } + } + if(Array.isArray(data)) { + return "array" + } + return "generic" +} + +var CACHED_CONSTRUCTORS = { + "float32":[], + "float64":[], + "int8":[], + "int16":[], + "int32":[], + "uint8":[], + "uint16":[], + "uint32":[], + "array":[], + "uint8_clamped":[], + "buffer":[], + "generic":[] +} + +;(function() { + for(var id in CACHED_CONSTRUCTORS) { + CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1)) + } +}); + +function wrappedNDArrayCtor(data, shape, stride, offset) { + if(data === undefined) { + var ctor = CACHED_CONSTRUCTORS.array[0] + return ctor([]) + } else if(typeof data === "number") { + data = [data] + } + if(shape === undefined) { + shape = [ data.length ] + } + var d = shape.length + if(stride === undefined) { + stride = new Array(d) + for(var i=d-1, sz=1; i>=0; --i) { + stride[i] = sz + sz *= shape[i] + } + } + if(offset === undefined) { + offset = 0 + for(var i=0; i elø1 ? (function () { + return minø1 = elø1; + })() : void 0; + }.call(this)); + return loop[0] = inc(index1ø1), loop; + })() : void 0; + } while (index1ø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this)); + return function () { + var spanø1 = maxø1 - minø1; + return function () { + var array4ø1 = heightmap; + return function () { + var G__5ø1 = array4ø1.shape[0]; + return function loop() { + var recur = loop; + var xø1 = 0; + do { + recur = xø1 < G__5ø1 ? (function () { + (function () { + var G__6ø1 = array4ø1.shape[1]; + return function loop() { + var recur = loop; + var yø1 = 0; + do { + recur = yø1 < G__6ø1 ? (function () { + (function () { + return heightmapSet(heightmap, xø1, yø1, (heightmapGet(heightmap, xø1, yø1) - minø1) / spanø1); + })(); + return loop[0] = inc(yø1), loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this)); + return loop[0] = inc(xø1), loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); + }.call(this); + }.call(this); +}; +var makeHeightmap = exports.makeHeightmap = function makeHeightmap(exponent) { + return function () { + var resolutionø1 = Math.pow(2, exponent) + 1; + return function () { + var heightmapø1 = ndarray(new Float64Array(resolutionø1 * resolutionø1), [ + resolutionø1, + resolutionø1 + ]); + heightmapø1.exponent = exponent; + heightmapø1.resolution = resolutionø1; + heightmapø1.last = dec(resolutionø1); + return heightmapø1; + }.call(this); + }.call(this); +}; +var topLeftCorner = exports.topLeftCorner = function topLeftCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(0, 0).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var topRightCorner = exports.topRightCorner = function topRightCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(centerø1, 0).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var bottomLeftCorner = exports.bottomLeftCorner = function bottomLeftCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(0, centerø1).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var bottomRightCorner = exports.bottomRightCorner = function bottomRightCorner(heightmap) { + return function () { + var centerø1 = heightmapCenterIndex(heightmap); + return heightmap.lo(centerø1, centerø1).hi(inc(centerø1), inc(centerø1)); + }.call(this); +}; +var dsInitCorners = exports.dsInitCorners = function dsInitCorners(heightmap) { + return function () { + var lastø1 = heightmapLastIndex(heightmap); + heightmapSet(heightmap, 0, 0, rand()); + heightmapSet(heightmap, 0, lastø1, rand()); + heightmapSet(heightmap, lastø1, 0, rand()); + return heightmapSet(heightmap, lastø1, lastø1, rand()); + }.call(this); +}; +var dsSquare = exports.dsSquare = function dsSquare(heightmap, x, y, radius, spread) { + return function () { + var newHeightø1 = jitter(average4(heightmapGet(heightmap, x - radius, y - radius), heightmapGet(heightmap, x - radius, y + radius), heightmapGet(heightmap, x + radius, y - radius), heightmapGet(heightmap, x + radius, y + radius)), spread); + return heightmapSet(heightmap, x, y, newHeightø1); + }.call(this); +}; +var dsDiamond = exports.dsDiamond = function dsDiamond(heightmap, x, y, radius, spread) { + return function () { + var newHeightø1 = jitter(safeAverage(heightmapGetSafe(heightmap, x - radius, y), heightmapGetSafe(heightmap, x + radius, y), heightmapGetSafe(heightmap, x, y - radius), heightmapGetSafe(heightmap, x, y + radius)), spread); + return heightmapSet(heightmap, x, y, newHeightø1); + }.call(this); +}; +var dsSquares = exports.dsSquares = function dsSquares(heightmap, radius, spread) { + return function () { + var start8ø1 = radius; + var end9ø1 = heightmapResolution(heightmap); + var stride7ø1 = 2 * radius; + return function loop() { + var recur = loop; + var xø1 = start8ø1; + do { + recur = xø1 < end9ø1 ? (function () { + (function loop() { + var recur = loop; + var yø1 = start8ø1; + do { + recur = yø1 < end9ø1 ? (function () { + (function () { + return dsSquare(heightmap, xø1, yø1, radius, spread); + })(); + return loop[0] = yø1 + stride7ø1, loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this)); + return loop[0] = xø1 + stride7ø1, loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); +}; +var dsDiamonds = exports.dsDiamonds = function dsDiamonds(heightmap, radius, spread) { + return function () { + var sizeø1 = heightmapResolution(heightmap); + return function () { + var start11ø1 = 0; + var end12ø1 = sizeø1; + var stride10ø1 = radius; + return function loop() { + var recur = loop; + var yø1 = start11ø1; + do { + recur = yø1 < end12ø1 ? (function () { + (function () { + return function () { + var shiftø1 = isEven(yø1 / radius) ? radius : 0; + return function () { + var start14ø1 = shiftø1; + var end15ø1 = sizeø1; + var stride13ø1 = 2 * radius; + return function loop() { + var recur = loop; + var xø1 = start14ø1; + do { + recur = xø1 < end15ø1 ? (function () { + (function () { + return dsDiamond(heightmap, xø1, yø1, radius, spread); + })(); + return loop[0] = xø1 + stride13ø1, loop; + })() : void 0; + } while (xø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); + })(); + return loop[0] = yø1 + stride10ø1, loop; + })() : void 0; + } while (yø1 = loop[0], recur === loop); + return recur; + }.call(this); + }.call(this); + }.call(this); +}; +var diamondSquare = exports.diamondSquare = function diamondSquare(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + (function loop() { + var recur = loop; + var radiusø1 = centerø1; + var spreadø1 = initialSpreadø1; + do { + recur = radiusø1 >= 1 ? (function () { + dsSquares(heightmap, radiusø1, spreadø1); + dsDiamonds(heightmap, radiusø1, spreadø1); + return loop[0] = radiusø1 / 2, loop[1] = spreadø1 * spreadReductionø1, loop; + })() : void 0; + } while (radiusø1 = loop[0], spreadø1 = loop[1], recur === loop); + return recur; + }.call(this)); + return normalize(heightmap); + }.call(this); +}; +var diamondSquare1 = exports.diamondSquare1 = function diamondSquare1(heightmap) { + dsInitCorners(heightmap); + return normalize(heightmap); +}; +var diamondSquare2 = exports.diamondSquare2 = function diamondSquare2(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + dsSquares(heightmap, centerø1, initialSpreadø1); + return normalize(heightmap); + }.call(this); +}; +var diamondSquare3 = exports.diamondSquare3 = function diamondSquare3(heightmap) { + return function () { + var initialSpreadø1 = 0.3; + var spreadReductionø1 = 0.5; + var centerø1 = heightmapCenterIndex(heightmap); + var sizeø1 = heightmap.shape[0]; + dsInitCorners(heightmap); + dsSquares(heightmap, centerø1, initialSpreadø1); + dsDiamonds(heightmap, centerø1, initialSpreadø1); + dsSquares(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø1); + dsDiamonds(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø1); + return normalize(heightmap); + }.call(this); +}; +var makeDirectionalLight = exports.makeDirectionalLight = function makeDirectionalLight() { + return function () { + var lightø1 = new THREE.DirectionalLight(16777215, 1); + lightø1.position.set(100, 0, 150); + return lightø1; + }.call(this); +}; +var makeCamera = exports.makeCamera = function makeCamera() { + return function () { + var cameraø1 = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000); + cameraø1.position.set(0, -100, 150); + return cameraø1; + }.call(this); +}; +var makeRenderer = exports.makeRenderer = function makeRenderer() { + return function () { + var rendererø1 = new THREE.WebGLRenderer({ 'antialias': false }); + rendererø1.setClearColor(16777215); + rendererø1.setSize(width, height); + rendererø1.setPixelRatio(2); + return rendererø1; + }.call(this); +}; +var makeGeometry = exports.makeGeometry = function makeGeometry(heightmap) { + return function () { + var resolutionø1 = heightmap.shape[0]; + var geometryø1 = new THREE.PlaneGeometry(terrainSize, terrainSize, resolutionø1 - 1, resolutionø1 - 1); + return geometryø1; + }.call(this); +}; +var makeControls = exports.makeControls = function makeControls(camera, renderer) { + return function () { + var controlsø1 = new THREE.TrackballControls(camera, renderer.domElement); + controlsø1.rotateSpeed = 1.4; + controlsø1.zoomSpeed = 0.5; + controlsø1.staticMoving = true; + controlsø1.dynamicDampingFactor = 0.3; + return controlsø1; + }.call(this); +}; +var makePlane = exports.makePlane = function makePlane(geometry) { + return function () { + var materialø1 = new THREE.MeshLambertMaterial({ + 'wireframe': wireframe, + 'wireframeLinewidth': wireframeWidth, + 'color': 47872 + }); + return new THREE.Mesh(geometry, materialø1); + }.call(this); +}; +var attachToDom = exports.attachToDom = function attachToDom(renderer, elName, refreshFn) { + return function () { + var containerø1 = document.getElementById(elName); + var settingsø1 = document.createElement('div'); + var refreshButtonø1 = document.createElement('button'); + var buttonTextø1 = document.createTextNode('Refresh'); + var cancelScrollø1 = function (e) { + return e.preventDefault(); + }; + refreshButtonø1.onclick = refreshFn; + renderer.domElement.onmousewheel = cancelScrollø1; + renderer.domElement.addEventListener('MozMousePixelScroll', cancelScrollø1, false); + refreshButtonø1.appendChild(buttonTextø1); + containerø1.appendChild(renderer.domElement); + containerø1.appendChild(settingsø1); + return settingsø1.appendChild(refreshButtonø1); + }.call(this); +}; +var updateGeometry = exports.updateGeometry = function updateGeometry(geometry, heightmap) { + (function loop() { + var recur = loop; + var iø1 = 0; + do { + recur = iø1 < geometry.vertices.length ? (function () { + geometry.vertices[iø1].z = terrainHeight * heightmap.data[iø1]; + return loop[0] = iø1 + 1, loop; + })() : void 0; + } while (iø1 = loop[0], recur === loop); + return recur; + }.call(this)); + geometry.computeVertexNormals(); + return geometry; +}; +var makeDemo = exports.makeDemo = function makeDemo(elementId, algorithm, size) { + var scene = new THREE.Scene(); + scene.add(new THREE.AxisHelper(100)); + var clock = new THREE.Clock(); + var camera = makeCamera(); + var renderer = makeRenderer(); + var geometry = void 0; + var plane = void 0; + scene.add(makeDirectionalLight()); + scene.add(new THREE.AmbientLight(16777215, 0.05)); + var refresh = function refresh() { + return function () { + var heightmapø1 = makeHeightmap(size); + console.log('Generating terrain...'); + (function () { + var G__16ø1 = new Date().getTime(); + var G__18ø1 = (function () { + return algorithm(heightmapø1); + })(); + var G__17ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__17ø1 - G__16ø1) + 'ms.'); + return G__18ø1; + }.call(this)); + console.log('Rebuilding geometry...'); + (function () { + var G__19ø1 = new Date().getTime(); + var G__21ø1 = (function () { + geometry = makeGeometry(heightmapø1); + return updateGeometry(geometry, heightmapø1); + })(); + var G__20ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__20ø1 - G__19ø1) + 'ms.'); + return G__21ø1; + }.call(this)); + console.log('Rebuilding plane...'); + return function () { + var G__22ø1 = new Date().getTime(); + var G__24ø1 = (function () { + scene.remove(plane); + plane = makePlane(geometry); + return scene.add(plane); + })(); + var G__23ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__23ø1 - G__22ø1) + 'ms.'); + return G__24ø1; + }.call(this); + }.call(this); + }; + attachToDom(renderer, elementId, refresh); + var controls = makeControls(camera, renderer); + var render = function render() { + return function () { + var deltaø1 = clock.getDelta(); + requestAnimationFrame(render); + controls.update(deltaø1); + return renderer.render(scene, camera); + }.call(this); + }; + refresh(); + render(); + return void 0; +}; +var makeFinal = exports.makeFinal = function makeFinal(elementId) { + var scene = new THREE.Scene(); + scene.add(new THREE.AxisHelper(100)); + var clock = new THREE.Clock(); + var camera = makeCamera(); + var renderer = makeRenderer(); + var geometry = void 0; + var plane = void 0; + scene.add(makeDirectionalLight()); + scene.add(new THREE.AmbientLight(16777215, 0.05)); + var refresh = function refresh() { + return function () { + var heightmapø1 = makeHeightmap(6); + console.log('Generating terrain...'); + (function () { + var G__25ø1 = new Date().getTime(); + var G__27ø1 = (function () { + return diamondSquare(heightmapø1); + })(); + var G__26ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__26ø1 - G__25ø1) + 'ms.'); + return G__27ø1; + }.call(this)); + console.log('Rebuilding geometry...'); + (function () { + var G__28ø1 = new Date().getTime(); + var G__30ø1 = (function () { + geometry = makeGeometry(heightmapø1); + return updateGeometry(geometry, heightmapø1); + })(); + var G__29ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__29ø1 - G__28ø1) + 'ms.'); + return G__30ø1; + }.call(this)); + console.log('Rebuilding plane...'); + return function () { + var G__31ø1 = new Date().getTime(); + var G__33ø1 = (function () { + scene.remove(plane); + plane = makePlane(geometry); + return scene.add(plane); + })(); + var G__32ø1 = new Date().getTime(); + console.log('Elapsed time: ' + (G__32ø1 - G__31ø1) + 'ms.'); + return G__33ø1; + }.call(this); + }.call(this); + }; + attachToDom(renderer, elementId, refresh); + var controls = makeControls(camera, renderer); + var render = function render() { + return function () { + var deltaø1 = clock.getDelta(); + requestAnimationFrame(render); + controls.update(deltaø1); + return renderer.render(scene, camera); + }.call(this); + }; + refresh(); + render(); + return void 0; +}; +var run = exports.run = function run() { + makeDemo('demo-1', diamondSquare1, 2); + makeDemo('demo-2', diamondSquare2, 4); + makeDemo('demo-3', diamondSquare3, 4); + return makeFinal('demo-final'); +}; +$(run); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFub255bW91cy53aXNwIl0sIm5hbWVzIjpbIl9uc18iLCJpZCIsImRvYyIsIndpZHRoIiwiZXhwb3J0cyIsImhlaWdodCIsIndpcmVmcmFtZSIsIndpcmVmcmFtZVdpZHRoIiwidGVycmFpbkhlaWdodCIsInRlcnJhaW5TaXplIiwiaW5jIiwieCIsImRlYyIsIm1pZHBvaW50IiwiYSIsImIiLCJhdmVyYWdlMiIsImF2ZXJhZ2U0IiwiYyIsImQiLCJzYWZlQXZlcmFnZSIsInRvdGFsw7gxIiwiY291bnTDuDEiLCJpc0V2ZW4iLCJuIiwiaXNPZGQiLCJyYW5kIiwiTWF0aCIsInJhbmRvbSIsInJhbmRBcm91bmRaZXJvIiwic3ByZWFkIiwiaml0dGVyIiwidmFsdWUiLCJoZWlnaHRtYXBSZXNvbHV0aW9uIiwiaGVpZ2h0bWFwIiwic2hhcGUiLCJoZWlnaHRtYXBMYXN0SW5kZXgiLCJoZWlnaHRtYXBDZW50ZXJJbmRleCIsImhlaWdodG1hcEdldCIsInkiLCJnZXQiLCJoZWlnaHRtYXBHZXRTYWZlIiwibGFzdMO4MSIsImhlaWdodG1hcFNldCIsInZhbCIsInNldCIsImhlaWdodG1hcFNldElmVW5zZXQiLCJub3JtYWxpemUiLCJtYXjDuDEiLCJJbmZpbml0eSIsIm1pbsO4MSIsImVsw7gxIiwic3BhbsO4MSIsInjDuDEiLCJ5w7gxIiwibWFrZUhlaWdodG1hcCIsImV4cG9uZW50IiwicmVzb2x1dGlvbsO4MSIsInBvdyIsImhlaWdodG1hcMO4MSIsIm5kYXJyYXkiLCJGbG9hdDY0QXJyYXkiLCJyZXNvbHV0aW9uIiwibGFzdCIsInRvcExlZnRDb3JuZXIiLCJjZW50ZXLDuDEiLCJsbyIsImhpIiwidG9wUmlnaHRDb3JuZXIiLCJib3R0b21MZWZ0Q29ybmVyIiwiYm90dG9tUmlnaHRDb3JuZXIiLCJkc0luaXRDb3JuZXJzIiwiZHNTcXVhcmUiLCJyYWRpdXMiLCJuZXdIZWlnaHTDuDEiLCJkc0RpYW1vbmQiLCJkc1NxdWFyZXMiLCJkc0RpYW1vbmRzIiwic2l6ZcO4MSIsInNoaWZ0w7gxIiwiZGlhbW9uZFNxdWFyZSIsImluaXRpYWxTcHJlYWTDuDEiLCJzcHJlYWRSZWR1Y3Rpb27DuDEiLCJyYWRpdXPDuDEiLCJzcHJlYWTDuDEiLCJkaWFtb25kU3F1YXJlMSIsImRpYW1vbmRTcXVhcmUyIiwiZGlhbW9uZFNxdWFyZTMiLCJtYWtlRGlyZWN0aW9uYWxMaWdodCIsImxpZ2h0w7gxIiwiVEhSRUUiLCJEaXJlY3Rpb25hbExpZ2h0IiwicG9zaXRpb24uc2V0IiwibWFrZUNhbWVyYSIsImNhbWVyYcO4MSIsIlBlcnNwZWN0aXZlQ2FtZXJhIiwibWFrZVJlbmRlcmVyIiwicmVuZGVyZXLDuDEiLCJXZWJHTFJlbmRlcmVyIiwic2V0Q2xlYXJDb2xvciIsInNldFNpemUiLCJzZXRQaXhlbFJhdGlvIiwibWFrZUdlb21ldHJ5IiwiZ2VvbWV0cnnDuDEiLCJQbGFuZUdlb21ldHJ5IiwibWFrZUNvbnRyb2xzIiwiY2FtZXJhIiwicmVuZGVyZXIiLCJjb250cm9sc8O4MSIsIlRyYWNrYmFsbENvbnRyb2xzIiwiZG9tRWxlbWVudCIsInJvdGF0ZVNwZWVkIiwiem9vbVNwZWVkIiwic3RhdGljTW92aW5nIiwiZHluYW1pY0RhbXBpbmdGYWN0b3IiLCJtYWtlUGxhbmUiLCJnZW9tZXRyeSIsIm1hdGVyaWFsw7gxIiwiTWVzaExhbWJlcnRNYXRlcmlhbCIsIk1lc2giLCJhdHRhY2hUb0RvbSIsImVsTmFtZSIsInJlZnJlc2hGbiIsImNvbnRhaW5lcsO4MSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJzZXR0aW5nc8O4MSIsImNyZWF0ZUVsZW1lbnQiLCJyZWZyZXNoQnV0dG9uw7gxIiwiYnV0dG9uVGV4dMO4MSIsImNyZWF0ZVRleHROb2RlIiwiY2FuY2VsU2Nyb2xsw7gxIiwiZSIsInByZXZlbnREZWZhdWx0Iiwib25jbGljayIsImRvbUVsZW1lbnQub25tb3VzZXdoZWVsIiwiZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyIiwiYXBwZW5kQ2hpbGQiLCJ1cGRhdGVHZW9tZXRyeSIsImnDuDEiLCJ2ZXJ0aWNlcy5sZW5ndGgiLCJ2ZXJ0aWNlcyIsInoiLCJkYXRhIiwiY29tcHV0ZVZlcnRleE5vcm1hbHMiLCJtYWtlRGVtbyIsImVsZW1lbnRJZCIsImFsZ29yaXRobSIsInNpemUiLCJzY2VuZSIsIlNjZW5lIiwiYWRkIiwiQXhpc0hlbHBlciIsImNsb2NrIiwiQ2xvY2siLCJwbGFuZSIsIkFtYmllbnRMaWdodCIsInJlZnJlc2giLCJyZW1vdmUiLCJjb250cm9scyIsInJlbmRlciIsImRlbHRhw7gxIiwiZ2V0RGVsdGEiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJ1cGRhdGUiLCJtYWtlRmluYWwiLCJydW4iLCIkIl0sIm1hcHBpbmdzIjoiO0lBQUEsSUFBQ0EsSSxHQUFEO0FBQUEsUUFBQUMsRSxFQUFJLE1BQUo7QUFBQSxRQUFBQyxHLEVBQUEsSyxDQUFBO0FBQUEsTTs7O0FBS0EsSUFBS0MsS0FBQSxHQUFBQyxPQUFBLENBQUFELEtBQUEsR0FBTSxHQUFYLEM7QUFDQSxJQUFLRSxNQUFBLEdBQUFELE9BQUEsQ0FBQUMsTUFBQSxHQUFPLEdBQVosQztBQUNBLElBQUtDLFNBQUEsR0FBQUYsT0FBQSxDQUFBRSxTQUFBLEcsSUFBTCxDO0FBQ0EsSUFBS0MsY0FBQSxHQUFBSCxPQUFBLENBQUFHLGNBQUEsR0FBZ0IsR0FBckIsQztBQUNBLElBQUtDLGFBQUEsR0FBQUosT0FBQSxDQUFBSSxhQUFBLEdBQWUsRUFBcEIsQztBQUNBLElBQUtDLFdBQUEsR0FBQUwsT0FBQSxDQUFBSyxXQUFBLEdBQWEsR0FBbEIsQzs7OztBQW9CQSxJQUFNQyxHQUFBLEdBQUFOLE9BQUEsQ0FBQU0sR0FBQSxHQUFOLFNBQU1BLEdBQU4sQ0FBV0MsQ0FBWCxFQUNFO0FBQUEsV0FBR0EsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7QUFHQSxJQUFNQyxHQUFBLEdBQUFSLE9BQUEsQ0FBQVEsR0FBQSxHQUFOLFNBQU1BLEdBQU4sQ0FBV0QsQ0FBWCxFQUNFO0FBQUEsV0FBR0EsQ0FBSCxH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QUEsSUFFQzJELFFBQUQsQ0FBVyxRQUFYLEVBQW9CMUQsY0FBcEIsRUFBcUMsQ0FBckMsRUFGQTtBQUFBLElBR0EsT0FBQzhFLFNBQUQsQ0FBWSxZQUFaLEVBSEE7QUFBQSxDQURGLEM7QUFNQ0UsQ0FBRCxDQUFHRCxHQUFIIiwic291cmNlc0NvbnRlbnQiOlsiKG5zIGRlbW9cbiAgKDpyZXF1aXJlIFtuZGFycmF5XSkpXG5cblxuOyBDb25zdGFudHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZiB3aWR0aCA2MTApXG4oZGVmIGhlaWdodCA0MDApXG4oZGVmIHdpcmVmcmFtZSB0cnVlKVxuKGRlZiB3aXJlZnJhbWUtd2lkdGggMS4yKVxuKGRlZiB0ZXJyYWluLWhlaWdodCA1MClcbihkZWYgdGVycmFpbi1zaXplIDEwMClcblxuOyBHZW5lcmFsIFV0aWxpdGllcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm1hY3JvIHdoZW4gW2NvbmRpdGlvbiAmIGJvZHldXG4gIGAoaWYgfmNvbmRpdGlvblxuICAgICAoZG8gfkBib2R5KSkpXG5cbihkZWZtYWNybyB3aGVuLW5vdCBbY29uZGl0aW9uICYgYm9keV1cbiAgYCh3aGVuIChub3QgfmNvbmRpdGlvbilcbiAgICAgfkBib2R5KSlcblxuKGRlZm1hY3JvIC0+IFsmIG9wZXJhdGlvbnNdXG4gIChyZWR1Y2VcbiAgICAoZm4gW2Zvcm0gb3BlcmF0aW9uXVxuICAgICAgKGNvbnMgKGZpcnN0IG9wZXJhdGlvbilcbiAgICAgICAgICAgIChjb25zIGZvcm0gKHJlc3Qgb3BlcmF0aW9uKSkpKVxuICAgIChmaXJzdCBvcGVyYXRpb25zKVxuICAgIChyZXN0IG9wZXJhdGlvbnMpKSlcblxuXG4oZGVmbiBpbmMgW3hdXG4gICgrIHggMSkpXG5cbihkZWZuIGRlYyBbeF1cbiAgKC0geCAxKSlcblxuXG4oZGVmbWFjcm8gZG8tdGltZXMgW3Zhcm5hbWUgbGltaXQgJiBib2R5XVxuICAobGV0IFtlbmQgKGdlbnN5bSldXG4gICAgYChsZXQgW35lbmQgfmxpbWl0XVxuICAgICAgIChsb29wIFt+dmFybmFtZSAwXVxuICAgICAgICAgKHdoZW4gKDwgfnZhcm5hbWUgfmVuZClcbiAgICAgICAgICAgfkBib2R5XG4gICAgICAgICAgIChyZWN1ciAoaW5jIH52YXJuYW1lKSkpKSkpKVxuXG4oZGVmbWFjcm8gZG8tc3RyaWRlIFt2YXJuYW1lcyBzdGFydC1mb3JtIGVuZC1mb3JtIHN0cmlkZS1mb3JtICYgYm9keV1cbiAgKGxldCBbc3RyaWRlIChnZW5zeW0gXCJzdHJpZGVcIilcbiAgICAgICAgc3RhcnQgKGdlbnN5bSBcInN0YXJ0XCIpXG4gICAgICAgIGVuZCAoZ2Vuc3ltIFwiZW5kXCIpXG4gICAgICAgIGJ1aWxkIChmbiBidWlsZCBbdmFyc11cbiAgICAgICAgICAgICAgICAoaWYgKGVtcHR5PyB2YXJzKVxuICAgICAgICAgICAgICAgICAgYChkbyB+QGJvZHkpXG4gICAgICAgICAgICAgICAgICAobGV0IFt2YXJuYW1lIChmaXJzdCB2YXJzKV1cbiAgICAgICAgICAgICAgICAgICAgYChsb29wIFt+dmFybmFtZSB+c3RhcnRdXG4gICAgICAgICAgICAgICAgICAgICAgICh3aGVuICg8IH52YXJuYW1lIH5lbmQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgfihidWlsZCAocmVzdCB2YXJzKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXIgKCsgfnZhcm5hbWUgfnN0cmlkZSkpKSkpKSldXG4gICAgOyBGaXggdGhlIG51bWJlcnMgb25jZSBvdXRzaWRlIHRoZSBuZXN0ZWQgbG9vcHMsXG4gICAgOyBhbmQgdGhlbiBidWlsZCB0aGUgZ3V0cy5cbiAgICBgKGxldCBbfnN0YXJ0IH5zdGFydC1mb3JtXG4gICAgICAgICAgIH5lbmQgfmVuZC1mb3JtXG4gICAgICAgICAgIH5zdHJpZGUgfnN0cmlkZS1mb3JtXVxuICAgICAgIH4oYnVpbGQgdmFybmFtZXMpKSkpXG5cblxuKGRlZm1hY3JvIGRvLW5kYXJyYXkgW3ZhcnMgYXJyYXktZm9ybSAmIGJvZHldXG4gIChsZXQgW2FycmF5LXZhciAoZ2Vuc3ltIFwiYXJyYXlcIilcbiAgICAgICAgYnVpbGQgKGZuIGJ1aWxkIFt2YXJzIG5dXG4gICAgICAgICAgICAgICAgKGlmIChlbXB0eT8gdmFycylcbiAgICAgICAgICAgICAgICAgIGAoZG8gfkBib2R5KVxuICAgICAgICAgICAgICAgICAgYChkby10aW1lcyB+KGZpcnN0IHZhcnMpIChhZ2V0ICguLXNoYXBlIH5hcnJheS12YXIpIH5uKVxuICAgICAgICAgICAgICAgICAgICAgfihidWlsZCAocmVzdCB2YXJzKSAoaW5jIG4pKSkpKV1cbiAgICBgKGxldCBbfmFycmF5LXZhciB+YXJyYXktZm9ybV1cbiAgICAgICB+KGJ1aWxkIHZhcnMgMCkpKSlcblxuKGRlZm1hY3JvIGRvLW5kYXJyYXktZWwgW2VsZW1lbnQgYXJyYXktZm9ybSAmIGJvZHldXG4gIChsZXQgW2luZGV4IChnZW5zeW0gXCJpbmRleFwiKVxuICAgICAgICBhcnJheSAoZ2Vuc3ltIFwiYXJyYXlcIildXG4gICAgYChsZXQgW35hcnJheSB+YXJyYXktZm9ybV1cbiAgICAgICAoZG8tdGltZXMgfmluZGV4ICguLWxlbmd0aCAoLi1kYXRhIH5hcnJheSkpXG4gICAgICAgICAobGV0IFt+ZWxlbWVudCAoYWdldCAoLi1kYXRhIH5hcnJheSkgfmluZGV4KV1cbiAgICAgICAgICAgfkBib2R5KSkpKSlcblxuXG4oZGVmbWFjcm8gaW5jISBbcGxhY2VdXG4gIGAoc2V0ISB+cGxhY2UgKGluYyB+cGxhY2UpKSlcblxuKGRlZm1hY3JvIGFkZCEgW3BsYWNlIGFtb3VudF1cbiAgYChzZXQhIH5wbGFjZSAoKyB+cGxhY2UgfmFtb3VudCkpKVxuXG5cbihkZWZtYWNybyBsIFsmIGZvcm1zXVxuICBgKGNvbnNvbGUubG9nIH5AZm9ybXMpKVxuXG4oZGVmbWFjcm8gdGltZSBbJiBib2R5XVxuICAobGV0IFtzdGFydCAoZ2Vuc3ltKVxuICAgICAgICBlbmQgKGdlbnN5bSlcbiAgICAgICAgcmVzdWx0IChnZW5zeW0pXVxuICAgIGAobGV0IFt+c3RhcnQgKC5nZXRUaW1lIChuZXcgRGF0ZSkpXG4gICAgICAgICAgIH5yZXN1bHQgKGRvIH5AYm9keSlcbiAgICAgICAgICAgfmVuZCAoLmdldFRpbWUgKG5ldyBEYXRlKSldXG4gICAgICAgKGwgKCsgXCJFbGFwc2VkIHRpbWU6IFwiICgtIH5lbmQgfnN0YXJ0KSBcIm1zLlwiKSlcbiAgICAgICB+cmVzdWx0KSkpXG5cblxuKGRlZm4gbWlkcG9pbnQgW2EgYl1cbiAgKC8gKCsgYSBiKSAyKSlcblxuKGRlZm4gYXZlcmFnZTIgW2EgYl1cbiAgKC8gKCsgYSBiKSAyKSlcblxuKGRlZm4gYXZlcmFnZTQgW2EgYiBjIGRdXG4gICgvICgrIGEgYiBjIGQpIDQpKVxuXG4oZGVmbiBzYWZlLWF2ZXJhZ2UgW2EgYiBjIGRdXG4gIChsZXQgW3RvdGFsIDAgY291bnQgMF1cbiAgICAod2hlbiBhIChhZGQhIHRvdGFsIGEpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBiIChhZGQhIHRvdGFsIGIpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBjIChhZGQhIHRvdGFsIGMpIChpbmMhIGNvdW50KSlcbiAgICAod2hlbiBkIChhZGQhIHRvdGFsIGQpIChpbmMhIGNvdW50KSlcbiAgICAoLyB0b3RhbCBjb3VudCkpKVxuXG5cbihkZWZuIGV2ZW4/IFtuXVxuICAoPT0gMCAobW9kIG4gMikpKVxuXG4oZGVmbiBvZGQ/IFtuXVxuICAoPT0gMSAobW9kIG4gMikpKVxuXG5cbjsgUmFuZG9tbmVzcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIHJhbmQgW11cbiAgKE1hdGgucmFuZG9tKSlcblxuKGRlZm4gcmFuZC1hcm91bmQtemVybyBbc3ByZWFkXVxuICAoLSAoKiBzcHJlYWQgKHJhbmQpIDIpIHNwcmVhZCkpXG5cbihkZWZuIGppdHRlciBbdmFsdWUgc3ByZWFkXVxuICAoKyB2YWx1ZSAocmFuZC1hcm91bmQtemVybyBzcHJlYWQpKSlcblxuXG47IEhlaWdodG1hcCBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBoZWlnaHRtYXAtcmVzb2x1dGlvbiBbaGVpZ2h0bWFwXVxuICAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMCkpXG5cbihkZWZuIGhlaWdodG1hcC1sYXN0LWluZGV4IFtoZWlnaHRtYXBdXG4gIChkZWMgKGhlaWdodG1hcC1yZXNvbHV0aW9uIGhlaWdodG1hcCkpKVxuXG4oZGVmbiBoZWlnaHRtYXAtY2VudGVyLWluZGV4IFtoZWlnaHRtYXBdXG4gIChtaWRwb2ludCAwIChoZWlnaHRtYXAtbGFzdC1pbmRleCBoZWlnaHRtYXApKSlcblxuXG4oZGVmbiBoZWlnaHRtYXAtZ2V0IFtoZWlnaHRtYXAgeCB5XVxuICAoLmdldCBoZWlnaHRtYXAgeCB5KSlcblxuKGRlZm4gaGVpZ2h0bWFwLWdldC1zYWZlIFtoZWlnaHRtYXAgeCB5XVxuICAobGV0IFtsYXN0IChoZWlnaHRtYXAtbGFzdC1pbmRleCBoZWlnaHRtYXApXVxuICAgICh3aGVuIChhbmQgKDw9IDAgeCBsYXN0KVxuICAgICAgICAgICAgICAgKDw9IDAgeSBsYXN0KSlcbiAgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCB4IHkpKSkpXG5cbihkZWZuIGhlaWdodG1hcC1zZXQhIFtoZWlnaHRtYXAgeCB5IHZhbF1cbiAgKC5zZXQgaGVpZ2h0bWFwIHggeSB2YWwpKVxuXG4oZGVmbiBoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBbaGVpZ2h0bWFwIHggeSB2YWxdXG4gICh3aGVuICg9PSAwIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCB4IHkpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5IHZhbCkpKVxuXG5cbihkZWZuIG5vcm1hbGl6ZSBbaGVpZ2h0bWFwXVxuICAobGV0IFttYXggKC0gSW5maW5pdHkpXG4gICAgICAgIG1pbiBJbmZpbml0eV1cbiAgICAoZG8tbmRhcnJheS1lbCBlbCBoZWlnaHRtYXBcbiAgICAgICh3aGVuICg8IG1heCBlbCkgKHNldCEgbWF4IGVsKSlcbiAgICAgICh3aGVuICg+IG1pbiBlbCkgKHNldCEgbWluIGVsKSkpXG4gICAgKGxldCBbc3BhbiAoLSBtYXggbWluKV1cbiAgICAgIChkby1uZGFycmF5IFt4IHldIGhlaWdodG1hcFxuICAgICAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIHggeVxuICAgICAgICAgICAgICAgICAgICAgICAgKC8gKC0gKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkgbWluKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BhbikpKSkpKVxuXG5cbihkZWZuIG1ha2UtaGVpZ2h0bWFwIFtleHBvbmVudF1cbiAgKGxldCBbcmVzb2x1dGlvbiAoKyAoTWF0aC5wb3cgMiBleHBvbmVudCkgMSldXG4gICAgKGxldCBbaGVpZ2h0bWFwIChuZGFycmF5IChuZXcgRmxvYXQ2NEFycmF5ICgqIHJlc29sdXRpb24gcmVzb2x1dGlvbikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtyZXNvbHV0aW9uIHJlc29sdXRpb25dKV1cbiAgICAgIChzZXQhIGhlaWdodG1hcC5leHBvbmVudCBleHBvbmVudClcbiAgICAgIChzZXQhIGhlaWdodG1hcC5yZXNvbHV0aW9uIHJlc29sdXRpb24pXG4gICAgICAoc2V0ISBoZWlnaHRtYXAubGFzdCAoZGVjIHJlc29sdXRpb24pKVxuICAgICAgaGVpZ2h0bWFwKSkpXG5cblxuKGRlZm4gdG9wLWxlZnQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gMCAwKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG4oZGVmbiB0b3AtcmlnaHQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gY2VudGVyIDApXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIGJvdHRvbS1sZWZ0LWNvcm5lciBbaGVpZ2h0bWFwXVxuICAobGV0IFtjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoLT4gaGVpZ2h0bWFwXG4gICAgICAoLmxvIDAgY2VudGVyKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG4oZGVmbiBib3R0b20tcmlnaHQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gY2VudGVyIGNlbnRlcilcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuXG47IERpYW1vbmQtU3F1YXJlIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBkcy1pbml0LWNvcm5lcnMgW2hlaWdodG1hcF1cbiAgKGxldCBbbGFzdCAoaGVpZ2h0bWFwLWxhc3QtaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIDAgICAgMCAgICAocmFuZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwICAgIGxhc3QgKHJhbmQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgbGFzdCAwICAgIChyYW5kKSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGxhc3QgbGFzdCAocmFuZCkpKSlcblxuKGRlZm4gZHMtc3F1YXJlIFtoZWlnaHRtYXAgeCB5IHJhZGl1cyBzcHJlYWRdXG4gIChsZXQgW25ldy1oZWlnaHQgKGppdHRlclxuICAgICAgICAgICAgICAgICAgICAgKGF2ZXJhZ2U0XG4gICAgICAgICAgICAgICAgICAgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCAoLSB4IHJhZGl1cykgKC0geSByYWRpdXMpKVxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgKC0geCByYWRpdXMpICgrIHkgcmFkaXVzKSlcbiAgICAgICAgICAgICAgICAgICAgICAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwICgrIHggcmFkaXVzKSAoLSB5IHJhZGl1cykpXG4gICAgICAgICAgICAgICAgICAgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCAoKyB4IHJhZGl1cykgKCsgeSByYWRpdXMpKSlcbiAgICAgICAgICAgICAgICAgICAgIHNwcmVhZCldXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCB4IHkgbmV3LWhlaWdodCkpKVxuXG4oZGVmbiBkcy1kaWFtb25kIFtoZWlnaHRtYXAgeCB5IHJhZGl1cyBzcHJlYWRdXG4gIChsZXQgW25ldy1oZWlnaHQgKGppdHRlclxuICAgICAgICAgICAgICAgICAgICAgKHNhZmUtYXZlcmFnZVxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldC1zYWZlIGhlaWdodG1hcCAoLSB4IHJhZGl1cykgeSlcbiAgICAgICAgICAgICAgICAgICAgICAgKGhlaWdodG1hcC1nZXQtc2FmZSBoZWlnaHRtYXAgKCsgeCByYWRpdXMpIHkpXG4gICAgICAgICAgICAgICAgICAgICAgIChoZWlnaHRtYXAtZ2V0LXNhZmUgaGVpZ2h0bWFwIHggKC0geSByYWRpdXMpKVxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldC1zYWZlIGhlaWdodG1hcCB4ICgrIHkgcmFkaXVzKSkpXG4gICAgICAgICAgICAgICAgICAgICBzcHJlYWQpXVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5IG5ldy1oZWlnaHQpKSlcblxuXG4oZGVmbiBkcy1zcXVhcmVzIFtoZWlnaHRtYXAgcmFkaXVzIHNwcmVhZF1cbiAgKGRvLXN0cmlkZSBbeCB5XSByYWRpdXMgKGhlaWdodG1hcC1yZXNvbHV0aW9uIGhlaWdodG1hcCkgKCogMiByYWRpdXMpXG4gICAgKGRzLXNxdWFyZSBoZWlnaHRtYXAgeCB5IHJhZGl1cyBzcHJlYWQpKSlcblxuKGRlZm4gZHMtZGlhbW9uZHMgW2hlaWdodG1hcCByYWRpdXMgc3ByZWFkXVxuICAobGV0IFtzaXplIChoZWlnaHRtYXAtcmVzb2x1dGlvbiBoZWlnaHRtYXApXVxuICAgIChkby1zdHJpZGUgW3ldIDAgc2l6ZSByYWRpdXNcbiAgICAgIChsZXQgW3NoaWZ0IChpZiAoZXZlbj8gKC8geSByYWRpdXMpKSByYWRpdXMgMCldXG4gICAgICAgIChkby1zdHJpZGUgW3hdIHNoaWZ0IHNpemUgKCogMiByYWRpdXMpXG4gICAgICAgICAgKGRzLWRpYW1vbmQgaGVpZ2h0bWFwIHggeSByYWRpdXMgc3ByZWFkKSkpKSkpXG5cbihkZWZuIGRpYW1vbmQtc3F1YXJlIFtoZWlnaHRtYXBdXG4gIChsZXQgW2luaXRpYWwtc3ByZWFkIDAuM1xuICAgICAgICBzcHJlYWQtcmVkdWN0aW9uIDAuNVxuICAgICAgICBjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKVxuICAgICAgICBzaXplIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKV1cbiAgICAoZHMtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgICAobG9vcCBbcmFkaXVzIGNlbnRlclxuICAgICAgICAgICBzcHJlYWQgaW5pdGlhbC1zcHJlYWRdXG4gICAgICAod2hlbiAoPj0gcmFkaXVzIDEpXG4gICAgICAgIChkcy1zcXVhcmVzIGhlaWdodG1hcCByYWRpdXMgc3ByZWFkKVxuICAgICAgICAoZHMtZGlhbW9uZHMgaGVpZ2h0bWFwIHJhZGl1cyBzcHJlYWQpXG4gICAgICAgIChyZWN1ciAoLyByYWRpdXMgMilcbiAgICAgICAgICAgICAgICgqIHNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uKSkpKVxuICAgIChub3JtYWxpemUgaGVpZ2h0bWFwKSkpXG5cblxuKGRlZm4gZGlhbW9uZC1zcXVhcmUtMSBbaGVpZ2h0bWFwXVxuICAoZHMtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgKG5vcm1hbGl6ZSBoZWlnaHRtYXApKVxuXG4oZGVmbiBkaWFtb25kLXNxdWFyZS0yIFtoZWlnaHRtYXBdXG4gIChsZXQgW2luaXRpYWwtc3ByZWFkIDAuM1xuICAgICAgICBzcHJlYWQtcmVkdWN0aW9uIDAuNVxuICAgICAgICBjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKVxuICAgICAgICBzaXplIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKV1cbiAgICAoZHMtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgICAoZHMtc3F1YXJlcyBoZWlnaHRtYXAgY2VudGVyIGluaXRpYWwtc3ByZWFkKVxuICAgIChub3JtYWxpemUgaGVpZ2h0bWFwKSkpXG5cbihkZWZuIGRpYW1vbmQtc3F1YXJlLTMgW2hlaWdodG1hcF1cbiAgKGxldCBbaW5pdGlhbC1zcHJlYWQgMC4zXG4gICAgICAgIHNwcmVhZC1yZWR1Y3Rpb24gMC41XG4gICAgICAgIGNlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXG4gICAgICAgIHNpemUgKGFnZXQgaGVpZ2h0bWFwLnNoYXBlIDApXVxuICAgIChkcy1pbml0LWNvcm5lcnMgaGVpZ2h0bWFwKVxuICAgIChkcy1zcXVhcmVzIGhlaWdodG1hcCBjZW50ZXIgaW5pdGlhbC1zcHJlYWQpXG4gICAgKGRzLWRpYW1vbmRzIGhlaWdodG1hcCBjZW50ZXIgaW5pdGlhbC1zcHJlYWQpXG4gICAgKGRzLXNxdWFyZXMgaGVpZ2h0bWFwICgvIGNlbnRlciAyKSAoKiBzcHJlYWQtcmVkdWN0aW9uIGluaXRpYWwtc3ByZWFkKSlcbiAgICAoZHMtZGlhbW9uZHMgaGVpZ2h0bWFwICgvIGNlbnRlciAyKSAoKiBzcHJlYWQtcmVkdWN0aW9uIGluaXRpYWwtc3ByZWFkKSlcbiAgICAobm9ybWFsaXplIGhlaWdodG1hcCkpKVxuXG5cbjsgVGhyZWUuanMgSGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQgW11cbiAgKGxldCBbbGlnaHQgKG5ldyBUSFJFRS5EaXJlY3Rpb25hbExpZ2h0IDB4ZmZmZmZmIDEpXVxuICAgIChsaWdodC5wb3NpdGlvbi5zZXQgMTAwIDAgMTUwKVxuICAgIGxpZ2h0KSlcblxuKGRlZm4gbWFrZS1jYW1lcmEgW11cbiAgKGxldCBbY2FtZXJhIChuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmFcbiAgICAgICAgICAgICAgICAgICAgNTUsXG4gICAgICAgICAgICAgICAgICAgICgvIHdpZHRoIGhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgMC4xLFxuICAgICAgICAgICAgICAgICAgICAxMDAwKV1cbiAgICAoY2FtZXJhLnBvc2l0aW9uLnNldCAwIC0xMDAgMTUwKVxuICAgIGNhbWVyYSkpXG5cbihkZWZuIG1ha2UtcmVuZGVyZXIgW11cbiAgKGxldCBbcmVuZGVyZXIgKG5ldyBUSFJFRS5XZWJHTFJlbmRlcmVyIHs6YW50aWFsaWFzIGZhbHNlfSldXG4gICAgKHJlbmRlcmVyLnNldENsZWFyQ29sb3IgMHhmZmZmZmYpXG4gICAgKHJlbmRlcmVyLnNldFNpemUgd2lkdGggaGVpZ2h0KVxuICAgIChyZW5kZXJlci5zZXRQaXhlbFJhdGlvIDIpXG4gICAgcmVuZGVyZXIpKVxuXG4oZGVmbiBtYWtlLWdlb21ldHJ5IFtoZWlnaHRtYXBdXG4gIChsZXQgW3Jlc29sdXRpb24gKGFnZXQgaGVpZ2h0bWFwLnNoYXBlIDApXG4gICAgICAgIGdlb21ldHJ5IChuZXcgVEhSRUUuUGxhbmVHZW9tZXRyeVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgIHRlcnJhaW4tc2l6ZVxuICAgICAgICAgICAgICAgICAgICAgICgtIHJlc29sdXRpb24gMSlcbiAgICAgICAgICAgICAgICAgICAgICAoLSByZXNvbHV0aW9uIDEpKV1cbiAgICBnZW9tZXRyeSkpXG5cbihkZWZuIG1ha2UtY29udHJvbHMgW2NhbWVyYSByZW5kZXJlcl1cbiAgKGxldCBbY29udHJvbHMgKG5ldyBUSFJFRS5UcmFja2JhbGxDb250cm9scyBjYW1lcmEgcmVuZGVyZXIuZG9tRWxlbWVudCldXG4gICAgKHNldCEgY29udHJvbHMucm90YXRlU3BlZWQgMS40KVxuICAgIChzZXQhIGNvbnRyb2xzLnpvb21TcGVlZCAwLjUpXG4gICAgKHNldCEgY29udHJvbHMuc3RhdGljTW92aW5nIHRydWUpXG4gICAgKHNldCEgY29udHJvbHMuZHluYW1pY0RhbXBpbmdGYWN0b3IgMC4zKVxuICAgIGNvbnRyb2xzKSlcblxuKGRlZm4gbWFrZS1wbGFuZSBbZ2VvbWV0cnldXG4gIChsZXQgW21hdGVyaWFsIChuZXcgVEhSRUUuTWVzaExhbWJlcnRNYXRlcmlhbFxuICAgICAgICAgICAgICAgICAgICAgIHs6d2lyZWZyYW1lIHdpcmVmcmFtZVxuICAgICAgICAgICAgICAgICAgICAgICA6d2lyZWZyYW1lTGluZXdpZHRoIHdpcmVmcmFtZS13aWR0aFxuICAgICAgICAgICAgICAgICAgICAgICA6Y29sb3IgMHgwMGJiMDB9KV1cbiAgICAobmV3IFRIUkVFLk1lc2ggZ2VvbWV0cnkgbWF0ZXJpYWwpKSlcblxuXG4oZGVmbiBhdHRhY2gtdG8tZG9tIFtyZW5kZXJlciBlbC1uYW1lIHJlZnJlc2gtZm5dXG4gIChsZXQgW2NvbnRhaW5lciAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQgZWwtbmFtZSlcbiAgICAgICAgc2V0dGluZ3MgKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJkaXZcIilcbiAgICAgICAgcmVmcmVzaC1idXR0b24gKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgXCJidXR0b25cIilcbiAgICAgICAgYnV0dG9uLXRleHQgKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlIFwiUmVmcmVzaFwiKVxuICAgICAgICBjYW5jZWwtc2Nyb2xsIChmbiBbZV0gKC5wcmV2ZW50RGVmYXVsdCBlKSldXG4gICAgKHNldCEgcmVmcmVzaC1idXR0b24ub25jbGljayByZWZyZXNoLWZuKVxuICAgIChzZXQhIHJlbmRlcmVyLmRvbUVsZW1lbnQub25tb3VzZXdoZWVsIGNhbmNlbC1zY3JvbGwpXG4gICAgKHJlbmRlcmVyLmRvbUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciBcIk1vek1vdXNlUGl4ZWxTY3JvbGxcIiBjYW5jZWwtc2Nyb2xsIGZhbHNlKVxuICAgICguYXBwZW5kQ2hpbGQgcmVmcmVzaC1idXR0b24gYnV0dG9uLXRleHQpXG4gICAgKC5hcHBlbmRDaGlsZCBjb250YWluZXIgcmVuZGVyZXIuZG9tRWxlbWVudClcbiAgICAoLmFwcGVuZENoaWxkIGNvbnRhaW5lciBzZXR0aW5ncylcbiAgICAoLmFwcGVuZENoaWxkIHNldHRpbmdzIHJlZnJlc2gtYnV0dG9uKSkpXG5cblxuKGRlZm4gdXBkYXRlLWdlb21ldHJ5IFtnZW9tZXRyeSBoZWlnaHRtYXBdXG4gIChsb29wIFtpIDBdXG4gICAgKGlmICg8IGkgZ2VvbWV0cnkudmVydGljZXMubGVuZ3RoKVxuICAgICAgKGRvIChzZXQhICguLXogKGFnZXQgZ2VvbWV0cnkudmVydGljZXMgaSkpXG4gICAgICAgICAgICAgICAgKCogdGVycmFpbi1oZWlnaHQgKGFnZXQgKC4tZGF0YSBoZWlnaHRtYXApIGkpKSlcbiAgICAgICAgKHJlY3VyICgrIGkgMSkpKSkpXG4gIChnZW9tZXRyeS5jb21wdXRlVmVydGV4Tm9ybWFscylcbiAgZ2VvbWV0cnkpXG5cblxuOyBNYWluIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gbWFrZS1kZW1vIFtlbGVtZW50LWlkIGFsZ29yaXRobSBzaXplXVxuICAoZGVmIHNjZW5lIChuZXcgVEhSRUUuU2NlbmUpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQXhpc0hlbHBlciAxMDApKVxuXG4gIChkZWYgY2xvY2sgKG5ldyBUSFJFRS5DbG9jaykpXG4gIChkZWYgY2FtZXJhIChtYWtlLWNhbWVyYSkpXG4gIChkZWYgcmVuZGVyZXIgKG1ha2UtcmVuZGVyZXIpKVxuXG4gIChkZWYgZ2VvbWV0cnkpXG4gIChkZWYgcGxhbmUpXG5cbiAgKHNjZW5lLmFkZCAobWFrZS1kaXJlY3Rpb25hbC1saWdodCkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BbWJpZW50TGlnaHQgMHhmZmZmZmYgMC4wNSkpXG5cbiAgKGRlZm4gcmVmcmVzaCBbXVxuICAgIChsZXQgW2hlaWdodG1hcCAobWFrZS1oZWlnaHRtYXAgc2l6ZSldXG4gICAgICAobCBcIkdlbmVyYXRpbmcgdGVycmFpbi4uLlwiKVxuICAgICAgKHRpbWUgKGFsZ29yaXRobSBoZWlnaHRtYXApKVxuXG4gICAgICAobCBcIlJlYnVpbGRpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAgICh0aW1lXG4gICAgICAgIChzZXQhIGdlb21ldHJ5IChtYWtlLWdlb21ldHJ5IGhlaWdodG1hcCkpXG4gICAgICAgICh1cGRhdGUtZ2VvbWV0cnkgZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIHBsYW5lLi4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2NlbmUucmVtb3ZlIHBsYW5lKVxuICAgICAgICAoc2V0ISBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG4gICAgICAgIChzY2VuZS5hZGQgcGxhbmUpKSkpXG5cbiAgKGF0dGFjaC10by1kb20gcmVuZGVyZXIgZWxlbWVudC1pZCByZWZyZXNoKVxuICAoZGVmIGNvbnRyb2xzIChtYWtlLWNvbnRyb2xzIGNhbWVyYSByZW5kZXJlcikpXG5cbiAgKGRlZm4gcmVuZGVyIFtdXG4gICAgKGxldCBbZGVsdGEgKGNsb2NrLmdldERlbHRhKV1cbiAgICAgIChyZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcmVuZGVyKVxuICAgICAgKC51cGRhdGUgY29udHJvbHMgZGVsdGEpXG4gICAgICAocmVuZGVyZXIucmVuZGVyIHNjZW5lIGNhbWVyYSkpKVxuXG4gIChyZWZyZXNoKVxuICAocmVuZGVyKVxuXG4gIG5pbClcblxuKGRlZm4gbWFrZS1maW5hbCBbZWxlbWVudC1pZF1cbiAgKGRlZiBzY2VuZSAobmV3IFRIUkVFLlNjZW5lKSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkF4aXNIZWxwZXIgMTAwKSlcblxuICAoZGVmIGNsb2NrIChuZXcgVEhSRUUuQ2xvY2spKVxuICAoZGVmIGNhbWVyYSAobWFrZS1jYW1lcmEpKVxuICAoZGVmIHJlbmRlcmVyIChtYWtlLXJlbmRlcmVyKSlcblxuICAoZGVmIGdlb21ldHJ5KVxuICAoZGVmIHBsYW5lKVxuXG4gIChzY2VuZS5hZGQgKG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQW1iaWVudExpZ2h0IDB4ZmZmZmZmIDAuMDUpKVxuXG4gIChkZWZuIHJlZnJlc2ggW11cbiAgICAobGV0IFtoZWlnaHRtYXAgKG1ha2UtaGVpZ2h0bWFwIDYpXVxuICAgICAgKGwgXCJHZW5lcmF0aW5nIHRlcnJhaW4uLi5cIilcbiAgICAgICh0aW1lIChkaWFtb25kLXNxdWFyZSBoZWlnaHRtYXApKVxuXG4gICAgICAobCBcIlJlYnVpbGRpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAgICh0aW1lXG4gICAgICAgIChzZXQhIGdlb21ldHJ5IChtYWtlLWdlb21ldHJ5IGhlaWdodG1hcCkpXG4gICAgICAgICh1cGRhdGUtZ2VvbWV0cnkgZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIHBsYW5lLi4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2NlbmUucmVtb3ZlIHBsYW5lKVxuICAgICAgICAoc2V0ISBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG4gICAgICAgIChzY2VuZS5hZGQgcGxhbmUpKSkpXG5cbiAgKGF0dGFjaC10by1kb20gcmVuZGVyZXIgZWxlbWVudC1pZCByZWZyZXNoKVxuICAoZGVmIGNvbnRyb2xzIChtYWtlLWNvbnRyb2xzIGNhbWVyYSByZW5kZXJlcikpXG5cbiAgKGRlZm4gcmVuZGVyIFtdXG4gICAgKGxldCBbZGVsdGEgKGNsb2NrLmdldERlbHRhKV1cbiAgICAgIChyZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcmVuZGVyKVxuICAgICAgKC51cGRhdGUgY29udHJvbHMgZGVsdGEpXG4gICAgICAocmVuZGVyZXIucmVuZGVyIHNjZW5lIGNhbWVyYSkpKVxuXG4gIChyZWZyZXNoKVxuICAocmVuZGVyKVxuXG4gIG5pbClcblxuKGRlZm4gcnVuIFtdXG4gIChtYWtlLWRlbW8gXCJkZW1vLTFcIiBkaWFtb25kLXNxdWFyZS0xIDIpXG4gIChtYWtlLWRlbW8gXCJkZW1vLTJcIiBkaWFtb25kLXNxdWFyZS0yIDQpXG4gIChtYWtlLWRlbW8gXCJkZW1vLTNcIiBkaWFtb25kLXNxdWFyZS0zIDQpXG4gIChtYWtlLWZpbmFsIFwiZGVtby1maW5hbFwiKSlcblxuKCQgcnVuKVxuXG5cbjsgdmltOiBsdys9ZG8tdGltZXMgbHcrPWRvLW5lc3RlZCA6XG4iXX0= diff -r a52d61eb7e85 -r 2d9281a1f7e7 media/js/wisp/terrain3.wisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/media/js/wisp/terrain3.wisp Sat Jun 25 15:57:05 2016 +0000 @@ -0,0 +1,470 @@ +(ns demo + (:require [ndarray])) + + +; Constants ------------------------------------------------------------------- +(def width 610) +(def height 400) +(def wireframe true) +(def wireframe-width 1.2) +(def terrain-height 50) +(def terrain-size 100) + +; General Utilities ----------------------------------------------------------- +(defmacro when [condition & body] + `(if ~condition + (do ~@body))) + +(defmacro when-not [condition & body] + `(when (not ~condition) + ~@body)) + +(defmacro -> [& operations] + (reduce + (fn [form operation] + (cons (first operation) + (cons form (rest operation)))) + (first operations) + (rest operations))) + + +(defn inc [x] + (+ x 1)) + +(defn dec [x] + (- x 1)) + + +(defmacro do-times [varname limit & body] + (let [end (gensym)] + `(let [~end ~limit] + (loop [~varname 0] + (when (< ~varname ~end) + ~@body + (recur (inc ~varname))))))) + +(defmacro do-stride [varnames start-form end-form stride-form & body] + (let [stride (gensym "stride") + start (gensym "start") + end (gensym "end") + build (fn build [vars] + (if (empty? vars) + `(do ~@body) + (let [varname (first vars)] + `(loop [~varname ~start] + (when (< ~varname ~end) + ~(build (rest vars)) + (recur (+ ~varname ~stride)))))))] + ; Fix the numbers once outside the nested loops, + ; and then build the guts. + `(let [~start ~start-form + ~end ~end-form + ~stride ~stride-form] + ~(build varnames)))) + + +(defmacro do-ndarray [vars array-form & body] + (let [array-var (gensym "array") + build (fn build [vars n] + (if (empty? vars) + `(do ~@body) + `(do-times ~(first vars) (aget (.-shape ~array-var) ~n) + ~(build (rest vars) (inc n)))))] + `(let [~array-var ~array-form] + ~(build vars 0)))) + +(defmacro do-ndarray-el [element array-form & body] + (let [index (gensym "index") + array (gensym "array")] + `(let [~array ~array-form] + (do-times ~index (.-length (.-data ~array)) + (let [~element (aget (.-data ~array) ~index)] + ~@body))))) + + +(defmacro inc! [place] + `(set! ~place (inc ~place))) + +(defmacro add! [place amount] + `(set! ~place (+ ~place ~amount))) + + +(defmacro l [& forms] + `(console.log ~@forms)) + +(defmacro time [& body] + (let [start (gensym) + end (gensym) + result (gensym)] + `(let [~start (.getTime (new Date)) + ~result (do ~@body) + ~end (.getTime (new Date))] + (l (+ "Elapsed time: " (- ~end ~start) "ms.")) + ~result))) + + +(defn midpoint [a b] + (/ (+ a b) 2)) + +(defn average2 [a b] + (/ (+ a b) 2)) + +(defn average4 [a b c d] + (/ (+ a b c d) 4)) + +(defn safe-average [a b c d] + (let [total 0 count 0] + (when a (add! total a) (inc! count)) + (when b (add! total b) (inc! count)) + (when c (add! total c) (inc! count)) + (when d (add! total d) (inc! count)) + (/ total count))) + + +(defn even? [n] + (== 0 (mod n 2))) + +(defn odd? [n] + (== 1 (mod n 2))) + + +; Randomness ------------------------------------------------------------------ +(defn rand [] + (Math.random)) + +(defn rand-around-zero [spread] + (- (* spread (rand) 2) spread)) + +(defn jitter [value spread] + (+ value (rand-around-zero spread))) + + +; Heightmap Helpers ----------------------------------------------------------- +(defn heightmap-resolution [heightmap] + (aget heightmap.shape 0)) + +(defn heightmap-last-index [heightmap] + (dec (heightmap-resolution heightmap))) + +(defn heightmap-center-index [heightmap] + (midpoint 0 (heightmap-last-index heightmap))) + + +(defn heightmap-get [heightmap x y] + (.get heightmap x y)) + +(defn heightmap-get-safe [heightmap x y] + (let [last (heightmap-last-index heightmap)] + (when (and (<= 0 x last) + (<= 0 y last)) + (heightmap-get heightmap x y)))) + +(defn heightmap-set! [heightmap x y val] + (.set heightmap x y val)) + +(defn heightmap-set-if-unset! [heightmap x y val] + (when (== 0 (heightmap-get heightmap x y)) + (heightmap-set! heightmap x y val))) + + +(defn normalize [heightmap] + (let [max (- Infinity) + min Infinity] + (do-ndarray-el el heightmap + (when (< max el) (set! max el)) + (when (> min el) (set! min el))) + (let [span (- max min)] + (do-ndarray [x y] heightmap + (heightmap-set! heightmap x y + (/ (- (heightmap-get heightmap x y) min) + span)))))) + + +(defn make-heightmap [exponent] + (let [resolution (+ (Math.pow 2 exponent) 1)] + (let [heightmap (ndarray (new Float64Array (* resolution resolution)) + [resolution resolution])] + (set! heightmap.exponent exponent) + (set! heightmap.resolution resolution) + (set! heightmap.last (dec resolution)) + heightmap))) + + +(defn top-left-corner [heightmap] + (let [center (heightmap-center-index heightmap)] + (-> heightmap + (.lo 0 0) + (.hi (inc center) (inc center))))) + +(defn top-right-corner [heightmap] + (let [center (heightmap-center-index heightmap)] + (-> heightmap + (.lo center 0) + (.hi (inc center) (inc center))))) + +(defn bottom-left-corner [heightmap] + (let [center (heightmap-center-index heightmap)] + (-> heightmap + (.lo 0 center) + (.hi (inc center) (inc center))))) + +(defn bottom-right-corner [heightmap] + (let [center (heightmap-center-index heightmap)] + (-> heightmap + (.lo center center) + (.hi (inc center) (inc center))))) + + +; Diamond-Square -------------------------------------------------------------- +(defn ds-init-corners [heightmap] + (let [last (heightmap-last-index heightmap)] + (heightmap-set! heightmap 0 0 (rand)) + (heightmap-set! heightmap 0 last (rand)) + (heightmap-set! heightmap last 0 (rand)) + (heightmap-set! heightmap last last (rand)))) + +(defn ds-square [heightmap x y radius spread] + (let [new-height (jitter + (average4 + (heightmap-get heightmap (- x radius) (- y radius)) + (heightmap-get heightmap (- x radius) (+ y radius)) + (heightmap-get heightmap (+ x radius) (- y radius)) + (heightmap-get heightmap (+ x radius) (+ y radius))) + spread)] + (heightmap-set! heightmap x y new-height))) + +(defn ds-diamond [heightmap x y radius spread] + (let [new-height (jitter + (safe-average + (heightmap-get-safe heightmap (- x radius) y) + (heightmap-get-safe heightmap (+ x radius) y) + (heightmap-get-safe heightmap x (- y radius)) + (heightmap-get-safe heightmap x (+ y radius))) + spread)] + (heightmap-set! heightmap x y new-height))) + + +(defn ds-squares [heightmap radius spread] + (do-stride [x y] radius (heightmap-resolution heightmap) (* 2 radius) + (ds-square heightmap x y radius spread))) + +(defn ds-diamonds [heightmap radius spread] + (let [size (heightmap-resolution heightmap)] + (do-stride [y] 0 size radius + (let [shift (if (even? (/ y radius)) radius 0)] + (do-stride [x] shift size (* 2 radius) + (ds-diamond heightmap x y radius spread)))))) + +(defn diamond-square [heightmap] + (let [initial-spread 0.3 + spread-reduction 0.5 + center (heightmap-center-index heightmap) + size (aget heightmap.shape 0)] + (ds-init-corners heightmap) + (loop [radius center + spread initial-spread] + (when (>= radius 1) + (ds-squares heightmap radius spread) + (ds-diamonds heightmap radius spread) + (recur (/ radius 2) + (* spread spread-reduction)))) + (normalize heightmap))) + + +(defn diamond-square-1 [heightmap] + (ds-init-corners heightmap) + (normalize heightmap)) + +(defn diamond-square-2 [heightmap] + (let [initial-spread 0.3 + spread-reduction 0.5 + center (heightmap-center-index heightmap) + size (aget heightmap.shape 0)] + (ds-init-corners heightmap) + (ds-squares heightmap center initial-spread) + (normalize heightmap))) + +(defn diamond-square-3 [heightmap] + (let [initial-spread 0.3 + spread-reduction 0.5 + center (heightmap-center-index heightmap) + size (aget heightmap.shape 0)] + (ds-init-corners heightmap) + (ds-squares heightmap center initial-spread) + (ds-diamonds heightmap center initial-spread) + (ds-squares heightmap (/ center 2) (* spread-reduction initial-spread)) + (ds-diamonds heightmap (/ center 2) (* spread-reduction initial-spread)) + (normalize heightmap))) + + +; Three.js Helpers ------------------------------------------------------------ +(defn make-directional-light [] + (let [light (new THREE.DirectionalLight 0xffffff 1)] + (light.position.set 100 0 150) + light)) + +(defn make-camera [] + (let [camera (new THREE.PerspectiveCamera + 55, + (/ width height) + 0.1, + 1000)] + (camera.position.set 0 -100 150) + camera)) + +(defn make-renderer [] + (let [renderer (new THREE.WebGLRenderer {:antialias false})] + (renderer.setClearColor 0xffffff) + (renderer.setSize width height) + (renderer.setPixelRatio 2) + renderer)) + +(defn make-geometry [heightmap] + (let [resolution (aget heightmap.shape 0) + geometry (new THREE.PlaneGeometry + terrain-size + terrain-size + (- resolution 1) + (- resolution 1))] + geometry)) + +(defn make-controls [camera renderer] + (let [controls (new THREE.TrackballControls camera renderer.domElement)] + (set! controls.rotateSpeed 1.4) + (set! controls.zoomSpeed 0.5) + (set! controls.staticMoving true) + (set! controls.dynamicDampingFactor 0.3) + controls)) + +(defn make-plane [geometry] + (let [material (new THREE.MeshLambertMaterial + {:wireframe wireframe + :wireframeLinewidth wireframe-width + :color 0x00bb00})] + (new THREE.Mesh geometry material))) + + +(defn attach-to-dom [renderer el-name refresh-fn] + (let [container (document.getElementById el-name) + settings (document.createElement "div") + refresh-button (document.createElement "button") + button-text (document.createTextNode "Refresh") + cancel-scroll (fn [e] (.preventDefault e))] + (set! refresh-button.onclick refresh-fn) + (set! renderer.domElement.onmousewheel cancel-scroll) + (renderer.domElement.addEventListener "MozMousePixelScroll" cancel-scroll false) + (.appendChild refresh-button button-text) + (.appendChild container renderer.domElement) + (.appendChild container settings) + (.appendChild settings refresh-button))) + + +(defn update-geometry [geometry heightmap] + (loop [i 0] + (if (< i geometry.vertices.length) + (do (set! (.-z (aget geometry.vertices i)) + (* terrain-height (aget (.-data heightmap) i))) + (recur (+ i 1))))) + (geometry.computeVertexNormals) + geometry) + + +; Main ------------------------------------------------------------------------ +(defn make-demo [element-id algorithm size] + (def scene (new THREE.Scene)) + (scene.add (new THREE.AxisHelper 100)) + + (def clock (new THREE.Clock)) + (def camera (make-camera)) + (def renderer (make-renderer)) + + (def geometry) + (def plane) + + (scene.add (make-directional-light)) + (scene.add (new THREE.AmbientLight 0xffffff 0.05)) + + (defn refresh [] + (let [heightmap (make-heightmap size)] + (l "Generating terrain...") + (time (algorithm heightmap)) + + (l "Rebuilding geometry...") + (time + (set! geometry (make-geometry heightmap)) + (update-geometry geometry heightmap)) + + (l "Rebuilding plane...") + (time + (scene.remove plane) + (set! plane (make-plane geometry)) + (scene.add plane)))) + + (attach-to-dom renderer element-id refresh) + (def controls (make-controls camera renderer)) + + (defn render [] + (let [delta (clock.getDelta)] + (requestAnimationFrame render) + (.update controls delta) + (renderer.render scene camera))) + + (refresh) + (render) + + nil) + +(defn make-final [element-id] + (def scene (new THREE.Scene)) + (scene.add (new THREE.AxisHelper 100)) + + (def clock (new THREE.Clock)) + (def camera (make-camera)) + (def renderer (make-renderer)) + + (def geometry) + (def plane) + + (scene.add (make-directional-light)) + (scene.add (new THREE.AmbientLight 0xffffff 0.05)) + + (defn refresh [] + (let [heightmap (make-heightmap 6)] + (l "Generating terrain...") + (time (diamond-square heightmap)) + + (l "Rebuilding geometry...") + (time + (set! geometry (make-geometry heightmap)) + (update-geometry geometry heightmap)) + + (l "Rebuilding plane...") + (time + (scene.remove plane) + (set! plane (make-plane geometry)) + (scene.add plane)))) + + (attach-to-dom renderer element-id refresh) + (def controls (make-controls camera renderer)) + + (defn render [] + (let [delta (clock.getDelta)] + (requestAnimationFrame render) + (.update controls delta) + (renderer.render scene camera))) + + (refresh) + (render) + + nil) + +(defn run [] + (make-demo "demo-1" diamond-square-1 2) + (make-demo "demo-2" diamond-square-2 4) + (make-demo "demo-3" diamond-square-3 4) + (make-final "demo-final")) + +($ run) + + +; vim: lw+=do-times lw+=do-nested : diff -r a52d61eb7e85 -r 2d9281a1f7e7 settings.py --- a/settings.py Mon Mar 07 13:44:20 2016 +0000 +++ b/settings.py Sat Jun 25 15:57:05 2016 +0000 @@ -40,7 +40,8 @@ '*': { '.less': ('hydeengine.media_processors.LessCSS',), '.js': ('hydeengine.media_processors.TemplateProcessor', - 'hydeengine.media_processors.YUICompressor',) + # 'hydeengine.media_processors.YUICompressor', + ) }, 'images/': { '.png': ('hydeengine.media_processors.Thumbnail',),