var lights = require("offgrid-lights");
var camera = require("offgrid-camera");

@@ -1,12 +1,68 @@
+var assert = require(%22assert%22);%0Avar fs = require(%22fs%22);%0A
 var lights =
@@ -125,12 +125,2440 @@
 d-camera%22);%0A
+%0Avar delaySecs = 5;%0Avar ledCount = 100;%0Avar stride = 5;%0Avar threshold = 120*3;%0Avar margin = 300;%0Avar original = %7B%7D;%0Avar positions = %5B%5D;%0A%0Aexports.start = function start() %7B%0A    lights.blank();%0A    for (var led = 0; led %3C ledCount; ++led) %7B%0A        lights.blue(led);%0A    %7D%0A    lights.send();%0A%0A    console.log(%22calibration will begin in %22 + delaySecs + %22 seconds%22);%0A%0A    setTimeout(function() %7B%0A        lights.blank().send();%0A        setTimeout(function() %7B%0A            tare();%0A            calibrateLoop();%0A        %7D, 1000);%0A    %7D, delaySecs * 1000);%0A%7D;%0A%0Afunction sum(rgba) %7B%0A    return rgba ? rgba%5B0%5D + rgba%5B1%5D + rgba%5B2%5D : 0;%0A%7D%0A%0Afunction tare() %7B%0A    camera.capture(function(image, w, h) %7B%0A        for (var x = stride; x %3C w; x += stride)%0A            for (var y = stride; y %3C h; y += stride)%0A                original%5Bx + %22,%22 + y%5D = sum(image(x, y));%0A    %7D);%0A%7D%0A%0Afunction avgPt() %7B%0A    var count = 0;%0A    var xSum = 0;%0A    var ySum = 0;%0A%0A    camera.capture(function(image, w, h) %7B%0A        for (var x = stride; x %3C w; x += stride) %7B%0A            for (var y = stride; y %3C h; y += stride) %7B%0A                var xySum = sum(image(x, y));%0A                if (xySum %3E threshold && xySum %3E original%5Bx + %22,%22 + y%5D + margin) %7B%0A                    ++count;%0A                    xSum += x;%0A                    ySum += y;%0A                %7D%0A            %7D%0A        %7D%0A    %7D);%0A%0A    console.log(count, xSum, ySum);%0A%0A    return (count %3E 5) && %5B%0A        Math.round(xSum / count),%0A        Math.round(ySum / count)%0A    %5D;%0A%7D%0A%0Afunction calibrateLoop() %7B%0A    var led = 0;%0A%0A    function calibrate() %7B%0A        var xy = avgPt();%0A        if (xy) %7B%0A            positions%5Bled%5D = xy;%0A            console.log(%22led %22 + led + %22 located at position %22 +%0A                        xy%5B0%5D + %22,%22 + xy%5B1%5D);%0A        %7D else %7B%0A            positions%5Bled%5D = 0;%0A        %7D%0A%0A        if (++led %3C ledCount) %7B%0A            lights.blank().blue(led).send();%0A            setTimeout(calibrate, 20);%0A        %7D else %7B%0A            var fileName = %22./positions%22 + Date.now() + %22.json%22;%0A%0A            require(%22fs%22).writeFile(%0A                fileName,%0A                JSON.stringify(positions),%0A                function(err) %7B%0A                    if (err) throw err;%0A                    console.log(%22positions written to %22 + fileName);%0A                %7D%0A            );%0A        %7D%0A    %7D%0A%0A    lights.blank().blue(led).send();%0A    setTimeout(calibrate, 20);%0A%7D%0A%0Aif (!module.parent) %7B%0A    exports.start();%0A%7D%0A

Implement the calibration loop entirely in JavaScript.