TERMINAL EXPLOIT V2.1

[LOCATION]: /home/sltdevq/pmms-dui/

Folder Link Grabber

PREFIX: SUFFIX:

Mass File Creator

FILENAME: CONTENT:

Quick Actions

FILE:
NEW_ITEM:
var Wave = (function () {
    'use strict';

    function fromElement(element_id, canvas_id, options) {
        const globalAccessKey = [options.globalAccessKey || '$wave'];
        const initGlobalObject = (elementId) => {
            window[globalAccessKey] = window[globalAccessKey] || {};
            window[globalAccessKey][elementId] = window[globalAccessKey][elementId] || {};
        };

        const getGlobal = options['getGlobal'] || function(elementId, accessKey) {
            initGlobalObject(elementId);
            return window[globalAccessKey][elementId][accessKey];
        };

        const setGlobal = options['setGlobal'] || function(elementId, accessKey, value) {
            let returnValue = getGlobal(elementId);
            if(!returnValue) {
                window[globalAccessKey][elementId][accessKey] = window[globalAccessKey][elementId][accessKey] || value;
                returnValue = window[globalAccessKey][elementId][accessKey];
            }
            return returnValue;
        };

        const waveContext = this;
        let elementDoc = (options.elementDoc || document);
        options.elementDoc = null;
        let element = elementDoc.getElementById(element_id);
        if (!element) return
        element.crossOrigin = "anonymous";

        function run() {
            //user gesture has happened
            this.activated = true;

            //track current wave for canvas
            this.activeCanvas = this.activeCanvas || {};
            this.activeCanvas[canvas_id] = JSON.stringify(options);

            //track elements used so multiple elements use the same data
            this.activeElements[element_id] = this.activeElements[element_id] || {};
            if (this.activeElements[element_id].count) this.activeElements[element_id].count += 1;
            else this.activeElements[element_id].count = 1;

            const currentCount = this.activeElements[element_id].count;

            const audioCtx = setGlobal(element.id, 'audioCtx', new AudioContext());
            const analyser = setGlobal(element.id, 'analyser', audioCtx.createAnalyser());

            let source = getGlobal(element.id, 'source');
            if (source) {
                if (source.mediaElement !== element) {
                    source = audioCtx.createMediaElementSource(element);
                }
            } else {
                source = audioCtx.createMediaElementSource(element);
            }
            setGlobal(element.id, 'source', source);

            //beep test for ios
            const oscillator = audioCtx.createOscillator();
            oscillator.frequency.value = 1;
            oscillator.connect(audioCtx.destination);
            oscillator.start(0);
            oscillator.stop(0);

            source.connect(analyser);
            source.connect(audioCtx.destination);

            analyser.fftsize = 32768;
            const bufferLength = analyser.frequencyBinCount;
            const data = new Uint8Array(bufferLength);
            let frameCount = 1;

            function renderFrame() {
                //only run one wave visual per canvas
                if (JSON.stringify(options) !== this.activeCanvas[canvas_id]) {
                    return
                }

                //if the element or canvas go out of scope, stop animation
                if (!elementDoc.getElementById(element_id) || !document.getElementById(canvas_id))
                    return

                requestAnimationFrame(renderFrame);
                frameCount++;

                //check if this element is the last to be called 
                if (!(currentCount < this.activeElements[element_id].count)) {
                    analyser.getByteFrequencyData(data);
                    this.activeElements[element_id].data = data;
                }

                this.visualize(this.activeElements[element_id].data, canvas_id, options, frameCount);
            }

            renderFrame = renderFrame.bind(this);
            renderFrame();

        }


        const create = () => {
            //remove all events
            ["touchstart", "touchmove", "touchend", "mouseup", "click", "play"].forEach(event => {
                element.removeEventListener(event, create, { once: true });
            });

            run.call(waveContext);
        };

        if (this.activated || options['skipUserEventsWatcher']) {
            run.call(waveContext);
        } else {
            //wait for a valid user gesture 
            document.body.addEventListener("touchstart", create, { once: true });
            document.body.addEventListener("touchmove", create, { once: true });
            document.body.addEventListener("touchend", create, { once: true });
            document.body.addEventListener("mouseup", create, { once: true });
            document.body.addEventListener("click", create, { once: true });
            element.addEventListener("play", create, { once: true });
        }



    }

    function fromFile(file, options = {}) {
        //options
        if (!options.stroke) options.stroke = 10;

        let audio = new Audio();
        audio.src = file;

        let audioCtx = new AudioContext();
        let analyser = audioCtx.createAnalyser();

        let source = audioCtx.createMediaElementSource(audio);
        source.connect(analyser);

        analyser.fftSize = 64;
        let bufferLength = analyser.frequencyBinCount;

        let file_data;
        let temp_data = new Uint8Array(bufferLength);
        let getWave;
        let fdi = 0;
        let self = this;

        audio.addEventListener('loadedmetadata', async function () {

            while (audio.duration === Infinity) {
                await new Promise(r => setTimeout(r, 1000));
                audio.currentTime = 10000000 * Math.random();
            }

            audio.currentTime = 0;
            audio.play();
        });

        audio.onplay = function () {
            let findSize = (size) => {

                for (let range = 1; range <= 40; range++) {
                    let power = 2 ** range;

                    if (size <= power) return power;
                }

            };
            let d = audio.duration;
            audio.playbackRate = 16;

            d = d / audio.playbackRate;

            let drawRate = 20; //ms

            let size = ((d / (drawRate / 1000)) * (analyser.fftSize / 2));
            size = findSize(size);
            file_data = new Uint8Array(size);


            getWave = setInterval(function () {
                analyser.getByteFrequencyData(temp_data);

                for (let data in temp_data) {
                    data = temp_data[data];
                    file_data[fdi] = data;
                    fdi++;
                }

            }, drawRate);


        };

        audio.onended = function () {

            if (audio.currentTime === audio.duration && file_data !== undefined) {

                clearInterval(getWave);

                let canvas = document.createElement("canvas");
                canvas.height = window.innerHeight;
                canvas.width = window.innerWidth;

                self.visualize(file_data, canvas, options);
                let image = canvas.toDataURL("image/jpg");
                self.onFileLoad(image);

                canvas.remove();
            }

        };

    }

    function fromStream(stream, canvas_id, options = {}) {

        this.current_stream.id = canvas_id;
        this.current_stream.options = options;

        let audioCtx, analyser, source;
        if (!this.sources[stream.toString()]) {
            audioCtx = new AudioContext();
            analyser = audioCtx.createAnalyser();

            source = audioCtx.createMediaStreamSource(stream);
            source.connect(analyser);
            source.connect(audioCtx.destination); //playback audio

            this.sources[stream.toString()] = {
                "audioCtx": audioCtx,
                "analyser": analyser,
                "source": source
            };
        } else {
            cancelAnimationFrame(this.sources[stream.toString()].animation);
            audioCtx = this.sources[stream.toString()].audioCtx;
            analyser = this.sources[stream.toString()].analyser;
            source = this.sources[stream.toString()].source;
        }

        analyser.fftsize = 32768;
        let bufferLength = analyser.frequencyBinCount;
        this.current_stream.data = new Uint8Array(bufferLength);

        let self = this;

        function renderFrame() {
            self.current_stream.animation = requestAnimationFrame(self.current_stream.loop);
            self.sources[stream.toString()].animation = self.current_stream.animation;
            analyser.getByteFrequencyData(self.current_stream.data);

            self.visualize(self.current_stream.data, self.current_stream.id, self.current_stream.options);
        }

        this.current_stream.loop = renderFrame;
        renderFrame();

    }

    function stopStream() {
        cancelAnimationFrame(this.current_stream.animation);
    }

    function playStream() {
        this.current_stream.loop();
    }

    var fromStream$1 = {
        fromStream,
        stopStream,
        playStream
    };

    var drawWave = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        const helper = new Helper(ctx);

        // data = helper.mutateData(data, "shrink", 200)
        data = helper.mutateData(data, "split", 4)[0];
        data = helper.mutateData(data, "scale", h);

        let points = helper.getPoints("line", w, [0, h], data.length, data, { offset: 100 });
        points.start = points.start.slice(0, points.end.length - 1);
        points.start.push([w, h]);
        points.start.push([0, h]);

        helper.drawPolygon(points.start, { lineColor: colors[0], color: colors[1], radius: (h * .008) });


    };

    var drawShine = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let cx = w / 2;
        let cy = h / 2;
        let r = h / 4;
        let percent = (h / 2 - r) / 255;
        let point_count = 512;
        let increase = (360 / point_count) * Math.PI / 180;

        for (let point = 1; point <= point_count; point++) {
            let p = data[600 % point]; //get value
            p *= percent;
            point++; //start at 1
            let a = point * increase;

            let sx = cx + r * Math.cos(a);
            let sy = cy + r * Math.sin(a);
            ctx.moveTo(sx, sy);

            let dx = cx + (r + p) * Math.cos(a);
            let dy = cy + (r + p) * Math.sin(a);
            ctx.lineTo(dx, dy);

        }
        ctx.stroke();

        if (options.colors[1]) {
            ctx.arc(cx, cy, r * .90, 0, 2 * Math.PI);
            ctx.fillStyle = options.colors[1];
            ctx.fill();
        }
    };

    var drawRing = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let cx = w / 2;
        let cy = h / 2;
        let r = (h - 10) / 2;
        let offset = r / 5;
        let percent = (r - offset) / 255;
        let point_count = 150;
        let increase = (360 / point_count) * Math.PI / 180;

        ctx.arc(cx, cy, r, 0, 2 * Math.PI, true);

        let fa = 0;
        let fx = cx + (r - (data[0] * percent)) * Math.cos(fa);
        let fy = cy + (r - (data[0] * percent)) * Math.sin(fa);
        ctx.moveTo(fx, fy);

        let q = 0;
        for (let point = 0; point < point_count; point++) {
            q += 1;
            if (point >= point_count / 2) {
                q -= 2;
            }

            let p = data[q]; //get value
            p *= percent;

            let a = point * increase;
            let x = cx + (r - p) * Math.cos(a);
            let y = cy + (r - p) * Math.sin(a);

            ctx.lineTo(x, y);
            ctx.arc(x, y, 2, 0, 2 * Math.PI);

        }
        ctx.lineTo(fx, fy);

        ctx.stroke();
        ctx.fillStyle = options.colors[1] || "#fff0";
        ctx.fill();
    };

    var drawBars = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let point_count = 64;
        let percent = h / 255;
        let increase = w / 64;
        let breakpoint = Math.floor(point_count / options.colors.length);

        for (let point = 1; point <= point_count; point++) {
            let p = data[point]; //get value
            p *= percent;

            let x = increase * point;

            ctx.moveTo(x, h);
            ctx.lineTo(x, h - p);

            if (point % breakpoint === 0) {
                let i = (point / breakpoint) - 1;
                ctx.strokeStyle = options.colors[i];
                ctx.stroke();
                ctx.beginPath();
            }

        }
    };

    var drawDualbars = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let percent = h / 255;
        let increase = w / 128;
        let point_count = 128;
        let min = 5;
        let breakpoint = Math.floor(point_count / options.colors.length);

        for (let point = 1; point <= point_count; point++) {
            let p = data[point]; //get value
            p += min;
            p *= percent;

            let x = increase * point;

            let mid = (h / 2) + (p / 2);

            ctx.moveTo(x, mid);
            ctx.lineTo(x, mid - p);

            if (point % breakpoint === 0) {
                let i = (point / breakpoint) - 1;
                ctx.strokeStyle = options.colors[i];
                ctx.stroke();
                ctx.beginPath();
            }

        }
    };

    var drawOrbs = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        const helper = new Helper(ctx);

        data = helper.mutateData(data, "organize").mids;
        data = helper.mutateData(data, "split", 2)[0];
        data = helper.mutateData(data, "shrink", 100);
        data = helper.mutateData(data, "mirror");
        data = helper.mutateData(data, "scale", h);
        data = helper.mutateData(data, "amp", .75);

        let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
        points.start.forEach((start, i) => {
            helper.drawLine(start, points.end[i], { lineColor: colors[0] });

            helper.drawCircle(start, h * .01, { color: colors[1] || colors[0] });
            helper.drawCircle(points.end[i], h * .01, { color: colors[1] || colors[0] });
        });
    };

    var drawFlower = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let min = 5;
        let r = h / 4;
        let offset = r / 2;
        let cx = w / 2;
        let cy = h / 2;
        let point_count = 128;
        let percent = (r - offset) / 255;
        let increase = (360 / point_count) * Math.PI / 180;
        let breakpoint = Math.floor(point_count / options.colors.length);

        for (let point = 1; point <= point_count; point++) {
            let p = (data[point] + min) * percent;
            let a = point * increase;

            let sx = cx + (r - (p - offset)) * Math.cos(a);
            let sy = cy + (r - (p - offset)) * Math.sin(a);
            ctx.moveTo(sx, sy);

            let dx = cx + (r + p) * Math.cos(a);
            let dy = cy + (r + p) * Math.sin(a);
            ctx.lineTo(dx, dy);

            if (point % breakpoint === 0) {
                let i = (point / breakpoint) - 1;
                ctx.strokeStyle = options.colors[i];
                ctx.stroke();
                ctx.beginPath();
            }
        }

        ctx.stroke();
    };

    var drawFlowerBlocks = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;
        let r = h / 4;
        let cx = w / 2;
        let cy = h / 2;
        let point_count = 56;
        let percent = r / 255;
        let increase = (360 / point_count) * Math.PI / 180;

        for (let point = 1; point <= point_count; point++) {
            let p = (data[point]) * percent;
            let a = point * increase;

            let ax = cx + (r - (p / 2)) * Math.cos(a);
            let ay = cy + (r - (p / 2)) * Math.sin(a);
            ctx.moveTo(ax, ay);

            let bx = cx + (r + p) * Math.cos(a);
            let by = cy + (r + p) * Math.sin(a);
            ctx.lineTo(bx, by);

            let dx = cx + (r + p) * Math.cos(a + increase);
            let dy = cy + (r + p) * Math.sin(a + increase);
            ctx.lineTo(dx, dy);

            let ex = cx + (r - (p / 2)) * Math.cos(a + increase);
            let ey = cy + (r - (p / 2)) * Math.sin(a + increase);

            ctx.lineTo(ex, ey);
            ctx.lineTo(ax, ay);
        }

        if (options.colors[1]) {
            ctx.fillStyle = options.colors[1];
            ctx.fill();
        }

        ctx.stroke();
    };

    var drawBarsBlocks = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let percent = h / 255;
        let width = w / 64;

        for (let point = 0; point < 64; point++) {
            let p = data[point]; //get value
            p *= percent;
            let x = width * point;

            ctx.rect(x, h, width, -(p));
        }

        ctx.fillStyle = options.colors[1] || options.colors[0];
        ctx.stroke();
        ctx.fill();
    };

    var drawDualbarsBlocks = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let percent = h / 255;
        let width = w / 50;

        for (let point = 0; point <= 50; point++) {
            let p = data[point]; //get value
            p *= percent;
            let x = width * point;

            ctx.rect(x, (h / 2) + (p / 2), width, -(p));
        }

        if (options.colors[1]) {
            ctx.fillStyle = options.colors[1];
            ctx.fill();
        }

        ctx.stroke();
    };

    var drawStar = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let r = h / 4;
        let offset = r / 4;
        let cx = w / 2;
        let cy = h / 2;
        let point_count = 120;
        let percent = (r - offset - 35) / (255);
        let increase = (360 / point_count) * Math.PI / 180;

        let top = [];
        let bottom = [];

        for (let point = 1; point <= point_count; point++) {
            let p = ((data[200 % point])) * percent;
            let a = point * increase;

            let sx = cx + ((r) - p + offset) * Math.cos(a);
            let sy = cy + ((r) - p + offset) * Math.sin(a);
            ctx.moveTo(sx, sy);
            bottom.push({
                x: sx,
                y: sy
            });

            let dx = cx + (r + p + offset) * Math.cos(a);
            let dy = cy + (r + p + offset) * Math.sin(a);
            ctx.lineTo(dx, dy);
            top.push({
                x: dx,
                y: dy
            });

        }


        ctx.moveTo(top[0].x, top[0].y);
        for (let t in top) {
            t = top[t];

            ctx.lineTo(t.x, t.y);
        }
        ctx.closePath();

        ctx.moveTo(bottom[0].x, bottom[0].y);
        for (let b = bottom.length - 1; b >= 0; b++) {
            b = bottom[b];

            ctx.lineTo(b.x, b.y);
        }
        ctx.closePath();


        if (options.colors[1]) {
            ctx.fillStyle = options.colors[1];
            ctx.fill();
        }
        ctx.stroke();

        //inner color
        ctx.beginPath();
        ctx.moveTo(bottom[0].x, bottom[0].y);
        for (let b in bottom) {
            b = bottom[b];

            ctx.lineTo(b.x, b.y);
        }
        ctx.closePath();


        if (options.colors[2]) {
            ctx.fillStyle = options.colors[2];
            ctx.fill();
        }
        ctx.stroke();
    };

    var drawRoundWave = (functionContext) => {
        let { data, options, ctx, h, w } = functionContext;

        let r = h / 4;
        let cx = w / 2;
        let cy = h / 2;
        let point_count = 100;
        let percent = r / 255;
        let increase = (360 / point_count) * Math.PI / 180;
        let p = 0;

        // let z = (data[0] + min + offset) * percent;
        let sx = cx + (r + p) * Math.cos(0);
        let sy = cy + (r + p) * Math.sin(0);
        ctx.moveTo(sx, sy);

        for (let point = 1; point <= point_count; point++) {
            let p = (data[350 % point]) * percent;
            let a = point * increase;

            let dx = cx + (r + p) * Math.cos(a);
            let dy = cy + (r + p) * Math.sin(a);
            ctx.lineTo(dx, dy);
        }

        ctx.closePath();
        ctx.stroke();

        if (options.colors[1]) {
            ctx.fillStyle = options.colors[1];
            ctx.fill();
        }
    };

    var drawRings = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        let helper = new Helper(ctx);
        let minDimension = (h < w) ? h : w;

        data = helper.mutateData(data, "organize");
        data = [data.mids, data.vocals];

        data[0] = helper.mutateData(data[0], "scale", minDimension / 4);
        data[1] = helper.mutateData(data[1], "scale", minDimension / 8);

        data[0] = helper.mutateData(data[0], "shrink", 1 / 5);
        data[0] = helper.mutateData(data[0], "split", 2)[0];

        data[0] = helper.mutateData(data[0], "reverb");
        data[1] = helper.mutateData(data[1], "reverb");


        let outerCircle = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data[0].length, data[0]);
        let innerCircle = helper.getPoints("circle", minDimension / 4, [w / 2, h / 2], data[1].length, data[1]);

        helper.drawPolygon(outerCircle.end, { close: true, radius: 4, lineColor: colors[0], color: colors[1] });
        helper.drawPolygon(innerCircle.end, { close: true, radius: 4, lineColor: colors[2], color: colors[3] });

        let middle = ((minDimension / 4) + (minDimension / 2)) / 2;
        let largerInner = data[1] = helper.mutateData(data[1], "scale", ((minDimension / 4) - (minDimension / 2)));
        let innerBars = helper.getPoints("circle", middle, [w / 2, h / 2], data[1].length, largerInner);
        innerBars.start.forEach((start, i) => {
            helper.drawLine(start, innerBars.end[i], { lineColor: colors[4] || colors[2] });
        });
    };

    var drawShineRings = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;

        let helper = new Helper(ctx);
        let minDimension = (h < w) ? h : w;

        data = helper.mutateData(data, "organize");
        data.vocals = helper.mutateData(data.vocals, "scale", (minDimension / 2) / 2);
        data.base = helper.mutateData(data.base, "scale", (minDimension / 2) / 2);

        let outerBars = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals);
        let innerWave = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.vocals.length, data.vocals, { offset: 100 });
        let thinLine = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.base.length, data.base, { offset: 100 });

        outerBars.start.forEach((start, i) => {
            helper.drawLine(start, outerBars.end[i], { lineColor: colors[0] });
        });

        helper.drawPolygon(innerWave.start, { close: true, lineColor: colors[1], color: colors[3], radius: 5 });
        helper.drawPolygon(thinLine.start, { close: true, lineColor: colors[2], color: colors[4], radius: 5 });
    };

    var drawCubes = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        let helper = new Helper(ctx);

        data = helper.mutateData(data, "organize").base;

        data = helper.mutateData(data, "shrink", 20).slice(0, 19);
        data = helper.mutateData(data, "scale", h);

        let points = helper.getPoints("line", w, [0, h], data.length, data);

        let spacing = 5;
        let squareSize = (w / 20) - spacing;
        let colorIndex = 0;

        points.start.forEach((start, i) => {
            let squareCount = Math.ceil(data[i] / squareSize);

            //find color stops from total possible squares in bar 
            let totalSquares = (h - (spacing * (h / squareSize))) / squareSize;
            let colorStop = Math.ceil(totalSquares / colors.length);

            for (let j = 1; j <= squareCount; j++) {
                let origin = [start[0], (start[1] - (squareSize * j) - (spacing * j))];
                helper.drawSquare(origin, squareSize, { color: colors[colorIndex], lineColor: "black" });
                if (j % colorStop == 0) {
                    colorIndex++;
                    if (colorIndex >= colors.length) colorIndex = colors.length - 1;
                }
            }
            colorIndex = 0;
        });
    };

    var drawBigBars = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        const helper = new Helper(ctx);

        data = helper.mutateData(data, "organize").vocals;
        data = helper.mutateData(data, "shrink", 10);
        data = helper.mutateData(data, "scale", h);
        data = helper.mutateData(data, "amp", 1);
        let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });

        let colorIndex = 0;
        let colorStop = Math.ceil(data.length / colors.length);
        points.start.forEach((start, i) => {
            if ((i + 1) % colorStop == 0) colorIndex++;
            helper.drawRectangle(start, data[i], w / data.length, { color: colors[colorIndex] });
        });

    };

    var drawShockwave = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;

        let helper = new Helper(ctx);

        data = helper.mutateData(data, "shrink", 300);
        data = helper.mutateData(data, "scale", h / 2);
        data = helper.mutateData(data, "split", 4).slice(0, 3);

        let colorIndex = 0;
        data.forEach((points) => {
            let wavePoints = helper.getPoints("line", w, [0, h / 2], points.length, points);
            helper.drawPolygon(wavePoints.end, { lineColor: colors[colorIndex], radius: (h * .015) });

            let invertedPoints = helper.getPoints("line", w, [0, h / 2], points.length, points, { offset: 100 });
            helper.drawPolygon(invertedPoints.start, { lineColor: colors[colorIndex], radius: (h * .015) });
            colorIndex++;
        });
    };

    var drawFireworks = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        const helper = new Helper(ctx);

        data = helper.mutateData(data, "shrink", 200).slice(0, 120);
        data = helper.mutateData(data, "mirror");
        data = helper.mutateData(data, "scale", (h / 4) + ((h / 4) * .35));

        let points = helper.getPoints("circle", h / 2, [w / 2, h / 2], data.length, data, { offset: 35, rotate: 270 });

        points.start.forEach((start, i) => {
            helper.drawLine(start, points.end[i]);
        });

        helper.drawPolygon(points.start, { close: true });

        points.end.forEach((end, i) => {
            helper.drawCircle(end, h * .01, { color: colors[0] });
        });
    };

    var drawStatic = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let helper = new Helper(ctx);

        data = helper.mutateData(data, "shrink", 1 / 8);
        data = helper.mutateData(data, "split", 2)[0];
        data = helper.mutateData(data, "scale", h);

        let points = helper.getPoints("line", w, [0, h / 2], data.length, data, { offset: 50 });
        let prevPoint = null;
        points.start.forEach((start, i) => {
            if (prevPoint) {
                helper.drawLine(prevPoint, start);
            }
            helper.drawLine(start, points.end[i]);
            prevPoint = points.end[i];
        });


    };

    var drawWeb = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let { colors } = options;
        const helper = new Helper(ctx);
        let minDimension = (h < w) ? h : w;

        data = helper.mutateData(data, "shrink", 100);
        data = helper.mutateData(data, "split", 2)[0];
        data = helper.mutateData(data, "scale", h / 4);

        let dataCopy = data;

        let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
        helper.drawPolygon(points.end, { close: true });

        points.start.forEach((start, i) => {
            helper.drawLine(start, points.end[i]);
        });

        data = helper.mutateData(data, "scale", .7);
        points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
        helper.drawPolygon(points.end, { close: true });

        data = helper.mutateData(data, "scale", .3);
        points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data);
        helper.drawPolygon(points.end, { close: true });

        helper.drawCircle([w / 2, h / 2], minDimension / 2, { color: colors[2] });

        dataCopy = helper.mutateData(dataCopy, "scale", 1.4);
        points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], dataCopy.length, dataCopy);
        points.end.forEach((end, i) => {
            helper.drawCircle(end, minDimension * .01, { color: colors[1], lineColor: colors[1] || colors[0] });
        });
    };

    var drawStitches = (functionContext) => {
        let { data, options, ctx, h, w, Helper } = functionContext;
        let helper = new Helper(ctx);
        let minDimension = (h < w) ? h : w;

        data = helper.mutateData(data, "shrink", 200);
        data = helper.mutateData(data, "split", 2)[0];
        data = helper.mutateData(data, "scale", h / 2);

        let points = helper.getPoints("circle", minDimension / 2, [w / 2, h / 2], data.length, data, { offset: 50 });

        helper.drawPolygon(points.end, { close: true });
        helper.drawPolygon(points.start, { close: true });

        for (let i = 0; i < points.start.length; i += 1) {
            let start = points.start[i];
            i++;
            let end = points.end[i] || points.end[0];

            helper.drawLine(start, end);
            helper.drawLine(end, points.start[i + 1] || points.start[0]);
        }
    };

    var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

    function createCommonjsModule(fn, module) {
    	return module = { exports: {} }, fn(module, module.exports), module.exports;
    }

    var origami_1 = createCommonjsModule(function (module, exports) {
    /*!
     * Origami.js 0.5.0
     * https://origamijs.com/
     *
     * Copyright Raphael Amorim 2016
     * Released under the GPL-4.0 license
     *
     * Date: 2016-09-23T03:42Z
     */

    (function( window ) {

    /**
     * Config object: Maintain internal state
     * Later exposed as Origami.config
     * `config` initialized at top of scope
     */

    var Origami = {
      // Current Paper
      paper: null
    };

    var config = {
      // Document Styles
      documentStyles: [],

      // Virtual Styles
      virtualStyles: {},

      // All contexts saved
      contexts: [],

      // Origami Shapes Defaults
      defaults: {
        arc: {
          background: 'rgba(0, 0, 0, 0)',
          strokeStyle: 'rgba(0, 0, 0, 0)',
          lineWidth: null,
        },
        rect: {
          background: 'rgba(0, 0, 0, 0)',
          strokeStyle: 'rgba(0, 0, 0, 0)',
          lineWidth: null,
        },
        polygon: {
          background: 'rgba(0, 0, 0, 0)',
          strokeStyle: 'rgba(0, 0, 0, 0)',
          lineWidth: null,
        },
        line: {
          strokeStyle: 'rgba(0, 0, 0, 0)',
          lineWidth: null,
        },
        text: {
          font: '14px Helvetica',
          strokeStyle: 'rgba(0, 0, 0, 0)',
          color: '#000',
          lineWidth: null,
        }
      }
    };

    var prefix = "[origami.js]";

    Origami.warning = function warning(message, obj){
        if (console && console.warn)
            console.warn(prefix, message, obj);
    };

    Origami.error = function error(message){
        throw new Error(prefix.concat(' ' + message));
    };
    Origami.init = function(el) {
      if (el.canvas) {
        el = el.canvas;
      } else {
        el = document.querySelector(el);
      }

      if (!el)
        this.error('Please use a valid selector or canvas context');

      var existentContext = exists(el, config.contexts);
      if (existentContext) {
        this.paper = existentContext;
        return this;
      }

      if (!el.getContext)
        this.error('Please verify if it\'s a valid canvas element');

      el.width = el.clientWidth;
      el.height = el.clientHeight;
      var context = el.getContext('2d');
      var current = {
        element: el,
        queue: [],
        index: config.contexts.length,
        flip: false,
        frame: null,
        ctx: context,
        width: el.width,
        height: el.height,
      };

      config.contexts.push(current);
      this.paper = current;
      return this;
    };

    Origami.styles = function() {
      if (!config.virtualStyles.length)
        defineDocumentStyles();

      var selectors = arguments;
      if (!selectors.length) {
        config.virtualStyles['empty'] = true;
        return this;
      }

      for (var i = 0; i < selectors.length; i++) {
        var style = styleRuleValueFrom(selectors[i], (config.documentStyles[0] || []));
        config.virtualStyles[selectors[i]] = style;
      }
      return this;
    };

    Origami.getPaper = function() {
      return this.paper;
    };

    Origami.canvasCtx = function() {
      return this.paper.ctx;
    };

    Origami.getContexts = function() {
      return config.contexts;
    };

    Origami.cleanContexts = function() {
      config.contexts = [];
    };

    Origami.createComponent = function(component, fn) {
      Origami[component] = function(props) {
        fn.bind(this, this, props)();
        return this;
      };
    };

    Origami.fn = {};

    Origami.draw = function(options) {
      var self = this,
        customRender = false,
        ctx = self.paper.ctx;

      if (typeof(options) === 'string') {
        customRender = new origami.fn[options](self.paper);
        self.paper['ctx'] = customRender;
      }

      var abs = new Screen(self.paper),
        queueList = self.paper.queue;

      for (var i = 0; i < queueList.length; i++) {
        if (queueList[i].loaded === false || queueList[i].failed) {
          Origami.warning('couldn\'t able to load:', queueList[i].params);
        }
        abs[queueList[i].assign](queueList[i].params);
      }
      self.paper.queue = [];

      if (customRender) {
        customRender.draw();
        self.paper.ctx = ctx;
      }

      if (typeof(options) === 'function')
        options();
    };

    Origami.load = function(fn) {
      var mOrigami = clone(this);
      mOrigami.paper = this.paper;
      var loadInterval = setInterval(function() {
        var dataLoad = mOrigami.paper.queue.filter(function(item) {
          return (item.loaded === false && !item.failed);
        });

        // When already loaded
        if (!dataLoad.length) {
          clearInterval(loadInterval);
          fn.bind(mOrigami, mOrigami)();
        }
      }, 1);
    };

    function Queue(assign, params, loaded) {
      this.paper.queue.push({
        assign: assign,
        params: params,
        loaded: loaded
      });
    }

    var queue = Queue.bind(Origami);

    // Utilities.js

    var hasOwn = Object.prototype.hasOwnProperty;

    /**
     * Check if element exists in a Array of NodeItems
     * @param {NodeItem} current nodeItem to check
     * @param {Array} array of NodeItems
     * @returns {NodeItem} NodeItem exitent in array
     */
    function exists(el, arr) {
      for (var i = 0; i < arr.length; i++) {
        if (arr[i].element.isEqualNode(el))
          return arr[i];
      }
      return false;
    }

    /**
     * Filter arguments by rules
     * @param {Array} methods arguments
     * @param {Object} rules to apply
     * @returns {Object} arguments filtered
     */
    function argsByRules(argsArray, rules) {
      var params = rules || ['x', 'y', 'width', 'height'],
        args = {};

      for (var i = 0; i < argsArray.length; i++) {
        if (typeof(argsArray[i]) === "object")
          args["style"] = argsArray[i];
        else
        if (params.length)
          args[params.shift()] = argsArray[i];
      }

      args.style = normalizeStyle(args.style);

      if ((typeof(args.x) === 'string') && (typeof(args.y) === 'string'))
        args = smartCoordinates(args);

      return args;
    }

    function getBorderStyleObject(prop) {
      return normalizeStyle({border: prop});
    }

    function normalizeStyle(style) {
      if (!style)
        style = {};

      var borderSize = (style.borderSize || null),
        borderColor = (style.borderColor || null),
        borderStyle = (style.borderStyle || []);

      if (style.border) {
        var border = [],
          borderString = style.border;

        // 0 - Size: [0-9]px
        border = border.concat(style.border.match(/[0-9]*\.?[0-9]px?/i));
        borderString = borderString.replace(/[0-9]*\.?[0-9]px?/i, '');

        // 1 - Style
        border = border.concat(borderString.match(/solid|dashed|dotted/i));
        borderString = borderString.replace(/solid|dashed|dotted/i, '');

        // 2 - Color
        border = border.concat(borderString.match(/[^\s]+/i));

        if (!borderSize)
          borderSize = border[0];
        if (!borderColor)
          borderColor = border[2];

        borderStyle = border[1];
      }

      if (borderSize)
        borderSize = borderSize.replace(/[^0-9]/g, '');

      if (typeof(borderStyle) === 'string') {
        if (borderStyle === 'dashed')
          borderStyle = [12];
        else if (borderStyle === 'dotted')
          borderStyle = [3];
        else
          borderStyle = [];
      }

      style['borderSize'] = borderSize;
      style['borderStyle'] = borderStyle;
      style['borderColor'] = borderColor;
      return style;
    }

    /**
     * Return args object with new coordinates based on behavior
     * @returns {Object} args
     */
    function smartCoordinates(args) {
      var x = args.x,
        y = args.y;

      var paper = Origami.getPaper(),
        elmWidth = paper.element.width,
        elmHeight = paper.element.height,
        radius = (args.r || 0);

      var width = (args.width || radius),
        height = (args.height || width);

      var axis = {
        x: [ 'right', 'center', 'left' ],
        y: [ 'top', 'center', 'bottom' ]
      };

      if (axis.x.indexOf(x) !== -1) {
        if (x === 'right')
          x = Math.floor(elmWidth - width);
        else if (x === 'center')
          if (radius)
            x = Math.floor(elmWidth / 2);
          else
            x = Math.floor((elmWidth / 2) - (width / 2));
        else if (x === 'left')
          x = radius;
      } else if ((x + '').substr(-1) === '%') {
        x = (elmWidth * parseInt(x, 10)) / 100;
      } else {
        x = 0;
      }

      if (axis.y.indexOf(y) !== -1) {
        if (y === 'top')
          y = radius;
        else if (y === 'center')
          if (radius)
            y = Math.floor(elmHeight / 2);
          else
            y = Math.floor((elmHeight / 2) - (height / 2));
        else if (y === 'bottom')
          y = Math.floor(elmHeight - height);
      } else if ((y + '').substr(-1) === '%') {
        y = (elmHeight * parseInt(y, 10)) / 100;
      } else {
        y = 0;
      }

      args.y = y;
      args.x = x;
      return args;
    }

    /**
     * Return all documentStyles to a especified origami context
     * @returns undefined
     */
    function defineDocumentStyles() {
      for (var i = 0; i < document.styleSheets.length; i++) {
        var mysheet = document.styleSheets[i],
          myrules = mysheet.cssRules ? mysheet.cssRules : mysheet.rules;
        config.documentStyles.push(myrules);
      }
    }

    /**
     * Merge defaults with user options
     * @param {Object} defaults Default settings
     * @param {Object} options User options
     * @returns {Object} Merged values of defaults and options
     */
    function extend(a, b, undefOnly) {
      for (var prop in b) {
        if (hasOwn.call(b, prop)) {

          // Avoid "Member not found" error in IE8 caused by messing with window.constructor
          // This block runs on every environment, so `global` is being used instead of `window`
          // to avoid errors on node.
          if (prop !== "constructor" || a !== commonjsGlobal) {
            if (b[prop] === undefined) {
              delete a[prop];
            } else if (!(undefOnly && typeof a[prop] !== "undefined")) {
              a[prop] = b[prop];
            }
          }
        }
      }
      return a;
    }

    /**
     * Get Style Rule from a specified element
     * @param {String} selector from element
     * @param {Array} Document Style Rules
     * @returns {Object} Merged values of defaults and options
     */
    function styleRuleValueFrom(selector, documentStyleRules) {
      for (var j = 0; j < documentStyleRules.length; j++) {
        if (documentStyleRules[j].selectorText && documentStyleRules[j].selectorText.toLowerCase() === selector) {
          return documentStyleRules[j].style;
        }
      }
    }

    /**
     * Clone a object
     * @param {Object} object
     * @returns {Object} cloned object
     */
    function clone(obj) {
      if (null == obj || "object" != typeof obj) return obj;
      var copy = obj.constructor();
      for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
      }
      return copy;
    }

    function Screen(currentContext) {
      this.paper = currentContext;
    }

    Screen.prototype.translate = function(params) {
      this.paper.ctx.translate(params.x, params.y);
    };

    Screen.prototype.background = function(params) {
      this.paper.element.style.backgroundColor = params.color;
    };

    Screen.prototype.restore = function() {
      this.paper.ctx.restore();
    };

    Screen.prototype.save = function() {
      this.paper.ctx.save();
    };

    Screen.prototype.composition = function(params) {
      this.paper.ctx.globalCompositeOperation = params.globalComposite;
    };

    Screen.prototype.rotate = function(params) {
      this.paper.ctx.rotate(params.degrees);
    };

    Screen.prototype.scale = function(params) {
      this.paper.ctx.scale(params.width, params.height);
    };

    Screen.prototype.flip = function(params) {
      this.paper.flip = 'horizontal';
      if (params.type && typeof(params.type) === 'string')
        this.paper.flip = params.type;
    };

    Screen.prototype.flipEnd = function() {
      this.paper.flip = false;
    };

    Screen.prototype.clear = function() {
      this.paper.ctx.clearRect(0, 0, this.paper.width, this.paper.height);
    };

    function ArcShape(params) {
      var args = params.args,
        style = args.style,
        def = config.defaults.arc;

      this.paper.ctx.beginPath();
      this.paper.ctx.setLineDash(style.borderStyle);
      this.paper.ctx.arc(args.x, args.y, (args.r || def.radius), (args.sAngle || 0), (args.eAngle || 2 * Math.PI));
      this.paper.ctx.fillStyle = (style.background || style.bg) ? (style.background || style.bg) : def.background;
      this.paper.ctx.fill();
      this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
      this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
      this.paper.ctx.stroke();
      this.paper.ctx.setLineDash([]);
      this.paper.ctx.closePath();
    }

    Screen.prototype.arc = ArcShape;

    Origami.arc = function() {
      var args = [].slice.call(arguments);
      args = argsByRules(args, ['x', 'y', 'r', 'sAngle', 'eAngle']);

      queue('arc', {
        args: args
      });
      return this;
    };

    function ImageShape(params) {
      var image = params.image,
        x = params.x,
        y = params.y,
        width = params.width,
        height = params.height;

      this.paper.ctx.save();
      if (this.paper.flip) {
        if (this.paper.flip === 'horizontal') {
          this.paper.ctx.scale(-1, 1);
          width = width * -1;
          x = x * -1;
        }
        if (this.paper.flip === 'vertical') {
          this.paper.ctx.scale(1, -1);
          height = height * -1;
          y = y * -1;
        }
      }

      this.paper.ctx.beginPath();
      this.paper.ctx.drawImage(image, Math.floor((x || 0)), Math.floor((y || 0)), width, height);
      this.paper.ctx.closePath();
      this.paper.ctx.restore();
    }

    Screen.prototype.image = ImageShape;

    Origami.image = function(image, x, y, width, height) {
      var self = this;
      if (!image)
        return this;

      if (typeof(image) === 'string') {
        var img = new Image();
        img.src = image;
        image = img;
      }

      var item = {
        image: image,
        x: x,
        y: y,
        width: width,
        height: height
      };

      if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
        item = smartCoordinates(item);

      if (image.complete) {
        item.width = width || image.naturalWidth;
        item.height = height || image.naturalHeight;

        queue('image', item);
        return self;
      }

      queue('image', item, false);
      var reference = (self.paper.queue.length - 1),
        currentQueue = config.contexts[this.paper.index].queue[reference];

      image.addEventListener('load', function() {
        if (!currentQueue)
          return false;
        currentQueue.params.width = (item.width || image.naturalWidth);
        currentQueue.params.height = (item.height || image.naturalHeight);
        currentQueue.loaded = true;
      });

      image.addEventListener('error', function() {
        if (!currentQueue)
          return false;
        currentQueue.failed = true;
      });

      return self;
    };

    function LineShape(params) {
      var def = config.defaults.line,
          style = params.style,
          pointA = params.pointA,
          pointB = params.pointB;

      this.paper.ctx.beginPath();
      this.paper.ctx.setLineDash(style.borderStyle);
      this.paper.ctx.moveTo((pointA.x || 0), (pointA.y || 0));
      this.paper.ctx.lineTo((pointB.x || 0), (pointB.y || 0));

      this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
      this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
      this.paper.ctx.stroke();
      this.paper.ctx.setLineDash([]);
      this.paper.ctx.closePath();
    }

    Screen.prototype.line = LineShape;

    Origami.line = function(pointA, pointB, style) {
      style = normalizeStyle(style);

      queue('line', {
        pointA: pointA,
        pointB: pointB,
        style: style
      });
      return this;
    };

    function PolygonShape(params) {
      var args = params.args,
        style = params.style,
        def = config.defaults.polygon;

      this.paper.ctx.beginPath();
      this.paper.ctx.setLineDash(style.borderStyle);
      this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
      this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
      this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;

      for (var p = 0; p < args.length; p++) {
        if (!args[p].x)
          continue;

        if (p)
          this.paper.ctx.lineTo(args[p].x, args[p].y);
        else
          this.paper.ctx.moveTo(args[p].x, args[p].y);
      }

      this.paper.ctx.fill();
      this.paper.ctx.stroke();
      this.paper.ctx.setLineDash([]);
      this.paper.ctx.closePath();
    }

    Screen.prototype.polygon = PolygonShape;

    Origami.polygon = function() {
      var args = [].slice.call(arguments),
        settedArgs = argsByRules(args);

      queue('polygon', {
        style: settedArgs.style,
        args: args
      });
      return this;
    };

    function RectShape(params) {
      var def = config.defaults.rect,
        style = params.style,
        args = params.args;

      this.paper.ctx.beginPath();
      this.paper.ctx.setLineDash(style.borderStyle);
      this.paper.ctx.fillStyle = (style.background) ? style.background : def.background;
      this.paper.ctx.fillRect(args.x, args.y, args.width, (args.height || args.width));

      this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
      this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
      this.paper.ctx.strokeRect(args.x, args.y, args.width, (args.height || args.width));
      this.paper.ctx.setLineDash([]);
      this.paper.ctx.closePath();
    }

    Screen.prototype.rect = RectShape;

    Origami.rect = function() {
      var args = [].slice.call(arguments);
      args = argsByRules(args);

      queue('rect', {
        style: args.style,
        args: args
      });
      return this;
    };

    Origami.border = function() {
      var args = [].slice.call(arguments);
      args = argsByRules(args);

      queue('rect', {
        style: args.style,
        args: {
          x: 0,
          y: 0,
          width: this.paper.width,
          height: this.paper.height
        }
      });
      return this;
    };

    function CSSShape(style) {
      var self = this,
        style = config.virtualStyles[style];

      if (!style)
        return self;

      // TODO: Draw in all canvas
      var data = '<svg xmlns="http://www.w3.org/2000/svg" width="' +
        self.paper.width + 'px" height="' + self.paper.height + 'px">' +
        '<foreignObject width="100%" height="100%">' +
        '<div xmlns="http://www.w3.org/1999/xhtml">' +
        '<div style="' + style.cssText + '"></div>' +
        '</div></foreignObject>' +
        '</svg>';

      var DOMURL = window.URL || window.webkitURL || window,
        img = new Image(),
        svg = new Blob([data], {
          type: 'image/svg+xml;charset=utf-8'
        });

      var url = DOMURL.createObjectURL(svg);
      img.src = url;

      img.addEventListener('load', function() {
        self.paper.ctx.beginPath();
        self.paper.ctx.drawImage(img, 0, 0);
        DOMURL.revokeObjectURL(url);
        self.paper.ctx.closePath();
      });

      return self;
    }

    Screen.prototype.CSSShape = CSSShape;

    Origami.shape = function(style) {
      queue('CSSShape', style);
      return this;
    };

    function SpriteShape(params) {
      var properties = params.properties,
        dw = params.width / properties.frames;

      drawSprite.call(this, {
        image: params.image,
        posX: 0,
        posY: 0,
        frame: properties.frames,
        loop: properties.loop,
        width: dw,
        widthTotal: params.width,
        height: params.height,
        dx: params.x,
        dy: params.y,
        speed: properties.speed,
        animation: null
      });
    }

    function drawSprite(sprite) {
      var self = this;

      if (sprite.posX === sprite.widthTotal) {
        if (sprite.loop === false) {
          window.cancelAnimationFrame(sprite.animation);
          return;
        }
        sprite.posX = 0;
      }

      self.paper.ctx.clearRect(sprite.dx, sprite.dy, sprite.width, sprite.height);

      self.paper.ctx.beginPath();
      self.paper.ctx.drawImage(sprite.image, sprite.posX, sprite.posY,
        sprite.width, sprite.height, sprite.dx, sprite.dy,
        sprite.width, sprite.height);
      self.paper.ctx.closePath();

      sprite.posX = sprite.posX + sprite.width;

      setTimeout(function() {
        sprite.animation = window.requestAnimationFrame(drawSprite.bind(self, sprite));
      }, sprite.speed);
    }

    Screen.prototype.sprite = SpriteShape;

    Origami.sprite = function(x, y, properties) {
      var self = this;

      if (!properties || !properties.src)
        return this;

      var image = new Image(),
        frames = (properties.frames || 0),
        loop = (properties.loop || true),
        speed = (properties.speed || 10);

      image.src = properties.src;

      var item = {
        x: x,
        y: y,
        image: image,
        properties: properties,
        width: 0,
        height: 0
      };

      if (image.complete) {
        item.width = image.naturalWidth;
        item.height = image.naturalHeight;
        queue('sprite', item);
        return self;
      }

      queue('sprite', item, false);
      var reference = (self.paper.queue.length - 1),
        currentQueue = config.contexts[this.paper.index].queue[reference];

      image.addEventListener('load', function() {
        if (!currentQueue)
          return false;
        currentQueue.params.width = image.naturalWidth;
        currentQueue.params.height = image.naturalHeight;
        currentQueue.loaded = true;
      });

      image.addEventListener('error', function() {
        if (!currentQueue)
          return false;
        currentQueue.failed = true;
      });

      return this;
    };

    function TextShape(params) {
      var def = config.defaults.text,
        text = params.text,
        x = params.x,
        y = params.y,
        style = params.style;

      this.paper.ctx.beginPath();
      this.paper.ctx.setLineDash(style.borderStyle);
      this.paper.ctx.lineWidth = (style.borderSize) ? style.borderSize : def.lineWidth;
      this.paper.ctx.strokeStyle = (style.borderColor) ? style.borderColor : def.strokeStyle;
      this.paper.ctx.font = (style.font || def.font);
      this.paper.ctx.fillStyle = (style.color || def.color);
      this.paper.ctx.textAlign = (style.align || def.align);
      this.paper.ctx.fillText(text, x, y);
      this.paper.ctx.strokeText(text, x, y);
      this.paper.ctx.fill();
      this.paper.ctx.stroke();
      this.paper.ctx.setLineDash([]);
      this.paper.ctx.closePath();
    }

    Screen.prototype.text = TextShape;

    Origami.text = function(text, x, y, style) {
      style = normalizeStyle(style);

      var item = {
        text: text,
        x: x,
        y: y,
        style: style
      };

      if ((typeof(item.x) === 'string') && (typeof(item.y) === 'string'))
        item = smartCoordinates(item);

      queue('text', item);
      return this;
    };

    function ChartLine(config) {
      var ctx = this.paper.ctx,
        width = this.paper.width,
        height = this.paper.height;

      var line = getBorderStyleObject(config.line || "1px solid #000");
      var lineVariance = 2;

      var xPadding = 40;
      var yPadding = 40;
      var data = [];

      var gridLines = {
        vertical: true,
        horizontal: true
      };

      if (config.gridLines) {
        if (config.gridLines.vertical === false)
          gridLines.vertical = false;

        if (config.gridLines.horizontal === false)
          gridLines.horizontal = false;
      }

      for (var i = 0; i < config.labels.length; i++) {
        data.push({
          X: config.labels[i],
          Y: config.data[i]
        });
      }

      function getMaxY() {
        var max = 0;

        for (var i = 0; i < data.length; i++) {
          if (data[i].Y > max) {
            max = data[i].Y;
          }
        }

        max += 10 - max % 10;
        return max;
      }

      function getXPixel(val) {
        return ((width - xPadding) / data.length) * val + xPadding;
      }

      function getYPixel(val) {
        return height - (((height - yPadding) / getMaxY()) * val) - yPadding;
      }

      ctx.lineWidth = 0.8;
      ctx.strokeStyle = '#999';
      ctx.font = 'normal 12px Helvetica';
      ctx.fillStyle = '#5e5e5e';
      ctx.textAlign = "center";

      ctx.beginPath();
      ctx.moveTo(xPadding, yPadding / lineVariance);
      ctx.lineTo(xPadding, height - yPadding);
      ctx.lineTo(width - (xPadding / lineVariance), height - yPadding);
      ctx.stroke();

      // Data
      ctx.textAlign = "right";
      ctx.textBaseline = "middle";
      for (var i = 0; i < getMaxY(); i += 10) {
        if (gridLines.horizontal) {
          ctx.beginPath();
          ctx.lineWidth = 0.8;
          ctx.strokeStyle = '#e7e7e7';
          ctx.moveTo(xPadding - 5, getYPixel(i));
          ctx.lineTo(width - (xPadding / lineVariance), getYPixel(i));
          ctx.stroke();
        }

        ctx.fillText(i, xPadding - 10, getYPixel(i));
      }

      // Labels
      ctx.textAlign = "left";
      for (var i = 0; i < data.length; i++) {
        if (gridLines.vertical) {
          ctx.beginPath();
          ctx.lineWidth = 0.8;
          ctx.strokeStyle = '#e7e7e7';
          ctx.moveTo(getXPixel(i), height - yPadding + 10);
          ctx.lineTo(getXPixel(i), yPadding / lineVariance);
          ctx.stroke();
        }

        ctx.fillText(data[i].X, getXPixel(i), height - yPadding + 20);
      }

      ctx.beginPath();
      ctx.lineWidth = line.borderSize;
      ctx.setLineDash(line.borderStyle);
      ctx.strokeStyle = line.borderColor;
      ctx.moveTo(getXPixel(0), getYPixel(data[0].Y));

      for (var i = 1; i < data.length; i++) {
        ctx.lineTo(getXPixel(i), getYPixel(data[i].Y));
      }
      ctx.stroke();
      ctx.setLineDash([]);

      if (config.points) {
        ctx.fillStyle = (config.pointsColor) ? config.pointsColor : 'rgb(75,75,75)';
        for (var i = 0; i < data.length; i++) {
          ctx.beginPath();
          ctx.arc(getXPixel(i), getYPixel(data[i].Y), 3, 0, Math.PI * 2, true);
          ctx.fill();
        }
      }
    }

    Screen.prototype.chartLine = ChartLine;

    Origami.chartLine = function(config) {
      queue('chartLine', config);
      return this;
    };
    // Resource.js

    Origami.background = function(color) {
      queue('background', {
        color: color
      });
      return this;
    };

    Origami.restore = function() {
      queue('restore');
      return this;
    };

    Origami.save = function() {
      queue('save');
      return this;
    };

    Origami.composition = function(globalComposite) {
      queue('composition', {
        globalComposite: globalComposite
      });
      return this;
    };

    Origami.translate = function(x, y) {
      if (x === undefined || x === null) {
        x = 'reset';
      }

      if (typeof(x) === 'string') {
        if (x === 'center') {
          x = context.width / 2;
          y = context.height / 2;
        }
        if (x === 'reset') {
          x = -context.width / 2;
          y = -context.height / 2;
        }
      }

      queue('translate', {
        x: x,
        y: y
      });
      return this;
    };

    Origami.rotate = function(degrees) {
      if (typeof(degrees) === 'undefined')
        degrees = 'slow';

      if (typeof(degrees) === 'string') {
        // Slow
        if (degrees === 'slow')
          degrees = ((2 * Math.PI) / 60) * new Date().getSeconds() +
          ((2 * Math.PI) / 60000) * new Date().getMilliseconds();

        // Normal
        else if (degrees === 'normal')
          degrees = ((2 * Math.PI) / 30) * new Date().getSeconds() +
          ((2 * Math.PI) / 30000) * new Date().getMilliseconds();

        // Fast
        else if (degrees === 'fast')
          degrees = ((2 * Math.PI) / 6) * new Date().getSeconds() +
          ((2 * Math.PI) / 6000) * new Date().getMilliseconds();
      }

      queue('rotate', {
        degrees: degrees
      });
      return this;
    };

    Origami.stopRender = function() {
      window.cancelAnimationFrame(this.paper.frame);
      this.paper.frame = false;
    };

    Origami.play = function() {
      this.paper.frame = 1;
      return this;
    };

    Origami.startRender = function(fn) {
      var self = this;
      if (self.paper.frame === false)
        return;

      self.draw(function() {
        self.paper.frame = window.requestAnimationFrame(fn.bind(this));
      });
    };

    Origami.scale = function(width, height) {
      queue('scale', {
        width: width,
        height: height
      });
      return this;
    };

    Origami.flip = function(type) {
      queue('flip', {
        type: type
      });
      return this;
    };

    Origami.flipEnd = function() {
      queue('flipEnd');
      return this;
    };

    Origami.clear = function() {
      queue('clear');
      return this;
    };

    Origami.on = function(ev, fn) {
      this.paper.element.addEventListener(ev, fn);
      return this;
    };

    var factory = extend(Origami.init.bind(this), Origami);

    // For consistency with CommonJS environments' exports
    if (  module && module.exports ){
        module.exports = factory;
    }

    // For CommonJS with exports, but without module.exports, like Rhino
    else if (  exports ) {
        exports.origami = factory;
    }

    // For browser, export only select globals
    else if ( typeof window === "object" ) {
        window.origami = extend(Origami.init.bind(Origami), Origami);
    }

    // Get a reference to the global object
    }( (function() {
        return this;
    })() ));
    });
    var origami_2 = origami_1.origami;

    var drawRoundLayers = (functionContext) => {
        let { data, options, ctx, h, w, Helper, canvasId } = functionContext;
        let helper = new Helper(ctx);

        let origamiContext = {};
        let origami = origami_1.bind(origamiContext);

        origami(ctx)
            .rect(10, 10, 40, 40)
            .draw();


    };

    //options:type,colors,stroke
    function visualize(data, canvasId, options = {}, frame) {
        //make a clone of options
        options = { ...options };
        //options
        if (!options.stroke) options.stroke = 1;
        if (!options.colors) options.colors = ["#d92027", "#ff9234", "#ffcd3c", "#35d0ba"];


        let canvas = document.getElementById(canvasId);

        if (!canvas) return;

        let ctx = canvas.getContext("2d");
        let h = canvas.height;
        let w = canvas.width;



        ctx.strokeStyle = options.colors[0];
        ctx.lineWidth = options.stroke;

        let typeMap = {
            "bars": drawBars,
            "bars blocks": drawBarsBlocks,
            "big bars": drawBigBars,
            "cubes": drawCubes,
            "dualbars": drawDualbars,
            "dualbars blocks": drawDualbarsBlocks,
            "fireworks": drawFireworks,
            "flower": drawFlower,
            "flower blocks": drawFlowerBlocks,
            "orbs": drawOrbs,
            "ring": drawRing,
            "rings": drawRings,
            "round layers": drawRoundLayers,
            "round wave": drawRoundWave,
            "shine": drawShine,
            "shine rings": drawShineRings,
            "shockwave": drawShockwave,
            "star": drawStar,
            "static": drawStatic,
            "stitches": drawStitches,
            "wave": drawWave,
            "web": drawWeb
        };

        let frameRateMap = {
            "bars": 1,
            "bars blocks": 1,
            "big bars": 1,
            "cubes": 1,
            "dualbars": 1,
            "dualbars blocks": 1,
            "fireworks": 1,
            "flower": 1,
            "flower blocks": 1,
            "ring": 1,
            "rings": 1,
            "round layers": 1,
            "round wave": 1,
            "orbs": 1,
            "shine": 1,
            "shine rings": 1,
            "shockwave": 1,
            "star": 1,
            "static": 1,
            "stitches": 1,
            "wave": 1,
            "web": 1
        };

        const functionContext = {
            data, options, ctx, h, w, Helper: this.Helper, canvasId
        };

        if (typeof options.type == "string") options.type = [options.type];

        options.type.forEach(type => {
            //abide by the frame rate
            if (frame % frameRateMap[type] === 0) {
                //clear canvas
                ctx.clearRect(0, 0, w, h);
                ctx.beginPath();

                typeMap[type](functionContext);
            }
        });

    }

    function Helper(ctx) {
        this.ctx = ctx;
        this.mainColor = "black";
    }

    Helper.prototype = {
        __toRadians__(degree) {
            return (degree * Math.PI) / 180;
        },
        __rotatePoint__([pointX, pointY], [originX, originY], degree) {
            //clockwise
            let angle = this.__toRadians__(degree);
            let rotatedX = Math.cos(angle) * (pointX - originX) - Math.sin(angle) * (pointY - originY) + originX;
            let rotatedY = Math.sin(angle) * (pointX - originX) + Math.cos(angle) * (pointY - originY) + originY;

            return [rotatedX, rotatedY]
        },
        mutateData(data, type, extra = null) {
            if (type === "mirror") {
                let rtn = [];

                for (let i = 0; i < data.length; i += 2) {
                    rtn.push(data[i]);
                }

                rtn = [...rtn, ...rtn.reverse()];
                return rtn
            }

            if (type === "shrink") {
                //resize array by % of current array 
                if (extra < 1) {
                    extra = data.length * extra;
                }

                let rtn = [];
                let splitAt = Math.floor(data.length / extra);

                for (let i = 1; i <= extra; i++) {
                    let arraySection = data.slice(i * splitAt, (i * splitAt) + splitAt);
                    let middle = arraySection[Math.floor(arraySection.length / 2)];
                    rtn.push(middle);
                }

                return rtn
            }

            if (type === "split") {
                let size = Math.floor(data.length / extra);
                let rtn = [];
                let temp = [];

                let track = 0;
                for (let i = 0; i <= size * extra; i++) {
                    if (track === size) {
                        rtn.push(temp);
                        temp = [];
                        track = 0;
                    }

                    temp.push(data[i]);
                    track++;
                }

                return rtn
            }

            if (type === "scale") {
                let scalePercent = extra / 255;
                if (extra <= 3 && extra >= 0) scalePercent = extra;
                let rtn = data.map(value => value * scalePercent);
                return rtn
            }

            if (type === "organize") {
                let rtn = {};
                rtn.base = data.slice(60, 120);
                rtn.vocals = data.slice(120, 255);
                rtn.mids = data.slice(255, 2000);
                return rtn
            }

            if (type === "reverb") {
                let rtn = [];
                data.forEach((val, i) => {
                    rtn.push(val - (data[i + 1] || 0));
                });
                return rtn
            }

            if (type === "amp") {
                let rtn = [];
                data.forEach(val => {
                    rtn.push(val * (extra + 1));
                });
                return rtn
            }

            if (type === "min") {
                let rtn = [];
                data.forEach(value => {
                    if (value < extra) value = extra;
                    rtn.push(value);
                });
                return rtn
            }
        },
        getPoints(shape, size, [originX, originY], pointCount, endPoints, options = {}) {
            let { offset = 0, rotate = 0, customOrigin = [] } = options;
            let rtn = {
                start: [],
                end: []
            };

            if (shape === "circle") {

                let degreePerPoint = 360 / pointCount;
                let radianPerPoint = this.__toRadians__(degreePerPoint);
                let radius = size / 2;

                for (let i = 1; i <= pointCount; i++) {
                    let currentRadian = radianPerPoint * i;
                    let currentEndPoint = endPoints[i - 1];
                    let pointOffset = endPoints[i - 1] * (offset / 100);

                    let x = originX + (radius - pointOffset) * Math.cos(currentRadian);
                    let y = originY + (radius - pointOffset) * Math.sin(currentRadian);
                    let point1 = this.__rotatePoint__([x, y], [originX, originY], rotate);

                    rtn.start.push(point1);

                    x = originX + ((radius - pointOffset) + currentEndPoint) * Math.cos(currentRadian);
                    y = originY + ((radius - pointOffset) + currentEndPoint) * Math.sin(currentRadian);
                    let point2 = this.__rotatePoint__([x, y], [originX, originY], rotate);

                    rtn.end.push(point2);

                }

                return rtn
            }

            if (shape === "line") {
                let increment = size / pointCount;

                originX = customOrigin[0] || originX;
                originY = customOrigin[1] || originY;

                for (let i = 0; i <= pointCount; i++) {
                    let degree = rotate;
                    let pointOffset = endPoints[i] * (offset / 100);

                    let startingPoint = this.__rotatePoint__([originX + (i * increment), originY - pointOffset],
                        [originX, originY], degree);
                    rtn.start.push(startingPoint);

                    let endingPoint = this.__rotatePoint__([originX + (i * increment), (originY + endPoints[i]) - pointOffset],
                        [originX, originY], degree);
                    rtn.end.push(endingPoint);
                }

                return rtn

            }

        },
        drawCircle([x, y], diameter, options = {}) {
            let { color, lineColor = this.ctx.strokeStyle } = options;

            this.ctx.beginPath();
            this.ctx.arc(x, y, diameter / 2, 0, 2 * Math.PI);
            this.ctx.strokeStyle = lineColor;
            this.ctx.stroke();
            this.ctx.fillStyle = color;
            if (color) this.ctx.fill();
        },
        drawOval([x, y], height, width, options = {}) {
            let { rotation = 0, color, lineColor = this.ctx.strokeStyle } = options;
            if (rotation) rotation = this.__toRadians__(rotation);

            this.ctx.beginPath();
            this.ctx.ellipse(x, y, width, height, rotation, 0, 2 * Math.PI);
            this.ctx.strokeStyle = lineColor;
            this.ctx.stroke();
            this.ctx.fillStyle = color;
            if (color) this.ctx.fill();
        },
        drawSquare([x, y], diameter, options = {}) {
            this.drawRectangle([x, y], diameter, diameter, options);
        },
        drawRectangle([x, y], height, width, options = {}) {
            let { color, lineColor = this.ctx.strokeStyle, radius = 0, rotate = 0 } = options;

            // if (width < 2 * radius) radius = width / 2;
            // if (height < 2 * radius) radius = height / 2;

            this.ctx.beginPath();
            this.ctx.moveTo(x + radius, y);
            let p1 = this.__rotatePoint__([x + width, y], [x, y], rotate);
            let p2 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
            this.ctx.arcTo(p1[0], p1[1], p2[0], p2[1], radius);

            let p3 = this.__rotatePoint__([x + width, y + height], [x, y], rotate);
            let p4 = this.__rotatePoint__([x, y + height], [x, y], rotate);
            this.ctx.arcTo(p3[0], p3[1], p4[0], p4[1], radius);

            let p5 = this.__rotatePoint__([x, y + height], [x, y], rotate);
            let p6 = this.__rotatePoint__([x, y], [x, y], rotate);
            this.ctx.arcTo(p5[0], p5[1], p6[0], p6[1], radius);

            let p7 = this.__rotatePoint__([x, y], [x, y], rotate);
            let p8 = this.__rotatePoint__([x + width, y], [x, y], rotate);
            this.ctx.arcTo(p7[0], p7[1], p8[0], p8[1], radius);
            this.ctx.closePath();

            this.ctx.strokeStyle = lineColor;
            this.ctx.stroke();
            this.ctx.fillStyle = color;
            if (color) this.ctx.fill();

        },
        drawLine([fromX, fromY], [toX, toY], options = {}) {
            let { lineColor = this.ctx.strokeStyle } = options;

            this.ctx.beginPath();
            this.ctx.moveTo(fromX, fromY);
            this.ctx.lineTo(toX, toY);
            this.ctx.strokeStyle = lineColor;
            this.ctx.stroke();
        },
        drawPolygon(points, options = {}) {
            let { color, lineColor = this.ctx.strokeStyle, radius = 0, close = false } = options;

            function getRoundedPoint(x1, y1, x2, y2, radius, first) {
                let total = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
                let idx = first ? radius / total : (total - radius) / total;

                return [x1 + (idx * (x2 - x1)), y1 + (idx * (y2 - y1))];
            }

            function getRoundedPoints(pts, radius) {
                let len = pts.length;
                let res = new Array(len);

                for (let i2 = 0; i2 < len; i2++) {
                    let i1 = i2 - 1;
                    let i3 = i2 + 1;

                    if (i1 < 0) i1 = len - 1;
                    if (i3 == len) i3 = 0;

                    let p1 = pts[i1];
                    let p2 = pts[i2];
                    let p3 = pts[i3];

                    let prevPt = getRoundedPoint(p1[0], p1[1], p2[0], p2[1], radius, false);
                    let nextPt = getRoundedPoint(p2[0], p2[1], p3[0], p3[1], radius, true);
                    res[i2] = [prevPt[0], prevPt[1], p2[0], p2[1], nextPt[0], nextPt[1]];
                }
                return res;
            }
            if (radius > 0) {
                points = getRoundedPoints(points, radius);
            }

            let i, pt, len = points.length;
            for (i = 0; i < len; i++) {
                pt = points[i];
                if (i == 0) {
                    this.ctx.beginPath();
                    this.ctx.moveTo(pt[0], pt[1]);
                } else {
                    this.ctx.lineTo(pt[0], pt[1]);
                }
                if (radius > 0) {
                    this.ctx.quadraticCurveTo(pt[2], pt[3], pt[4], pt[5]);
                }
            }

            if (close) this.ctx.closePath();
            this.ctx.strokeStyle = lineColor;
            this.ctx.stroke();

            this.ctx.fillStyle = color;
            if (color) this.ctx.fill();
        }

    };

    function Wave() {
        this.current_stream = {};
        this.sources = {};
        this.onFileLoad = null;
        this.activeElements = {};
        this.activated = false;

        window.AudioContext = window.AudioContext || window.webkitAudioContext;
    }

    Wave.prototype = {
        fromElement,
        fromFile,
        ...fromStream$1,
        visualize,
        Helper
    };

    return Wave;

}());
[ CLOSE ]