diff options
Diffstat (limited to 'site/app')
934 files changed, 34448 insertions, 0 deletions
diff --git a/site/app/base/analyser.js b/site/app/base/analyser.js new file mode 100644 index 0000000..ac55d42 --- /dev/null +++ b/site/app/base/analyser.js @@ -0,0 +1,97 @@ +var Analyser = function(type, twist, elContainer, csApp) {
+ var self = this;
+ var scopeNode = twirl.audioContext.createAnalyser();
+ var node;
+ var elCanvas = $("<canvas />").css({
+ position: "absolute",
+ width: "100%",
+ height: "100%",
+ top: "0px",
+ left: "0px"
+ }).addClass("twist_scope").appendTo(elContainer);
+ var context = elCanvas[0].getContext("2d");
+ var playing = false;
+
+ this.remove = function() {
+ type = null;
+ elContainer.remove();
+ };
+
+ function frequency() {
+ if (type != 0 || !playing) return;
+ let style = getComputedStyle(document.body);
+ let width = elCanvas[0].width = elContainer.width();
+ let height = elCanvas[0].height = elContainer.height();
+
+ let freqData = new Uint8Array(scopeNode.frequencyBinCount);
+ let scaling = height / 256;
+ scopeNode.getByteFrequencyData(freqData);
+ context.fillStyle = style.getPropertyValue("--waveformBgColor");
+ context.fillRect(0, 0, width, height);
+ context.lineWidth = 2;
+ context.strokeStyle = style.getPropertyValue("--waveformFgColor");
+ context.beginPath();
+
+ for (var x = 0; x < width; x++) {
+ context.lineTo(x, height - freqData[x] * scaling);
+ }
+ context.stroke();
+ requestAnimationFrame(frequency);
+ }
+
+ function oscilloscope() {
+ if (type != 1 || !playing) return;
+ let style = getComputedStyle(document.body);
+ let width = elCanvas[0].width = elContainer.width();
+ let height = elCanvas[0].height = elContainer.height();
+
+ let timeData = new Uint8Array(scopeNode.frequencyBinCount);
+ let scaling = height / 256;
+ let risingEdge = 0;
+ let edgeThreshold = 5;
+ scopeNode.getByteTimeDomainData(timeData);
+
+ context.fillStyle = style.getPropertyValue("--waveformBgColor");
+ context.fillRect(0, 0, width, height);
+ context.lineWidth = 2;
+ context.strokeStyle = style.getPropertyValue("--waveformFgColor");
+ context.beginPath();
+
+ while (timeData[risingEdge++] - 128 > 0 && risingEdge <= width);
+ if (risingEdge >= width) risingEdge = 0;
+
+ while (timeData[risingEdge++] - 128 < edgeThreshold && risingEdge <= width);
+ if (risingEdge >= width) risingEdge = 0;
+
+ for (var x = risingEdge; x < timeData.length && x - risingEdge < width; x++) {
+ context.lineTo(x - risingEdge, height - timeData[x] * scaling);
+ }
+ context.stroke();
+ requestAnimationFrame(oscilloscope);
+ }
+
+ this.setPlaying = function(state) {
+ playing = state;
+ if (playing) {
+ if (type == 0) {
+ frequency();
+ } else if (type == 1) {
+ oscilloscope();
+ }
+ }
+ };
+
+ this.setType = function(v) {
+ type = v;
+ self.setPlaying(playing);
+ };
+
+ async function boot() {
+ node = await csApp.getNode();
+ node.connect(scopeNode);
+ if (twist.isPlaying()) {
+ self.setPlaying(true);
+ }
+ }
+ boot();
+};
\ No newline at end of file diff --git a/site/app/base/base.js b/site/app/base/base.js new file mode 100644 index 0000000..8bf12f2 --- /dev/null +++ b/site/app/base/base.js @@ -0,0 +1,512 @@ +var CSApplication = function(appOptions) {
+ var self = this;
+ var version = 1.0;
+ var debug = window.location.protocol.startsWith("file");
+ var baseUrl;
+ if (debug) {
+ baseUrl = "https://apps.csound.1bpm.net";
+ } else {
+ baseUrl = window.location.origin;
+ }
+ var cbid = 0;
+ var callbacks = {};
+ var appPath;
+ var udoReplacements = {
+ "/interop.udo": "/interop.web.udo",
+ "/sequencing_melodic_persistence.udo": "/sequencing_melodic_persistence.web.udo"
+ };
+ var defaultStorage = {version: version};
+ var storage = localStorage.getItem("csound");
+ if (storage) {
+ storage = JSON.parse(storage);
+ if (!storage.version || storage.version != version) {
+ storage = defaultStorage;
+ }
+ } else {
+ storage = defaultStorage;
+ }
+
+ function saveStorage() {
+ localStorage.setItem("csound", JSON.stringify(storage));
+ }
+
+
+ const defaultOptions = {
+ csdUrl: null,
+ csOptions: null,
+ trackMouse: false,
+ trackTouch: false,
+ trackClick: false,
+ trackMouseSpeed: false,
+ trackTouchSpeed: false,
+ keyDownScore: null, // score line to insert with code as p4, or function passed event to return score line
+ keyUpScore: null,
+ onPlay: null,
+ onStop: null,
+ ioReceivers: null,
+ files: null
+ };
+ let csound = null;
+
+ function basename(path) {
+ return path.split("/").reverse()[0];
+ }
+
+ this.getCsound = function() {
+ return csound;
+ }
+
+ if (!appOptions) {
+ appOptions = defaultOptions;
+ } else {
+ for (var key in defaultOptions) {
+ if (!appOptions.hasOwnProperty(key)) {
+ appOptions[key] = defaultOptions[key];
+ }
+ }
+ }
+
+ async function copyDataToLocal(arrayBuffer, name) {
+ if (!csound) return;
+ const buffer = new Uint8Array(arrayBuffer);
+ await csound.fs.writeFile(name, buffer);
+ return Promise.resolve();
+ }
+
+ async function copyUrlToLocal(url, name) {
+ if (!csound) return;
+ const response = await fetch(url);
+ const arrayBuffer = await response.arrayBuffer();
+ await copyDataToLocal(arrayBuffer, name);
+ return Promise.resolve();
+ }
+
+ this.loadUrl = function(url, a2, a3) {
+ var name;
+ var func;
+ if (typeof(a2) == "function") {
+ name = basename(url);
+ func = a2;
+ } else {
+ name = a2;
+ func = a3;
+ }
+ copyUrlToLocal(url, name).then(() => {
+ if (func) func(name);
+ });
+ };
+
+ this.loadBuffer = function(buffer, a2, a3) {
+ var name;
+ var func;
+ if (typeof(a2) == "function") {
+ name = basename(url);
+ func = a2;
+ } else {
+ name = a2;
+ func = a3;
+ }
+ copyDataToLocal(buffer, name).then(() => {
+ if (func) func(name);
+ });
+ }
+
+ function runCallback(data) {
+ if (!callbacks[data.cbid]) {
+ return;
+ }
+ callbacks[data.cbid].func(data);
+ if (callbacks.hasOwnProperty(data.cbid) && !callbacks[data.cbid].persist) {
+ self.removeCallback(data.cbid);
+ }
+ }
+
+ this.createCallback = function(func, persist) {
+ thisCbid = cbid;
+ callbacks[thisCbid] = {func: func, persist: persist};
+ if (cbid > 999999) {
+ cbid = 0;
+ } else {
+ cbid ++;
+ }
+ return thisCbid;
+ };
+
+ this.removeCallback = function(cbid) {
+ delete callbacks[cbid];
+ };
+
+ this.enableAudioInput = async function() {
+ if (!csound) return;
+ return (await csound.enableAudioInput());
+ };
+
+ this.unlinkFile = function(path) {
+ if (!csound) return;
+ csound.fs.unlink(path);
+ };
+
+ this.readFile = async function(path) {
+ if (!csound) return;
+ return (await csound.fs.readFile(path));
+ };
+
+ this.writeFile = async function(path, buffer) {
+ return (await csound.fs.writeFile(path, buffer));
+ };
+
+ this.setControlChannel = function(name, value) {
+ if (!csound) return;
+ csound.setControlChannel(name, value);
+ };
+
+ this.getControlChannel = async function(name) {
+ if (!csound) return;
+ return await csound.getControlChannel(name);
+ };
+
+ this.setStringChannel = function(name, value) {
+ if (!csound) return;
+ csound.setStringChannel(name, value);
+ };
+
+ this.getStringChannel = function(name) {
+ if (!csound) return;
+ return csound.getStringChannel(name);
+ };
+
+ this.getTable = function(tableNumber) {
+ if (!csound) return;
+ return csound.getTable(tableNumber);
+ };
+
+ this.compileOrc = async function(orc) {
+ if (!csound) return;
+ return await csound.compileOrc(orc);
+ }
+
+ function handleMessage(message) {
+ if (debug) console.log(message);
+ if (message.startsWith("callback ")) {
+ runCallback(JSON.parse(message.substr(9)));
+ } else if (appOptions.errorHandler && (message.startsWith("error: ") ||
+ message.startsWith("INIT ERROR ") ||
+ message.startsWith("PERF ERROR ") ||
+ message.startsWith("perf_error: "))) {
+ appOptions.errorHandler(message);
+ } else if (appOptions.ioReceivers) {
+ for (var k in appOptions.ioReceivers) {
+ if (message.startsWith(k + " ")) {
+ appOptions.ioReceivers[k](message.substr(k.length + 1));
+ return;
+ }
+ }
+ }
+ };
+
+ var urlExistsChecked = {};
+ function urlExists(url) {
+ return new Promise((resolve, reject) => {
+ if (urlExistsChecked.hasOwnProperty(url)) {
+ resolve(urlExistsChecked[url]);
+ } else {
+ fetch(url, {
+ method: "HEAD"
+ }).then(response => {
+ var exists = (response.status.toString()[0] === "2");
+ urlExistsChecked[url] = exists;
+ resolve(exists);
+ }).catch(error => {
+ reject(false);
+ });
+ }
+ });
+ }
+
+
+ function dirName(path) {
+ return path.substring(0, path.lastIndexOf("/"));
+ }
+
+ async function loadFiles(files) {
+ for (var i = 0; i < files.length; i++) {
+ await copyUrlToLocal(files[i].url, files[i].name);
+ }
+ };
+
+
+ function urlInFiles(url, files) {
+ for (var x in files) {
+ if (url == files[x].url) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ async function scanUdoUsage(url, files, soundCollections) {
+ const req = await fetch(url);
+ const text = await req.text();
+ var soundCollections;
+ var match;
+ var doSaveStorage = false;
+ if (!storage.knownUdoPaths) storage.knownUdoPaths = {};
+ var re = /sounddb_getcollection(|id) "(.*)"|#include "(.*)"/g;
+ do {
+ match = re.exec(text);
+ if (match) {
+ if (match[3] && !match[3].endsWith("sounddb.udo")) {
+ var udoPath;
+ var dopush = false;
+ if (udoReplacements.hasOwnProperty(match[3])) {
+ udoPath = baseUrl + "/udo/" + udoReplacements[match[3]];
+ if (!urlInFiles(udoPath)) {
+ dopush = true;
+ }
+ } else {
+ if (Object.keys(storage.knownUdoPaths).includes(match[3])) {
+ udoPath = storage.knownUdoPaths[match[3]];
+ if (!urlInFiles(udoPath, files)) dopush = true;
+ } else {
+ udoPath = baseUrl + ("/udo/" + match[3]).replaceAll("//", "/");
+ if (!urlInFiles(udoPath, files)) {
+ var exists = await urlExists(udoPath);
+ if (!exists) {
+ udoPath = appPath + ("/" + match[3]).replaceAll("//", "/");
+ }
+ storage.knownUdoPaths[match[3]] = udoPath;
+ doSaveStorage = true;
+ dopush = true;
+ }
+ }
+ }
+ if (dopush) {
+ files.push({url: udoPath, name: match[3]});
+ await scanUdoUsage(udoPath, files, soundCollections);
+ }
+ }
+ if (match[2] && !appOptions.manualSoundCollections) {
+ var collections = match[2].split(",");
+ for (var x in collections) {
+ if (!soundCollections.includes(collections[x])) {
+ soundCollections.push(collections[x]);
+ }
+ }
+ }
+ }
+ } while (match);
+
+ if (doSaveStorage) {
+ saveStorage();
+ }
+ }
+
+ this.getNode = async function() {
+ if (!csound) return;
+ return await csound.getNode();
+ }
+
+ this.play = async function(log, audioContext) {
+ if (!csound) {
+ if (log) log("Loading audio engine");
+ var csdBasename = basename(appOptions.csdUrl);
+ appPath = dirName(window.location.href);
+
+ if (csdBasename == appOptions.csdUrl) {
+ appOptions.csdUrl = appPath + "/" + appOptions.csdUrl;
+ }
+ const { Csound } = await import(baseUrl + "/code/csound.js");
+ var invokeOptions = {};
+ if (audioContext) {
+ invokeOptions.audioContext = audioContext;
+ }
+ csound = await Csound(invokeOptions);
+ await csound.setDebug(0);
+ csound.on("message", handleMessage);
+ await csound.setOption("-m0");
+ await csound.setOption("-d");
+ await csound.setOption("--env:INCDIR=/");
+ await csound.setOption("-odac");
+ await csound.setOption("--omacro:WEB=1");
+ if (appOptions.csOptions) {
+ for (var i = 0; i < appOptions.csOptions.length; i++) {
+ await csound.setOption(appOptions.csOptions[i]);
+ }
+ }
+
+ if (log) log("Preparing application code");
+ var files = [{url: appOptions.csdUrl, name: csdBasename}];
+ var soundCollections = [];
+ await scanUdoUsage(appOptions.csdUrl, files, soundCollections);
+
+ if (appOptions.files) {
+ appOptions.files.forEach(function(f){
+ files.push({url: f, name: f});
+ });
+ }
+
+ if (soundCollections.length > 0) {
+ if (log) log("Preparing application sounds");
+ var udoUrl = baseUrl + "/sound/collection_udo.py?collections=" + soundCollections.join(",");
+ files.push({url: udoUrl, name: "sounddb.udo"});
+
+ const response = await fetch(baseUrl + "/sound/map.json");
+ const jdata = await response.json();
+ for (var i = 0; i < soundCollections.length; i++) {
+ var fdata = jdata[soundCollections[i]];
+ for (var j = 0; j < fdata.sounds.length; j++) {
+ var path = fdata.sounds[j].path;
+ if (!urlInFiles(path, files)) {
+ var fileObj = {url: path, name: path};
+ files.push(fileObj);
+ }
+ }
+ }
+ }
+ if (appOptions.onPlay) {
+ csound.on("play", appOptions.onPlay);
+ }
+
+ if (appOptions.onStop) {
+ csound.on("stop", appOptions.onStop);
+ }
+
+ if (log) log("Loading application files");
+ if (appOptions.files) {
+ for (var x in appOptions.files) {
+ files.push({url: appPath + "/" + appOptions.files[x], name: appOptions.files[x]});
+ }
+ }
+ await loadFiles(files);
+ if (log) log("Compiling application");
+ await csound.compileCsd(csdBasename);
+ await csound.start();
+ }
+
+ };
+
+ this.insertScoreAsync = async function(instr, extraArgs, duration, start) {
+ if (!duration) duration = 1;
+ if (!start) start = 0;
+
+ return new Promise((resolve, reject) => {
+ var cbid = self.createCallback(function(ndata){
+ resolve(ndata);
+ });
+ var args = [start, duration, cbid];
+ for (let e of extraArgs) {
+ args.push(e);
+ }
+ self.insertScore(instr, args);
+ });
+ };
+
+ this.insertScore = async function(instr, args) {
+ if (!csound) return;
+ if (!args) args = [0, 1];
+ var scoreline = "i"
+
+ function add(item) {
+ if (isNaN(item)) {
+ scoreline += "\"" + item + "\" ";
+ } else {
+ scoreline += item + " ";
+ }
+ }
+
+ add(instr);
+ if (typeof(args) == "function") {
+ [0, 1, self.createCallback(args)].forEach(add);
+ } else {
+ args.forEach(add);
+ }
+ csound.inputMessage(scoreline);
+ };
+
+ var speedTimestamp = null;
+ var lastPosX = null;
+ var lastPosY = null;
+
+ function setSpeedChannels(x, y) {
+ if (!csound) return;
+ if (speedTimestamp == null) {
+ speedTimestamp = Date.now();
+ lastPosX = x;
+ lastPosY = y;
+ return;
+ }
+ var now = Date.now();
+ var dt = now - speedTimestamp;
+ var dx = event.pageX - lastPosX;
+ var dy = event.pageY - lastPosY;
+ var speedX = Math.round(dx / dt * 100);
+ var speedY = Math.round(dy / dt * 100);
+ speedTimestamp = now;
+ lastPosX = x;
+ lastPosY = y;
+
+ csound.setControlChannel("speedX", speedX);
+ csound.setControlChannel("speedY", speedY);
+ }
+
+ function setPositionChannels(x, y) {
+ if (!csound) return;
+ csound.setControlChannel("mouseX", x / window.innerWidth);
+ csound.setControlChannel("mouseY", y / window.innerHeight);
+ }
+
+
+ if (appOptions.trackMouse || appOptions.trackMouseSpeed) {
+ document.addEventListener("mousemove", function(event) {
+ var timestamp = null;
+ var lastMouseX = null;
+ var lastMouseY = null;
+ if (appOptions.trackMouse) {
+ setPositionChannels(event.pageX, event.pageY);
+ }
+ if (appOptions.trackMouseSpeed) {
+ setSpeedChannels(event.pageX, event.pageY);
+ }
+ });
+ }
+
+ if (appOptions.trackTouch || appOptions.trackTouchSpeed) {
+ document.addEventListener("touchmove", function(event) {
+ var evt = (typeof event.originalEvent === "undefined") ? event : event.originalEvent;
+ var touch = evt.touches[0] || evt.changedTouches[0];
+ if (appOptions.trackTouch) {
+ setPositionChannels(touch.pageX, touch.pageY);
+ }
+ if (appOptions.trackTouchSpeed) {
+ setSpeedChannels(touch.pageX, touch.pageY);
+ }
+ });
+ }
+
+
+ if (appOptions.keyDownScore) {
+ document.addEventListener("keydown", function(event) {
+ if (!csound) return;
+ var scoreline = null;
+ if (typeof appOptions.keyDownScore == "function") {
+ scoreline = appOptions.keyDownScore(event);
+ } else {
+ scoreline = appOptions.keyDownScore + " " + event.code;
+ }
+ csound.inputMessage(scoreline);
+ });
+ }
+
+ if (appOptions.keyUpScore) {
+ document.addEventListener("keydown", function(event) {
+ if (!csound) return;
+ var scoreline = null;
+ if (typeof appOptions.keyUpScore == "function") {
+ scoreline = appOptions.keyUpScore(event);
+ } else {
+ scoreline = appOptions.keyUpScore + " " + event.code;
+ }
+ csound.inputMessage(scoreline);
+ });
+ }
+}
\ No newline at end of file diff --git a/site/app/base/controls.js b/site/app/base/controls.js new file mode 100644 index 0000000..331f88b --- /dev/null +++ b/site/app/base/controls.js @@ -0,0 +1,214 @@ +var Control = function(definition) {
+ var self = this;
+ var state = false;
+ var type;
+ var element;
+ var elTextInput;
+
+
+
+ if (!definition.hasOwnProperty("channel")) {
+ definition.channel = definition.name.toLowerCase();
+ }
+
+ if (!definition.hasOwnProperty("min")) {
+ definition.min = 0;
+ }
+
+ if (!definition.hasOwnProperty("max")) {
+ definition.max = 1;
+ }
+
+ if (!definition.hasOwnProperty("step")) {
+ definition.step = 0.000001;
+ }
+
+ if (!definition.hasOwnProperty("dfault")) {
+ definition.dfault = 0;
+ }
+
+ Object.defineProperty(this, "element", {
+ get: function() {return element;},
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "textInputElement", {
+ get: function() {return elTextInput;},
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "elementRow", {
+ get: function() {
+ var tr = $("<tr />");
+ $("<td />").text(definition.name).appendTo(tr);
+ $("<td />").append(element).appendTo(tr);
+ var tinput = $("<td />").appendTo(tr);
+ if (elTextInput) {
+ tinput.append(elTextInput);
+ }
+ return tr;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "value", {
+ get: function() {
+ var val;
+ if (type == "select") {
+ val = element.val();
+ if (definition.asValue) {
+ val = definition.options[val];
+ }
+ } else if (type == "range") {
+ val = element.val();
+ } else if (type == "checkbox") {
+ val = (element.is(":checked")) ? definition.max : definition.min;
+ } else if (type == "button") {
+ val = 0;
+ } else if (type == "toggle") {
+ val = (state) ? definition.max : definition.min;
+ }
+
+ return val;
+ },
+ set: function(v) {
+ if (type == "checkbox") {
+ element.prop("checked", v);
+ } else {
+ element.val(v);
+ }
+ }
+ });
+
+ async function createControl() {
+ if (definition.options) {
+ type = "select";
+ element = $("<select />");
+ for (var o in definition.options) {
+ $("<option />").val(o).text(definition.options[o]).appendTo(element);
+ }
+ } else if (definition.image) {
+ type = "range";
+ var baseurl = "https://apps.csound.1bpm.net/controls/";
+ var response = await fetch(baseurl + definition.image + ".json");
+ var json = await response.json();
+ var width;
+ var height;
+ if (definition.width) {
+ width = definition.width;
+ } else {
+ if (!json.cellw) json.cellw = 32;
+ width = json.cellw;
+ }
+ if (definition.height) {
+ height = definition.height;
+ } else {
+ height = json.cellh;
+ }
+
+ if (json.ctltype == 0) {
+ element = $("<input />").attr("type", "range").addClass("input-knob").attr("data-diameter", json.cellh).attr("data-src", baseurl + json.fn).attr("data-sprites", json.frames - 1).attr("data-height", height).attr("data-width", width);
+ type = "range";
+ } else if (json.ctltype == 1 || json.ctltype == 3) {
+ element = $("<input />").attr("type", "range").addClass("input-slider").attr("data-height", height).attr("data-src", baseurl + json.fn).attr("data-width", width).attr("data-sprites", json.frames - 1); //.css({width: width, height: height});
+ type = "range";
+ } else if (json.ctltype == 2) {
+ element = $("<input />").attr("type", "checkbox").addClass("input-switch").attr("data-height", height).attr("data-width", width).attr("data-src", baseurl + json.fn);
+ type = "checkbox";
+ }
+ } else {
+ if (!definition.type || definition.type == "range") {
+ type = "range";
+ element = $("<input />").attr("type", "range");
+ } else if (definition.type == "toggle") {
+ type = "toggle";
+ element = $("<button />").text(definition.labelOff);
+ } else if (definition.type == "button") {
+ type = "button";
+ element = $("<button />").text(definition.label);
+ }
+ }
+
+ if (type == "range") {
+ element.attr("min", definition.min).attr("max", definition.max).attr("step", definition.step);
+ if (!definition.noTextInput) {
+ elTextInput = $("<input />").attr("type", "number").attr("min", definition.min).attr("max", definition.max).attr("step", definition.step).change(function() {
+ change($(this).val());
+ });
+ }
+ }
+
+ if (definition.onContextMenu) {
+ element.on("contextmenu", definition.onContextMenu);
+ }
+
+ element.change(function() {
+ if (definition.onChange) {
+ definition.onChange(self.value, self);
+ }
+ if (definition.channel) {
+ sendHost();
+ }
+ });
+
+ element.on("input", function() {
+ if (type == "range") {
+ if (!definition.noSendOnInput) {
+ sendHost();
+ }
+ if (elTextInput) {
+ elTextInput.text(Math.round(self.value * 100) / 100);
+ }
+ }
+ });
+
+ function sendHost() {
+ if (window.app) {
+ app.setControlChannel(definition.channel, self.value);
+ }
+ }
+
+ function change(val) {
+ if (type == "select" || type == "range") {
+ element.val(val);
+ } else if (type == "checkbox") {
+ if (val == 1 || val == true) {
+ element.prop("checked", true);
+ } else {
+ element.prop("checked", false);
+ }
+ } else if (type == "toggle") {
+ if (val == 1 || val == true) {
+ state = true;
+ if (definition.labelOn) {
+ element.text(definition.labelOn);
+ }
+ if (definition.cssOn) {
+ element.css(definition.cssOn);
+ }
+ } else {
+ state = false;
+ if (definition.labelOff) {
+ element.text(definition.labelOff);
+ }
+ if (definition.cssOff) {
+ element.css(definition.cssOff);
+ }
+ }
+ }
+ }
+ change(definition.dfault);
+ if (!definition.noTriggerInit) {
+ element.trigger("change");
+ }
+
+ if (definition.target) {
+ definition.target.append(element);
+ }
+
+ if (definition.onReady) {
+ definition.onReady(self);
+ }
+ }
+ createControl();
+};
\ No newline at end of file diff --git a/site/app/base/interop_work.deprecated.csd b/site/app/base/interop_work.deprecated.csd new file mode 100644 index 0000000..8a12b18 --- /dev/null +++ b/site/app/base/interop_work.deprecated.csd @@ -0,0 +1,108 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 48000
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+
+
+#include "sequencing_melodic_persistence.udo"
+
+opcode jsio_sendraw, 0, S
+ Smessage xin
+ prints "CBDT "
+ prints Smessage
+ prints "\n"
+endop
+
+
+gijsio_collections[][] init 20, 300
+
+opcode jsio_getcollection
+ Scollection, SonComplete xin
+
+endop
+
+
+instr jsio_loadcollection
+ Sdata = strget(p4)
+
+endin
+
+
+
+
+
+gSjsioBuffer[] init 16
+gijsioBufferMax = 0
+gijsioBufferLock = 0
+
+
+
+
+instr jsio_bufferadd
+ icbid = p4
+ Sstatus = strget(p5)
+ Sdetails = strget(p6)
+ if (gijsioBufferLock == 1) then
+ schedule(p1, 0.1, 1, icbid, Sstatus, Sdetails)
+ else
+ gijsioBufferLock = 1
+ Sitem = sprintf("{\"cbid\":%d", icbid)
+ if (strcmp(Sstatus, "") != 0) then
+ Sitem = strcat(Sitem, sprintf(",\"status\":\"%s\"", Sstatus))
+ endif
+
+ if (strcmp(Sdetails, "") != 0) then
+ Sitem = strcat(Sitem, sprintf(",\"details\":\"%s\"", Sdetails))
+ endif
+
+ gSjsioBuffer[gijsioBufferMax] = strcat(Sitem, "}")
+ gijsioBufferMax += 1
+
+ gijsioBufferLock = 0
+ endif
+ turnoff
+endin
+
+
+instr jsio_bufferflush
+ Schannel = strget(p4)
+
+ if (gijsioBufferLock == 1) then
+ schedule(p1, 0.1, 1, Schannel)
+ else
+ gijsioBufferLock = 1
+ if (gijsioBufferMax == 0) then
+ chnset "", Schannel
+ gijsioBufferLock = 0
+ else
+ index = 0
+ Soutput = "["
+ while (index < gijsioBufferMax) do
+ if (index > 0) then
+ Soutput = strcat(Soutput, ",")
+ endif
+ Soutput = strcat(Soutput, gSjsioBuffer[index])
+ index += 1
+ od
+ Soutput = strcat(Soutput, "]")
+ chnset Soutput, Schannel
+ gijsioBufferMax = 0
+ gijsioBufferLock = 0
+ endif
+ endif
+ turnoff
+endin
+
+
+</CsInstruments>
+<CsScore>
+i "jsio_bufferadd" 0 1
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/base/spline-edit.js b/site/app/base/spline-edit.js new file mode 100644 index 0000000..06faa7e --- /dev/null +++ b/site/app/base/spline-edit.js @@ -0,0 +1,453 @@ +var SplineEdit = function (elTarget, colour, duration, constraints, name) {
+ var self = this;
+ var targetName = "#" + elTarget.attr("id");
+ var svg;
+ var path;
+ var line = d3.line();
+ var yStep;
+ var selected;
+ var dragged;
+ var yScale = [constraints[0], constraints[1]];
+ var region = [0, 1];
+ this.changed = false;
+
+ Object.defineProperty(this, "width", {
+ get: function() { return parseFloat(elTarget.width()); },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "height", {
+ get: function() { return parseFloat(elTarget.height()); },
+ set: function(x) {}
+ });
+
+ if (constraints[3] > 0.0001) {
+ yStep = self.height / ((constraints[1] - constraints[0]) / constraints[3]);
+ }
+
+ var dfaultPos = ((constraints[2] - constraints[0]) / (constraints[1] - constraints[0]));
+ var rawPoints = [[0, dfaultPos], [1, dfaultPos]];
+ var pointRange = [0, 0];
+ var points = [...rawPoints];
+ var circlePoints = [];
+
+ this.getRawPoints = function() {
+ return rawPoints;
+ };
+
+ this.setRawPoints = function(p, noredraw) {
+ rawPoints = p;
+ if (!noredraw) self.redraw();
+ };
+
+ Object.defineProperty(this, "displayPoints", {
+ get: function() {
+ var output = [];
+ var x;
+ for (let p of points) {
+ output.push([p[0] * self.width, (1 - p[1]) * self.height]);
+ }
+ return output;
+ },
+ set: function(x) {}
+ });
+
+ this.resize = function(ratio, noredraw) {
+ for (var i in points) {
+ if (i != 0 && i != rawPoints.length - 1) {
+ rawPoints[i][0] = rawPoints[i][0] * ratio;
+ }
+ }
+ if (!noredraw) self.redraw();
+ };
+
+ function regionToAbsolute(xVal) {
+ return (xVal - region[0]) / (region[1] - region[0]);
+ }
+
+ function absoluteToRegion(xVal) {
+ return (xVal * (region[1] - region[0])) + region[0];
+ }
+
+
+ function interpolateRange(scaled, start, end) {
+ if (!start) start = region[0];
+ if (!end) end = region[1];
+ var scaling = 1 - (end - start);
+ var output = [];
+ var lastIndex;
+ var firstIndex = 0;
+ var lastIndex;
+ var yVal;
+ var xVal;
+ var allPoints = rawPoints;
+ if (start == 0 && end == 1) {
+ return {points: allPoints, indexes: [0, allPoints.length - 1]};
+ }
+
+ for (var i in allPoints) {
+ var x = allPoints[i][0];
+ if (x < start) {
+ firstIndex = parseInt(i);
+ }
+ }
+ for (var i = parseInt(allPoints.length - 1); i > firstIndex; i--) {
+ var x = allPoints[i][0];
+ if (x >= end) {
+ lastIndex = i;
+ }
+ }
+ for (var i = firstIndex; i <= lastIndex; i++) {
+ var v = allPoints[i];
+
+ xVal = (i == lastIndex) ? end : v[0];
+
+ if (i == firstIndex && v[0] != start) {
+ var next = allPoints[parseInt(i + 1)];
+ //yVal = v[1] + (start - v[0]) * (next[1] - v[1]) / (next[0] - v[0]);
+ yVal = v[1] + (v[0] - start) * (next[1] - v[1]) / (next[0] - v[0]);
+ } else if (i == lastIndex && v[0] != end) {
+ var last = allPoints[parseInt(i - 1)];
+ yVal = last[1] + (end - last[0]) * (v[1] - last[1]) / (v[0] - last[0]);
+ } else {
+ yVal = v[1];
+ }
+ if (scaled) xVal = regionToAbsolute(xVal);
+ output.push([xVal, yVal]);
+
+ }
+ return {points: output, indexes: [firstIndex, lastIndex]};
+ }
+
+ function getIndex(point) {
+ for (var i = 0; i < points.length; i ++) {
+ if (points[i][0] == point[0] && points[i][1] == point[1]) {
+ return i;
+ }
+ }
+ }
+
+
+ function getDuration() {
+ if (typeof(duration) == "function") {
+ return duration();
+ } else {
+ return duration;
+ }
+ }
+
+ var redrawing = false;
+ this.redraw = function() {
+ if (redrawing) return;
+ redrawing = true;
+ build();
+ redraw();
+ redrawing = false;
+ };
+
+ function setRangePoints() {
+ /*
+ if (points.length == rawPoints.length) {
+ //rawPoints.length = 0;
+ for (var i in points) {
+ //rawPoints[i] = [regionToAbsolute(points[i][0]), points[i][1]];
+ }
+ }*/
+ var res = interpolateRange(true);
+ pointRange = res.indexes;
+ points.length = 0;
+ circlePoints.length = 0;
+ for (let i in res.points) {
+ points.push(res.points[i]);
+ if ((region[0] == 0 && region[1] == 1)
+ || ((i != 0 || region[0] == 0) && (i != res.points.length - 1 || region[1] == 1)))
+ {
+ circlePoints.push(res.points[i]);
+ }
+ }
+ }
+
+ this.setRange = function(start, end) {
+ if (start != null) region[0] = start;
+ if (end != null) region[1] = end;
+ self.redraw();
+ };
+
+ this.setYScale = function(min, max) { // TODO unused
+ if (!min && !max) {
+ yScale = [constraints[0], constraints[1]];
+ }
+ };
+
+ this.setDuration = function(val) {
+ duration = val;
+ };
+
+ this.setConstraints = function(val) {
+ constraints = val;
+ }
+
+ function calculateValue(xy, asDuration) {
+ var x = xy[0];
+ if (asDuration) {
+ x *= getDuration();
+ }
+ var y = ((constraints[1] - constraints[0]) * xy[1]) + constraints[0];
+ return [x, y];
+ }
+
+ this.getData = function() {
+ var output = [];
+ var val;
+ var allPoints = rawPoints;
+ for (var p of allPoints) {
+ val = calculateValue(p, true);
+ output.push([Math.round(val[0] * 1000) / 1000, Math.round(val[1] * 1000) / 1000]);
+ }
+ return output;
+ };
+
+ this.getLinsegData = function(start, end, nullOnEmpty) {
+ if (nullOnEmpty && rawPoints.length == 2) return;
+ var duration = getDuration(); //(end - start) * getDuration(); // IF we are having dynamic area view
+ var rounding = 10000;
+ var output = [];
+ var lastTime = 0;
+ var time;
+ var lastIndex;
+ var firstIndex;
+ var lastIndex;
+ var allPoints = rawPoints;
+
+ for (var i in allPoints) {
+ var x = allPoints[i][0];
+ if (x <= start) {
+ firstIndex = parseInt(i);
+ }
+ }
+ for (var i = parseInt(allPoints.length - 1); i > firstIndex; i--) {
+ var x = allPoints[i][0];
+ if (x >= end) {
+ lastIndex = i;
+ }
+ }
+ for (var i = firstIndex; i <= lastIndex; i++) {
+ var v = calculateValue(allPoints[i], false);
+ if (i != firstIndex) {
+
+ time = (((i == lastIndex) ? end : v[0]) - start) * duration;
+ output.push((Math.round((time - lastTime) * rounding)) / rounding);
+ lastTime = time;
+ }
+
+ if (i == firstIndex && v[0] != start) {
+ var next = calculateValue(allPoints[parseInt(i + 1)], false);
+ //var interpVal = v[1] + (v[0] - start) * (next[1] - v[1]) / (next[0] - v[0]);
+ var interpVal = v[1] + (start - v[0]) * (next[1] - v[1]) / (next[0] - v[0]);
+ output.push(Math.round(interpVal * rounding) / rounding);
+ } else if (i == lastIndex && v[0] != end) {
+ var last = calculateValue(allPoints[parseInt(i - 1)], false);
+
+ var interpVal = last[1] + (end - last[0]) * (v[1] - last[1]) / (v[0] - last[0]);
+ //var interpVal = last[1] + (last[0] - end) * (v[1] - last[1]) / (v[0] - last[0]);
+ output.push(Math.round(interpVal * rounding) / rounding);
+ } else {
+ output.push(Math.round(v[1] * rounding) / rounding);
+ }
+
+ }
+ return output.join(",");
+ }
+
+ function getLabel(d) {
+ var val = calculateValue([absoluteToRegion(d[0]), d[1]], true);
+ var label = (Math.round(val[0] * 100) / 100) + "s<br/>" + (Math.round(val[1] * 1000) / 1000);
+ if (name) {
+ label = name + "<br/>" + label;
+ }
+ return label;
+ }
+
+ function redraw() {
+ setRangePoints();
+ path.datum(self.displayPoints);
+ svg.select("path").attr("d", line);
+ const circle = svg.selectAll("g").data(circlePoints, function(point){
+ return [point[0] * self.width, (1 - point[1]) * self.height];
+ });
+ circle.enter().append("g").call(
+ g => g.append("circle").attr("r", 0).attr("stroke", colour).attr("stroke-width", 1).attr("r", 7)
+ ).merge(circle).attr("transform", function(d){
+ return "translate(" + (d[0] * self.width) + "," + ((1 - d[1]) * self.height) + ")";
+ }).select("circle:last-child").attr("fill", function(d) {
+ if (selected && d[0] == selected[0] && d[1] == selected[1]) {
+ return "#000000";
+ } else {
+ return colour;
+ }
+ }).on("mouseover", function(event, d) {
+ twirl.tooltip.show(event, getLabel(d), colour);
+ }).on("mouseout", function(event) {
+ twirl.tooltip.hide();
+ }).on("dblclick", function(event, d) {
+ return; // TODO: not working properly particularly when zoomed
+ if (!window.twirl) return;
+ var index = getIndex(d);
+ var duration = getDuration();
+ console.log(d, regionToAbsolute(d[0]));
+ var minTime = ((points[index - 1]) ? absoluteToRegion(points[index - 1] + 0.00001) : 0) * duration;
+ var maxTime = ((points[index + 1]) ? absoluteToRegion(points[index + 1] - 0.00001) : 1) * duration;
+ var el = $("<div />");
+ var tb = $("<tbody />");
+ $("<table />").append(tb).appendTo(el);
+ var tpTime = new twirl.transform.Parameter({
+ host: null,
+ definition: {
+ name: "Time",
+ min: minTime,
+ max: maxTime,
+ dfault: d[0]
+ }
+ });
+ var tpValue = new twirl.transform.Parameter({
+ host: null,
+ definition: {
+ name: name,
+ min: constraints[0],
+ max: constraints[1],
+ dfault: d[1]
+ }
+ });
+
+ tb.append(tpTime.getElementRow(true)).append(tpValue.getElementRow(true));
+ twirl.prompt.show(el, function(){
+ d[0] = regionToAbsolute(tpTime.getValue())
+ d[1] = tpValue.getValue();
+ self.changed = true;
+ });
+ //d[0] = 0.4; d[1] = 0.4;
+ });
+ circle.exit().remove();
+ }
+
+ function build() {
+ line.curve(d3.curveLinear);
+ if (path) {
+ path.remove();
+ delete path;
+ }
+ if (svg) {
+ svg.remove();
+ delete svg;
+ }
+ svg = d3.select(targetName).append("svg").attr("width", self.width).attr("height", self.height);
+ svg.append("rect").attr("width", self.width).attr("height", self.height).attr("fill", "none");
+ path = svg.append("path").attr("fill", "none").attr("stroke", colour).attr("line-width", "3px"); //.call(redraw); // .datum(points)
+
+ svg.call(
+ d3.drag().subject(function(event){
+ let pos = event.sourceEvent.target.__data__;
+ var index;
+ var y;
+ if (!pos) {
+ var index;
+ for (var i = 0; i < rawPoints.length; i++) {
+ if (event.x > regionToAbsolute(rawPoints[i][0]) * self.width && rawPoints[i + 1] && event.x < regionToAbsolute(rawPoints[i + 1][0]) * self.width) {
+ index = i + 1;
+ if (yStep) {
+ y = Math.round(event.y / yStep) * yStep;
+ } else {
+ y = event.y;
+ }
+ //pos = [absoluteToRegion(event.x / self.width), 1 - (y / self.height)];
+ pos = [absoluteToRegion(event.x / self.width), 1 - (y / self.height)];
+ break;
+ }
+ }
+ if (index) {
+ var tmp = rawPoints.slice(0, index);
+ tmp.push(pos);
+ var newPoints = tmp.concat(rawPoints.slice(index));
+ rawPoints.length = 0;
+ Array.prototype.push.apply(rawPoints, newPoints);
+ redraw();
+ }
+ } else if (pos[0] == 0) {
+ index = 0;
+ } else if (pos[0] == 1) {
+ index = rawPoints.length - 1;
+ } else {
+ var p0;
+ var p1;
+ pos[0] = absoluteToRegion(pos[0]);
+ for (var p = 0; p < rawPoints.length; p++) {
+ p1 = (rawPoints[p + 1]) ? rawPoints[p + 1][0] : 1;
+ if (pos[0] != rawPoints[p][0]) {
+ p0 = rawPoints[p][0];
+ } else if (rawPoints[p + 1] && pos[0] == rawPoints[p + 1][0]) {
+ continue;
+ }
+
+ if (pos[0] > p0 && pos[0] < p1) {
+ index = p;
+ break;
+ }
+ }
+ }
+ return {pos: pos, index: index};
+ }).on("start", function(event) {
+ selected = event.subject.pos;
+ redraw();
+ }).on("drag", function(event) {
+ if (!event.subject) return;
+ if (!event.subject.hasOwnProperty("index")) return;
+ self.changed = true;
+ var val;
+ var pos;
+ if (event.subject.index != 0 && event.subject.index != rawPoints.length - 1) {
+ if (rawPoints[event.subject.index - 1] && event.x < regionToAbsolute(rawPoints[event.subject.index - 1][0]) * self.width) {
+ pos = rawPoints[event.subject.index - 1][0] + 0.00001;
+ } else if (rawPoints[event.subject.index - 1] && event.x > regionToAbsolute(rawPoints[event.subject.index + 1][0]) * self.width) {
+ pos = rawPoints[event.subject.index + 1][0] - 0.00001;
+ } else {
+ pos = absoluteToRegion(event.x / self.width);
+ }
+
+ pos = Math.max(0, Math.min(1, pos));
+ event.subject.pos[0] = pos;
+ }
+ if (yStep) {
+ val = Math.round(event.y / yStep) * yStep;
+ } else {
+ val = event.y;
+ }
+ val = 1 - (val / self.height);
+ event.subject.pos[1] = Math.max(0, Math.min(1, val));
+ rawPoints[event.subject.index][0] = event.subject.pos[0];
+ rawPoints[event.subject.index][1] = event.subject.pos[1];
+ redraw();
+ })
+ );
+ svg.node().focus();
+ }
+
+ d3.select(window).on("keydown", function(event){
+ if (!selected) return;
+ switch (event.key) {
+ case "Backspace":
+ case "Delete": {
+ event.preventDefault();
+ var i = rawPoints.indexOf(selected);
+ if (i != 0 && i != points.length - 1) {
+ rawPoints.splice(i, 1);
+ selected = rawPoints.length ? rawPoints[i > 0 ? i - 1 : 0] : null;
+ self.changed = true;
+ redraw();
+ }
+ }
+ }
+ });
+
+ build()
+ self.setRange(0, 1);
+};
diff --git a/site/app/base/waveform.js b/site/app/base/waveform.js new file mode 100644 index 0000000..c6276f1 --- /dev/null +++ b/site/app/base/waveform.js @@ -0,0 +1,1076 @@ +var Waveform = function(options) {
+ var self = this;
+ var elTarget;
+ if (typeof(options.target) == "string") {
+ elTarget = $("#" + options.target);
+ } else {
+ elTarget = options.target;
+ }
+ var elContainerOuter = $("<div />").css({position: "absolute", width: "100%", height: "100%"}).appendTo(elTarget);
+ var elContainer = $("<div />").css({cursor: "text", position: "absolute", width: "100%", bottom: "0px", top: "0px", left: "0px"}).appendTo(elContainerOuter);
+ var elTip = $("<div />").css({position: "fixed", "font-size": "var(--fontSizeLarge)", color: "var(--fgColor1)", "text-shadow": "0px 0px 5px var(--bgColor1)", "z-index": 12}).appendTo(elContainer);
+ var elCanvases = [];
+ var elTimeBar;
+ var elPlayhead;
+ var elCrossfades = [];
+ var elMarkersRunner;
+ var crossFadeRatios = [];
+ var selected = [0, 1, -1];
+ var onSelects = [];
+ var channels;
+ var wavedata = null;
+ var regionStart = 0;
+ var regionEnd = 1;
+ var duration = 1;
+ var stereoSelectRatio = 0.2
+ var dragData = {};
+ this.markers = [];
+ var selectionMarkers = [];
+ var hasContent = false;
+ this.onRegionChange = null;
+
+ this.getRegion = function() {
+ return [regionStart, regionEnd];
+ };
+
+ function absPosToDisplayPos(x) {
+ var pos = (x - regionStart) / (regionEnd - regionStart);
+ return (pos >= 0 && pos <= 1) ? pos : null;
+ }
+
+ function displayPosToAbsPos(x) {
+ return ((regionEnd - regionStart) * x) + regionStart;
+ }
+
+ function getDisplaySelected() {
+ var hasSelection = (selected[0] != selected[1]);
+ var start = absPosToDisplayPos(selected[0]);
+ //if (start == null) start = 0;
+ var end = absPosToDisplayPos(selected[1]);
+ //if (end == null) end = 1;
+
+ if (start && !end) end = 1;
+ if (!start && end) start = 0;
+ if (!start && !end) {
+ if (hasSelection) {
+ start = 0;
+ end = 1;
+ } else {
+ start = end = 0;
+ }
+ }
+ return [
+ start,
+ end,
+ selected[2]
+ ];
+ }
+
+ if (!options) {
+ options = {};
+ }
+
+ if (options.hasOwnProperty("onSelect")) {
+ onSelects.push(options.onSelect);
+ }
+
+ if (options.hasOwnProperty("duration")) {
+ duration = options.duration;
+ }
+
+ if (!options.hasOwnProperty("latencyCorrection")) {
+ options.latencyCorrection = 0;
+ }
+
+ if (!options.hasOwnProperty("showcrossfades")) {
+ options.showcrossfades = false;
+ }
+
+ if (!options.hasOwnProperty("showGrid")) {
+ options.showGrid = true;
+ }
+
+ if (!options.hasOwnProperty("drawStyle")) {
+ options.drawStyle = "bar"; //"linebar";
+ }
+
+ if (!options.hasOwnProperty("allowSelect")) {
+ options.allowSelect = true;
+ }
+
+ if (options.allowSelect) {
+ elContainer.mousedown(mouseDownHandler).dblclick(mouseDoubleClickHandler).on("mousemove", function(e) {
+ if (channels != 2) return;
+ var ratio = (e.clientY - elContainer.offset().top) / parseFloat(elContainer.height());
+ var shown = false;
+ var text;
+ if (ratio > 1 - stereoSelectRatio) {
+ shown = true;
+ text = "R";
+ } else if (ratio < stereoSelectRatio) {
+ shown = true;
+ text = "L";
+ }
+ if (shown) {
+ elTip.show().css({left: (e.clientX + 10) + "px", top: (e.clientY - 5) + "px"}).text(text);
+ } else {
+ elTip.hide();
+ }
+ }).on("mouseleave", function(){
+ elTip.hide();
+ });
+ }
+
+ var elCover = $("<div />").css({position: "absolute", width: "100%", height: "100%", "background-color": "var(--waveformCoverColor)", opacity: "var(--waveformCoverOpacity)", display: "none", "z-index": 10}).appendTo(elContainerOuter);
+
+ var Marker = function(data, identifier) {
+ var mself = this;
+ var elMarkers;
+ var headerWidth = 14;
+ var headerHeight = 15;
+ var elLine;
+ var elHeader;
+ var drag
+ var position;
+ var onMarkerChange;
+
+ Object.defineProperty(this, "position", {
+ get: function() { return position; },
+ set: function(x) {
+ setPosition(x);
+ }
+ });
+
+ Object.defineProperty(this, "identifier", {
+ get: function() { return identifier; },
+ set: function(x) {
+ identifier = x;
+ }
+ });
+
+ if (typeof(data) == "number") {
+ position = data;
+ } else if (data.preset) {
+ if (data.preset == "selectionstart") {
+ identifier = "";
+ selectionMarkers[0] = mself;
+ onMarkerChange = function() {
+ if (position > selectionMarkers[1].position) {
+ self.alterSelection(selectionMarkers[1].position, position, null, true);
+ } else {
+ self.alterSelection(position, null, null, true);
+ }
+ };
+ onSelects.push(function(start, regionStart, end) {
+ setPosition(start);
+ });
+ } else if (data.preset == "selectionend") {
+ identifier = "";
+ selectionMarkers[1] = mself;
+ onMarkerChange = function() {
+ if (position < selectionMarkers[0].position) {
+ self.alterSelection(position, selectionMarkers[0].position, null, true);
+ } else {
+ self.alterSelection(null, position, null, true);
+ }
+ };
+ onSelects.push(function(start, regionStart, end) {
+ setPosition(end);
+ });
+ }
+ } else {
+ position = data.position;
+ if (data.hasOwnProperty("identifier")) {
+ identifier = data.identifier;
+ }
+
+ if (data.hasOwnProperty("onChange")) {
+ onMarkerChange = data.onChange;
+ }
+
+ }
+
+ function setPosition(displayPos) {
+ if (!hasContent) return;
+ if (displayPos != null) {
+ position = displayPosToAbsPos(displayPos);
+ } else {
+ displayPos = absPosToDisplayPos(position);
+ }
+ if (!elLine) {
+ elLine = $("<div />").appendTo(elContainer).addClass("waveform_marker").css({position: "absolute",
+ height: "100%", top: "0px", width: "2px", "background-color": "var(--waveformMarkerColor)", "z-index": 11
+ });
+ }
+ if (!elHeader) {
+ elHeader = $("<div />").appendTo(elMarkersRunner).addClass("waveform_marker").css({position: "absolute",
+ height: "100%", top: "0px", width: headerWidth + "px", "background-color": "var(--waveformMarkerColor)", "border-bottom-left-radius": headerWidth + "px", "border-bottom-right-radius": headerWidth + "px", "z-index": 8,
+ "text-align": "center", "font-family": "sans-serif, Arial", "font-size": "8pt", "font-weight": "bold", cursor: "move", "user-select": "none"
+ }).mousedown(handleMousedown);
+ }
+
+ if (displayPos == null) {
+ elLine.hide();
+ elHeader.hide();
+ } else {
+ var posx = elContainer.width() * displayPos;
+ elLine.show().css("left", posx + "px");
+ posx = (posx - (headerWidth / 2)) + 1;
+ elHeader.show().css("left", posx + "px").text(identifier);
+ }
+ }
+
+ this.redraw = function() {
+ if (!hasContent) return;
+ if (position < regionStart || position > regionEnd) {
+ if (elLine) elLine.hide();
+ if (elHeader) elHeader.hide();
+ } else {
+ setPosition();
+ elLine.show();
+ elHeader.show();
+ }
+ }
+
+
+ function handleMousedown(e) {
+ if (!hasContent) return;
+ var pageX = e.pageX;
+ var offset = elMarkersRunner.offset();
+ var width = elMarkersRunner.width();
+
+ function handleDrag(e) {
+ var pos = ((e.pageX - pageX) + (pageX - offset.left)) / width;
+
+ if (pos <= 1 && pos >= 0) {
+ setPosition(pos);
+ if (onMarkerChange) {
+ onMarkerChange(pos);
+ }
+ }
+ }
+ function handleMouseUp(e) {
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp);
+ }
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ }
+
+ setPosition();
+ }; // end marker
+
+
+ if (options.hasOwnProperty("markers")) {
+ elContainer.css("top", "15px");
+ elMarkersRunner = $("<div />").appendTo(elContainerOuter).css({position: "absolute", width: "100%", height: "15px", top: "0px", left: "0px", "background-color": "var(--waveformMarkerRunnerColor)"});
+ if (typeof(options.markers) == "object") {
+ var id = 1;
+ for (let m of options.markers) {
+ self.markers.push(new Marker(m, id++));
+ }
+ }
+ }
+
+
+ if (options.timeBar) {
+ elContainer.css({overflow: "hidden", bottom: "20px"});
+ var elTimeBarOuter = $("<div />").appendTo(elContainerOuter).css({position: "absolute", width: "100%", height: "20px", bottom: "0px", left: "0px", "background-color": "var(--waveformTimeBarBgColor)"});
+ var elTimeBarIcons = $("<div />").appendTo(elTimeBarOuter).css({position: "absolute", width: "80px", height: "100%", bottom: "0px", left: "0px"});
+ var elTimeBarContainer = $("<div />").appendTo(elTimeBarOuter).css({position: "absolute", right: "0px", height: "100%", bottom: "0px", left: "80px", "background-color": "var(--waveformTimeBarBgColor)"}).click(handleTimeBarTrackClick);
+
+ elTimeBar = $("<div />").appendTo(elTimeBarContainer).css({position: "absolute", right: "0px", height: "16px", top: "2px", left: "0px", "background-color": "var(--waveformTimeBarFgColor)"}).mousedown(handleTimeBarMousedown);
+
+ elTimeBarIcons.append(twirl.createIcon({
+ label: "Zoom selection",
+ size: 20,
+ icon: "zoomSelection",
+ click: function() {
+ self.zoomSelection()
+ }
+ }).el);
+
+ elTimeBarIcons.append(twirl.createIcon({
+ label: "Zoom in",
+ size: 20,
+ icon: "zoomIn",
+ click: function() {
+ self.zoomIn()
+ }
+ }).el);
+
+ elTimeBarIcons.append(twirl.createIcon({
+ label: "Zoom out",
+ size: 20,
+ icon: "zoomOut",
+ click: function() {
+ self.zoomOut()
+ }
+ }).el);
+
+ elTimeBarIcons.append(twirl.createIcon({
+ label: "Show all",
+ size: 20,
+ icon: "showAll",
+ click: function() {
+ self.setRegion(0, 1);
+ }
+ }).el);
+
+
+ function setTimeBarPosition(displayLeft, displayRight, setRegion) {
+ if (displayLeft >= 0 && displayRight >= 0) {
+ elTimeBar.css({left: displayLeft, right: displayRight});
+ var w = elTimeBarContainer.width();
+ if (setRegion) {
+ regionStart = displayLeft / w;
+ regionEnd = 1 - (displayRight / w);
+ if (self.onRegionChange) {
+ self.onRegionChange([regionStart, regionEnd]);
+ }
+ }
+ }
+ }
+
+ function handleTimeBarTrackClick(event) {
+ var increment = 20;
+ var apos = event.pageX - elTimeBarContainer.offset().left;
+ var left = parseInt(elTimeBar.css("left"));
+ var right = parseInt(elTimeBar.css("right"));
+ var tbWidth = parseInt(elTimeBar.css("width"));
+ if (apos < left) {
+ left -= increment;
+ right += increment;
+ } else if (apos > left + tbWidth) {
+ left += increment;
+ right -= increment;
+ } else {
+ return;
+ }
+ setTimeBarPosition(left, right, true);
+ draw();
+ }
+
+ function handleTimeBarMousedown(e) {
+ if (!hasContent) return;
+ var pageX = e.pageX;
+ var offset = elTimeBarContainer.offset();
+ var cWidth = elTimeBarContainer.width();
+ var tbWidth = elTimeBar.width();
+ var sLeft = pageX - offset.left - parseInt(elTimeBar.css("left"));
+
+ function handleDrag(e) {
+ var left = ((e.pageX - pageX) + (pageX - offset.left));
+ left = left - sLeft;
+ var end = left + tbWidth;
+ var right = cWidth - end;
+ setTimeBarPosition(left, cWidth - end, true);
+ draw(4); //draw(15);
+
+ }
+
+ function handleMouseOut(e) {
+ handleMouseUp(e);
+ }
+
+ function handleMouseUp(e) {
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp).off("mouseleave", handleMouseOut);
+ function ensureDraw() {
+ if (drawing) return setTimeout(ensureDraw, 20);
+ draw();
+ }
+ ensureDraw();
+ }
+ $("body")
+ .on("mouseup", handleMouseUp)
+ .on("mousemove", handleDrag)
+ .on("mouseleave", handleMouseOut);
+ }
+ }
+
+ this.getDuration = function() {
+ return duration;
+ };
+
+ this.destroy = function() {
+ elTarget.remove();
+ };
+
+ this.show = function() {
+ elTarget.show();
+ };
+
+ this.hide = function() {
+ elTarget.hide();
+ };
+
+ this.cover = function(state) {
+ if (state) {
+ elCover.show();
+ } else {
+ elCover.hide();/*
+ setTimeout(function() {
+ elCover.hide();
+ }, options.latencyCorrection);*/
+ }
+ };
+
+ this.setOptions = function(o) {
+ Object.assign(options, o);
+ };
+
+
+ function drawCrossFades() {
+ if (!hasContent) return;
+ if (!options.showcrossfades) return;
+ if (elCrossfades.length == 0) {
+ for (var x = 0; x < 2; x++) {
+ elCrossfades.push($("<div />").css({
+ position: "absolute",
+ width: "1px",
+ "z-index": 9,
+ "line-width": "1px",
+ "height": "var(--waveformCrossfadeWidth)",
+ "background-color": "var(--waveformCrossfadeLineColor)"
+ }).appendTo(elContainer));
+ }
+ }
+ var containerHeight = elContainer.height();
+ var containerWidth = elContainer.width();
+ var displaySelected = getDisplaySelected();
+
+
+ function drawCrossfade(index) {
+ var thickness = 1;
+ var ratio = crossFadeRatios[index];
+ if (ratio == 0) {
+ elCrossfades[index].hide();
+ }
+
+ if (index == 0) {
+ var x1 = displaySelected[0] * containerWidth;
+ var y1 = containerHeight;
+ var x2 = x1 + (ratio * ((displaySelected[1] - displaySelected[0]) * containerWidth));
+ var y2 = 0;
+ } else {
+ var x1 = displaySelected[1] * containerWidth;;
+ var y1 = containerHeight;
+ var x2 = x1 - (ratio * ((displaySelected[1] - displaySelected[0]) * containerWidth));
+ var y2 = 0;
+ }
+ var length = Math.sqrt(((x2-x1) * (x2-x1)) + ((y2-y1) * (y2-y1)));
+ var centrex = ((x1 + x2) / 2) - (length / 2);
+ var centrey = ((y1 + y2) / 2) - (thickness / 2);
+ var angle = Math.atan2((y1-y2),(x1-x2))*(180/Math.PI);
+ elCrossfades[index].show().css({transform: "rotate(" + angle + "deg)", left: centrex, top: centrey, width: length + "px"});
+ }
+ drawCrossfade(0);
+ drawCrossfade(1);
+
+ };
+
+ this.alterSelection = function(start, end, channel, noOnSelects) {
+ if (!hasContent) return;
+ if (start != null) {
+ selected[0] = start;
+ }
+ if (end != null) {
+ selected[1] = end;
+ }
+
+ var displaySelected = getDisplaySelected();
+
+ if (channel == null) {
+ channel = selected[2];
+ } else {
+ selected[2] = channel;
+ }
+
+ var elWidth = elContainer.width();
+ var left = displaySelected[0] * elWidth;
+ var width = (displaySelected[1] * elWidth) - left;
+
+ if (dragData.selection) {
+ dragData.selection.css({
+ left: left,
+ width: width
+ });
+ }
+
+ if (dragData.location) {
+ dragData.location.css({
+ left: left
+ });
+ }
+
+ if (!noOnSelects && onSelects) {
+ for (let onSelect of onSelects) {
+ onSelect(start, regionStart, end, regionEnd, self);
+ }
+ }
+ drawCrossFades();
+ }
+
+ this.setSelection = function(start, end, channel) {
+ if (!hasContent) return;
+ if (!end) {
+ end = start;
+ }
+ self.alterSelection(start, end, channel);
+ };
+
+
+ function selectionMade() {
+ if (!hasContent) return;
+ var cWidth = elContainer.width();
+ var left = parseFloat(dragData.selection.css("left"));
+ var width = parseFloat(dragData.selection.css("width"));
+ var start = left / cWidth;
+ var end = (left + width) / cWidth;
+
+ selected = [
+ displayPosToAbsPos(start),
+ displayPosToAbsPos(end),
+ dragData.channel
+ ];
+
+ if (onSelects) {
+ for (let onSelect of onSelects) {
+ onSelect(start, regionStart, end, regionEnd, self);
+ }
+ }
+ drawCrossFades();
+ }
+
+ function createSelectionArea(e, leftOverride, widthOverride) {
+ var left = (leftOverride != null ) ? leftOverride : e.pageX - dragData.offset.left;
+
+ var containerHeight = parseFloat(elContainer.height());
+ var yratio = (e.pageY - dragData.offset.top) / containerHeight;
+ var heightmult = 1;
+ var topaugment = 0;
+ dragData.channel = -1;
+ if (channels == 2) {
+ if (yratio > 1 - stereoSelectRatio) {
+ heightmult = 0.5;
+ topaugment = containerHeight * 0.5;
+ dragData.channel = 1;
+ } else if (yratio < stereoSelectRatio) {
+ heightmult = 0.5;
+ dragData.channel = 0;
+ }
+ }
+ var width = (widthOverride != null) ? widthOverride : "0px";
+
+ if (dragData && dragData.selection) {
+ dragData.selection.remove();
+ }
+
+ dragData.selection = $("<div />")
+ .addClass("waveformSelection")
+ .css({
+ left: left,
+ top: topaugment,
+ position: "absolute",
+ opacity: "var(--waveformSelectOpacity)",
+ backgroundColor: "var(--waveformSelectColor)",
+ height: (100 * heightmult) + "%", //containerHeight * heightmult,
+ width: width,
+ "pointer-events": "none",
+ "z-index": 10
+ }).appendTo(elContainer);
+
+ if (dragData && dragData.location) {
+ dragData.location.remove();
+ }
+ dragData.location = $("<div />")
+ .addClass("waveformLocation")
+ .css({
+ left: left,
+ top: 0,
+ position: "absolute",
+ opacity: "var(--waveformSelectOpacity)",
+ backgroundColor: "var(--waveformLocationColor)",
+ width: "0px",
+ border: "1px solid black",
+ height: "100%", //elContainer.height(),
+ "pointer-events": "none",
+ "z-index": 11
+ }).appendTo(elContainer);
+ }
+
+ function mouseDoubleClickHandler(e) {
+ if (!hasContent) return;
+ dragData.pageX = 0;
+ dragData.offset.left = 0;
+ //dragData.pageXend = elContainer.width(); // TODO redundant
+ createSelectionArea(e, 0, elContainer.width());
+ selectionMade();
+ }
+
+ function mouseDownHandler(e) {
+ if (!hasContent) return;
+ var tolerancePx = 4;
+ if (!e.shiftKey) {
+ dragData.pageX = e.pageX;
+ dragData.pageY = e.pageY;
+ //dragData.pageXend = 0; // TODO redundant
+ dragData.elem = this;
+ dragData.offset = $(this).offset();
+ createSelectionArea(e);
+ dragData.shifted = false;
+ } else {
+ dragData.shifted = true;
+ handleDrag(e);
+ }
+
+ var elWidth = elContainer.width();
+ /*if (options.showcrossfades && elCrossfades.length != 0) {
+ elCrossfades[0].hide();
+ elCrossfades[1].hide();
+ }*/ // TODO redundant
+
+ function handleDrag(e) {
+ var origin = dragData.pageX - dragData.offset.left;
+ var dragPos = (e.pageX - dragData.pageX);
+ if (dragPos >= 0) {
+ if (dragPos + origin > elWidth) {
+ dragPos = elWidth;
+ }
+ if (dragPos <= tolerancePx) dragPos = 0;
+ dragData.selection.css({
+ left: origin + "px",
+ width: dragPos + "px"
+ });
+ } else {
+ var dpos = dragPos + origin;
+ var left;
+ var width;
+ if (dpos <= 0) {
+ left = 0;
+ width = origin;
+ } else {
+ left = dpos;
+ width = Math.abs(dragPos);
+ }
+ if (width <= tolerancePx) width = 0;
+ dragData.selection.css({
+ left: left + "px",
+ width: width + "px"
+ });
+ }
+ }
+
+ function handleMouseUp(e) {
+ $("body")
+ .off("mousemove", handleDrag)
+ .off("mouseup", handleMouseUp)
+ .off("mouseleave", handleMouseOut);
+ if (!hasContent) return;
+ //dragData.pageXend = e.pageX; // TODO redundant
+ selectionMade();
+ }
+
+ function handleMouseOut(e) {
+ if (e.clientX > $("body").width()) {
+ var left = parseFloat(dragData.selection.css("left"));
+ dragData.selection.css({width: (elContainer.width() - left) + "px"});
+ }
+ handleMouseUp(e);
+ }
+
+ $("body")
+ .on("mouseup", handleMouseUp)
+ .on("mousemove", handleDrag)
+ .on("mouseleave", handleMouseOut);
+ }
+
+ var lastDrawOneValueXpos;
+
+ this.resetDrawOneValue = function() {
+ lastDrawOneValueXpos = null;
+ };
+
+ function drawOneValue(x, values) {
+ var style = getComputedStyle(document.body);
+ var bgColour = (options.hasOwnProperty("bgColor")) ? options.bgColour : style.getPropertyValue("--waveformBgColor");
+ var fgColour = (options.hasOwnProperty("fgColor")) ? options.fgColour : style.getPropertyValue("--waveformFgColor");
+
+ function drawCanvas(canvasIndex, val) {
+ if (!val) return;
+ var elCanvas = elCanvases[canvasIndex];
+ let width = elCanvas.width();
+ let height = elCanvas.height();
+ let ctx = elCanvas[0].getContext("2d");
+ var lineWidth = 1;
+ if (lastDrawOneValueXpos) {
+ lineWidth = x - lastDrawOneValueXpos;
+ ctx.fillStyle = bgColour;
+ ctx.fillRect(lastDrawOneValueXpos, 0, lineWidth, height);
+ ctx.strokeStyle = fgColour;
+ }
+ lastDrawOneValueXpos = x;
+ ctx.lineWidth = lineWidth;
+ ctx.lineCap = "round";
+ ctx.fillStyle = fgColour;
+
+ ctx.beginPath();
+ val = (val + 1) * 0.5;
+ var posY0 = (val * height);
+ var posY1 = (height - posY0);
+ ctx.moveTo(x, posY0);
+ ctx.lineTo(x, posY1);
+ ctx.closePath();
+ ctx.stroke();
+ }
+
+ drawCanvas(0, values[0]);
+ if (values.length == 2) {
+ drawCanvas(1, values[1]);
+ }
+ }
+
+ this.movePlayhead = function(xratio, monitorValues) {
+ if (!hasContent) return;
+ setTimeout(function() {
+ var displayPos = absPosToDisplayPos(xratio);
+ if (!displayPos || displayPos < 0 || displayPos > 1) {
+ if (elPlayhead) {
+ elPlayhead.remove();
+ elPlayhead = null;
+ }
+ return;
+ }
+ var width = elContainer.width();
+ var left = Math.min(width * displayPos, width - 1);
+
+ if (monitorValues) {
+ drawOneValue(left, monitorValues);
+ }
+
+ if (!elPlayhead) {
+ elPlayhead = $("<div />")
+ .addClass("waveformPlayhead")
+ .css({
+ left: left,
+ top: 0,
+ position: "absolute",
+ backgroundColor: "var(--waveformPlayheadColor)",
+ width: "0px",
+ border: "1px solid var(--waveformPlayheadColor)",
+ height: "100%",
+ "pointer-events": "none",
+ "z-index": 13
+ }).appendTo(elContainer);
+ } else {
+ elPlayhead.css({left: left + "px"});
+ }
+ }, options.latencyCorrection);
+ };
+
+ var drawing = false;
+ async function draw(efficiency) {
+ if (!hasContent || !wavedata || wavedata.length == 0) return;
+ if (drawing) return;
+ drawing = true;
+
+ if (!efficiency) efficiency = 1;
+
+ if (elCanvases.length == 0) {
+ for (var i in wavedata) {
+ var height;
+ var top;
+ if (wavedata.length == 1) {
+ top = "0px";
+ height = "100%";
+ } else {
+ height = "50%";
+ if (i == 0) {
+ top = "0px";
+ } else {
+ top = "50%";
+ }
+ }
+ elCanvases[i] = $("<canvas />").css({position: "absolute", width: "100%", height: height, top: top, left: "0px"}).addClass("waveform_canvas").appendTo(elContainer);
+ }
+ }
+
+ for (m of self.markers) {
+ m.redraw();
+ }
+ self.alterSelection(null, null, null, true); // redraw selection and xfades
+
+
+ async function drawCanvas(canvasIndex) {
+ var elCanvas = elCanvases[canvasIndex]; //.empty();
+ elCanvas[0].width = elContainer.width();
+ elCanvas[0].height = elContainer.height() / wavedata.length;
+ let width = elCanvas.width();
+ let height = elCanvas.height();
+ let ctx = elCanvas[0].getContext("2d");
+ var wavelength;
+ var access;
+ if (typeof(wavedata[canvasIndex]) == "function") {
+ wavelength = await wavedata[canvasIndex](-1);
+ access = wavedata[canvasIndex];
+ } else {
+ wavelength = wavedata[0].length;
+ access = async function(index) {
+ return wavedata[0][index];
+ };
+ }
+
+ var start = Math.round(regionStart * wavelength);
+ var end = Math.round(regionEnd * wavelength);
+ var regionLength = Math.round((regionEnd - regionStart) * wavelength);
+ var indexStep = (regionLength / width) * efficiency;
+ var widthStep = (indexStep < 1) ? parseInt(width / regionLength) : 1;
+ widthStep = parseInt(Math.max(1, widthStep) * efficiency);
+ indexStep = parseInt(indexStep);
+
+ var style = getComputedStyle(document.body);
+ var bgColour = (options.hasOwnProperty("bgColor")) ? options.bgColor : style.getPropertyValue("--waveformBgColor");
+ var fgColour = (options.hasOwnProperty("fgColor")) ? options.fgColor : style.getPropertyValue("--waveformFgColor");
+ var val;
+ ctx.fillStyle = bgColour;
+ ctx.fillRect(0, 0, width, height);
+ ctx.strokeStyle = fgColour;
+
+ if (options.drawStyle == "line") {
+ ctx.lineCap = "butt";
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ ctx.moveTo(0, height * 0.5);
+ for (var x = 0, i = start; x < width; x+=widthStep, i+=indexStep) {
+ val = await access(i);
+ val = (val + 1) * 0.5;
+ ctx.lineTo(x, (val * height) );
+ }
+ ctx.closePath();
+ ctx.stroke();
+ } else if (options.drawStyle == "bar") {
+ ctx.lineWidth = widthStep;
+ ctx.lineCap = "round";
+ ctx.fillStyle = fgColour;
+ ctx.beginPath();
+
+ for (var x = 0, i = start; x < width; x+=widthStep, i+=indexStep) {
+ val = await access(i);
+ val = (val + 1) * 0.5;
+ var posY0 = (val * height);
+ var posY1 = (height - posY0);
+ ctx.moveTo(x, posY0);
+ ctx.lineTo(x, posY1);
+ }
+ ctx.closePath();
+ ctx.stroke();
+ } else if (options.drawStyle == "linebar") {
+ ctx.lineWidth = 1;
+ ctx.fillStyle = fgColour;
+ ctx.lineCap = "butt";
+
+ ctx.beginPath();
+ ctx.moveTo(0, height * 0.5);
+ xindex = 0;
+
+ var vals = [];
+ for (var x = 0, i = start; x < width; x+=widthStep, i+=indexStep) {
+ val = await access(i);
+ val = (val + 1) * 0.5;
+ vals[i] = val;
+ var posY0 = (val * height);
+ ctx.lineTo(x, posY0);
+ }
+
+ ctx.lineTo(width, (height * 0.5));
+
+ for ( ; x >= 0; x-=widthStep, i-=indexStep) {
+ var posY1 = (height - (vals[i] * height));
+ ctx.lineTo(x, posY1);
+ }
+
+ ctx.lineTo(0, height * 0.5);
+ ctx.fill();
+ ctx.closePath();
+ ctx.stroke();
+ } else {
+ console.log("Invalid drawStyle");
+ } // end drawing waveform
+
+ if (options.showGrid){
+ var lineSpacing = 50;
+ var lineNum = width / lineSpacing;
+ var position;
+
+ ctx.lineCap = "butt";
+ ctx.lineWidth = 1;
+ for (var x = 0; x < lineNum; x++) {
+ ctx.beginPath();
+ var left = x * lineSpacing;
+ ctx.strokeStyle = ctx.fillStyle = style.getPropertyValue("--waveformGridColor");
+ ctx.moveTo(left, 0);
+ ctx.lineTo(left, height);
+ ctx.stroke();
+
+ if ((canvasIndex == 0 && elCanvases.length == 1) ||
+ (canvasIndex == 1 && elCanvases.length == 2)) {
+
+ ctx.strokeStyle = ctx.fillStyle = style.getPropertyValue("--waveformGridTextColor");
+ positionLabel = duration * (regionStart + (((regionEnd - regionStart) / lineNum) * x));
+ ctx.fillText(Math.round(positionLabel * 1000 ) / 1000, left + 2, height - 2);
+ }
+ }
+
+ } // if showgrid
+
+ if (canvasIndex == 0 && elCanvases.length == 2) {
+ ctx.beginPath();
+ ctx.lineCap = "butt";
+ ctx.lineWidth = 1;
+ ctx.strokeStyle = style.getPropertyValue("--waveformChannelLineColor");
+ ctx.fillStyle = ctx.strokeStyle;
+ ctx.moveTo(0, height - 1);
+ ctx.lineTo(width, height - 1);
+ ctx.closePath();
+ ctx.stroke();
+ }
+ } // end drawCanvas
+
+ var drawCompletes = [];
+ for (let i in elCanvases) {
+ drawCompletes.push(false);
+ drawCanvas(i).then(function(){
+ drawCompletes[i] = true;
+ for (let c of drawCompletes) {
+ if (!c) {
+ return;
+ }
+ }
+ drawing = false;
+ });
+ }
+ }
+
+ this.redraw = function() {
+ draw();
+ };
+
+ Object.defineProperty(this, "crossFadeInRatio", {
+ get: function() { return crossFadeRatios[0]; },
+ set: function(v) {
+ crossFadeRatios[0] = v;
+ drawCrossFades();
+ }
+ });
+
+ Object.defineProperty(this, "crossFadeOutRatio", {
+ get: function() { return crossFadeRatios[1]; },
+ set: function(v) {
+ crossFadeRatios[1] = v;
+ drawCrossFades();
+ }
+ });
+
+ Object.defineProperty(this, "selected", {
+ get: function() { return selected; },
+ set: function(x) { }
+ });
+
+ Object.defineProperty(this, "duration", {
+ get: function() { return duration; },
+ set: function(x) { }
+ });
+
+ Object.defineProperty(this, "channels", {
+ get: function() { return channels; },
+ set: function(x) { }
+ });
+
+ Object.defineProperty(this, "regionStart", {
+ get: function() { return regionStart; },
+ set: function(x) {
+ self.setRegion(x, regionEnd);
+ }
+ });
+
+ Object.defineProperty(this, "showGrid", {
+ get: function() { return options.showGrid; },
+ set: function(x) {
+ options.showGrid = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "regionEnd", {
+ get: function() { return regionEnd; },
+ set: function(x) {
+ self.setRegion(regionStart, x);
+ }
+ });
+
+
+ this.zoomSelection = function() {
+ if (!dragData || !dragData.location) return;
+ dragData.location.css("left", "0px");
+ self.setRegion(selected[0], selected[1]);
+ };
+
+ this.zoomOut = function() {
+ self.setRegion(regionStart * 0.9, regionEnd * 1.1);
+ };
+
+ this.zoomIn = function() {
+ self.setRegion(regionStart * 1.1, regionEnd * 0.9);
+ };
+
+ this.setRegion = function(start, end) {
+ if (!hasContent) return;
+ if (end <= start) return;
+ if (end > 1) end = 1;
+ if (start < 0) start = 0;
+ regionStart = start;
+ regionEnd = end;
+ draw();
+ if (elTimeBar) {
+ var elTbcw = elTimeBarContainer.width();
+ elTimeBar.css({left: (regionStart * elTbcw) + "px", right: ((1 - regionEnd) * elTbcw) + "px"});
+ }
+ if (self.onRegionChange) {
+ self.onRegionChange([regionStart, regionEnd]);
+ }
+ };
+
+ this.setData = function(data, nduration, noRedraw) {
+ hasContent = true;
+ wavedata = data; // should be array
+ if (channels != data.length) {
+ for (var i in elCanvases) {
+ elCanvases[i].remove();
+ }
+ delete elCanvases[i];
+ elCanvases.length = 0;
+ }
+ channels = data.length;
+ duration = (nduration) ? nduration : 1;
+ if (!noRedraw) {
+ draw();
+ }
+ };
+
+ var lastSize = [];
+ function handleResize() {
+ if (!hasContent) return;
+ var width = elContainer.width();
+ var height = elContainer.height();
+
+ if (lastSize[0] = width && lastSize[1] == height) return;
+ lastSize = [width, height];
+
+ if (dragData && dragData.selection) {
+ selectionMade();
+ }
+ draw();
+ }
+
+ if (!options.noResizeHandler) {
+ window.addEventListener("resize", handleResize);
+ }
+}
diff --git a/site/app/clipart/clipart.csd b/site/app/clipart/clipart.csd new file mode 100644 index 0000000..570329a --- /dev/null +++ b/site/app/clipart/clipart.csd @@ -0,0 +1,63 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+#include "wavetables.udo"
+
+opcode oscbank, a, kkkkiiiiio
+ kfreq, kamp, kfreqstepmult, kampstepmult, ibands, iwidthamp, icentreamp, ihalfing, imaxrandrate, iband xin
+
+ aosc oscil kamp, min:k(kfreq, sr / 2)
+ aosc pdhalfy aosc, ihalfing
+ kwidth = abs:k(oscil:k(iwidthamp, random(0.1, imaxrandrate), gifnSine, random(0, 1)))
+ kcentre = abs:k(oscil:k(icentreamp, random(0.1, imaxrandrate), gifnSine, random(0, 1)))
+ aosc pdclip aosc, kwidth, kcentre
+
+ if (iband < ibands) then
+ arecurse oscbank kfreq * kfreqstepmult, kamp * kampstepmult, kfreqstepmult, kampstepmult, ibands, iwidthamp, icentreamp, ihalfing, imaxrandrate, iband + 1
+ aosc += arecurse
+ endif
+ xout aosc
+endop
+
+
+instr playback
+ ixstart = p4
+ iystart = p5
+ ixend = p6
+ iyend = p7
+ icolour = p8
+ ivariation = p9
+ iwidth = p10
+ iheight = p11
+
+ istartfreq = (ixstart * 100) + 20
+ iendfreq = (ixend * 100) + 20
+ kfreq linseg istartfreq, p3, iendfreq
+
+ istartfstep = iystart + 1.3
+ iendfstep = iyend + 1.3
+ kfreqstepmult linseg istartfstep, p3, iendfstep
+
+ aamp linseg 0, p3 * 0.05, 1, p3 * 0.9, 1, p3 * 0.05, 0
+ ioscillators = max(1, int(100 / active:i("playback")))
+
+ aout oscbank kfreq, 0.1, kfreqstepmult, random(0.9, 0.99), ioscillators, iwidth, iheight, icolour, ivariation * 2
+ aout *= aamp * 0.5
+ kpan linseg iystart, p3, iyend
+ aL, aR pan2 aout, kpan
+
+ outs aL, aR
+endin
+
+</CsInstruments>
+<CsScore>
+f0 36000
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/clipart/index.html b/site/app/clipart/index.html new file mode 100644 index 0000000..95db367 --- /dev/null +++ b/site/app/clipart/index.html @@ -0,0 +1,46 @@ +<html> + <head> + <style type="text/css"> + #start { + position: absolute; + left: 0px; + top: 0px; + height: 100%; + width: 100%; + background-color: #ffffff; + text-align: center; + cursor: pointer; + } + </style> + <script type="text/javascript" src="/code/jquery.js"></script> + <script type="text/javascript" src="/app/base/base.js"></script> + <script type="text/javascript" src="/code/svg.js"></script> + <script type="text/javascript" src="svgmess.js"></script> + <script type="text/javascript"> + $(function() { + window.svgmess = new SVGMess("svgimage"); + + window.app = new CSApplication({ + csdUrl: "clipart.csd", + onPlay: function () { + $("#start").hide(); + svgmess.run(); + }, + }); + + $("#start").click(function() { + $("#status").text("Loading..."); + app.play(); + }); + + }); + </script> + </head> + + <body> + <div id="start"> + <h1 id="status">Press to begin</h1> + </div> + <div id="svgimage"></div> + </body> +</html> diff --git a/site/app/clipart/svgmess.js b/site/app/clipart/svgmess.js new file mode 100644 index 0000000..261a21d --- /dev/null +++ b/site/app/clipart/svgmess.js @@ -0,0 +1,99 @@ +function randInt(min, max) {
+ min = Math.ceil(min);
+ max = Math.floor(max);
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+
+var SVGMess = function(target) {
+ var self = this;
+ var url = "https://data.1bpm.net/clipart/"
+ var animateTimeout;
+ var items;
+ var maxPointVariation = 0;
+ var maxWidth = 0;
+ var maxHeight = 0;
+ window.image = SVG().addTo("#" + target);
+
+ function stdcolour(str) {
+ var c = $("<canvas />");
+ var ctx = c[0].getContext("2d");
+ ctx.fillStyle = str;
+ var fill = ctx.fillStyle;
+ c.remove();
+ return fill;
+ }
+
+
+ function getMaxVar(item) {
+ var itemArray = item.array();
+ var maxVar = 0;
+ var vari;
+ for (let a of itemArray) {
+ vari = Math.abs(a[1] - a[0]);
+ if (vari > maxVar) maxVar = vari;
+ }
+ return maxVar;
+ }
+
+ async function load() {
+ var item;
+ var pathPart = window.location.href.substr(window.location.href.lastIndexOf("/"));
+ if (pathPart.indexOf("?") != -1) {
+ item = pathPart.substr(pathPart.indexOf("?") + 1);
+ } else {
+ var req = await fetch(url + "collection1/list.json");
+ var list = await req.json();
+ item = list.files[Math.floor(Math.random() * (list.files.length - 1)) - 1];
+ window.history.pushState("Image", "Image", window.location.href + "?" + item);
+ }
+ var data = await fetch(url + "collection1/" + item);
+ var src = await data.text();
+ image.svg(src);
+ image.size(3000, 4000);
+ items = image.find("polygon");
+
+ var vari, bbox;
+ for (let i of items) {
+ vari = getMaxVar(i);
+ bbox = i.bbox();
+ if (vari > maxPointVariation) maxPointVariation = vari;
+ if (bbox.w > maxWidth) maxWidth = bbox.w;
+ if (bbox.h > maxHeight) maxHeight = bbox.h;
+ }
+
+ self.items = items;
+ }
+
+ function animate() {
+ var posXmax = 300;
+ var posYmax = 300;
+ var item = items[Math.floor(Math.random() * (items.length - 1))];
+ var variation = getMaxVar(item) / maxPointVariation;
+ var fill = stdcolour(item.css().fill);
+ var bbox = item.bbox();
+ var colourRatio = Number("0x" + fill.substr(1)) / 16777215;
+ var duration = randInt(20, 500);
+ var posX = randInt(0, posXmax);
+ var posY = randInt(0, posYmax);
+ item.animate(duration, 0, "now")
+ .move(posX, posY)
+ //.rotate(randInt(1, 360)); //scale(2);
+ var timeout = randInt(20, 500);
+ animateTimeout = setTimeout(animate, timeout);
+ var args = [
+ 0, duration / 1000,
+ bbox.x / posXmax, bbox.y / posYmax,
+ posX / posXmax, posY / posYmax,
+ colourRatio, variation,
+ bbox.w / maxWidth, bbox.h / maxHeight
+ ];
+ app.insertScore("playback", args);
+ }
+
+ this.run = function() {
+ animate();
+ };
+
+ load();
+};
diff --git a/site/app/feedback/feedback.csd b/site/app/feedback/feedback.csd new file mode 100644 index 0000000..4a8a7f9 --- /dev/null +++ b/site/app/feedback/feedback.csd @@ -0,0 +1,195 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 16
+nchnls = 2
+0dbfs = 2
+seed 0
+
+
+#include "wavetables.udo"
+#include "frequency_tools.udo"
+
+gifbm_maxgain = 2
+
+opcode fbm_param, k, Sijjp
+ Sname, ichannel, imin, imax, iapplyportamento xin
+ Schannel = sprintf("%s_%d", Sname, ichannel)
+ krawval chnget Schannel
+ if (iapplyportamento == 1) then
+ kval port krawval, 0.005
+ else
+ kval = krawval
+ endif
+ SmodOnChannel = sprintf("%smodulating", Schannel)
+ kmodulating chnget SmodOnChannel
+ if (kmodulating == 1) then
+ kmodwave = chnget:k(sprintf("%smodwave", Schannel))
+ kmodfreq = chnget:k(sprintf("%smodfreq", Schannel))
+ kmodamp = chnget:k(sprintf("%smodamp", Schannel))
+ kmod = abs:k(oscilikt:k(kmodamp, kmodfreq, giwavetables[kmodwave]))
+ kout = kval + (kmod * (imax - imin))
+ else
+ kout = kval
+ endif
+/*
+ if (imin != -1) then
+ chnset imin, Schannel ; safe set channel to minimum
+ kout = max:k(kout, imin)
+ endif
+
+ if (imax != -1) then
+ kout = min:k(kout, imax)
+ endif
+*/
+ xout kout
+endop
+
+
+opcode fbm_fxinsert, a, aii
+ asig, ichanindex, insertindex xin
+ SchanAppend = sprintf("_%d_%d", ichanindex, insertindex)
+ keffect = chnget:k(strcat("insert", SchanAppend))
+ if (keffect == 1) then
+ asig freqshift1 asig, chnget:k(strcat("fs_freq", SchanAppend))
+ elseif (keffect == 2) then
+ asig ringmod1 asig, chnget:k(strcat("rm_freq", SchanAppend))
+ elseif (keffect == 3) then
+ asig nreverb asig, chnget:k(strcat("rv_time", SchanAppend)), 0.5
+ elseif (keffect == 4) then
+
+ elseif (keffect == 5) then
+
+ endif
+ xout asig
+endop
+
+
+opcode fbm_channel, aaaaa, ai
+ asig, ichannel xin
+ ieqgainadd = 4
+ keqh_gain = fbm_param("eqhighgain", ichannel, 0, gifbm_maxgain)
+ keqm_gain = fbm_param("eqmidgain", ichannel, 0, gifbm_maxgain)
+ keql_gain = fbm_param("eqlowgain", ichannel, 0, gifbm_maxgain)
+
+ keqh_freq = fbm_param("eqhighfreq", ichannel, 20, 18000)
+ keqm_freq = fbm_param("eqmidfreq", ichannel, 20, 18000)
+ keql_freq = fbm_param("eqlowfreq", ichannel, 20, 18000)
+
+ keqh_q = fbm_param("eqhighq", ichannel, 0.71, 0.9)
+ keqm_q = fbm_param("eqmidq", ichannel, 0.71, 0.9)
+ keql_q = fbm_param("eqlowq", ichannel, 0.71, 0.9)
+
+ ksend1 = fbm_param("send1", ichannel, 0, gifbm_maxgain, 0)
+ ksend2 = fbm_param("send2", ichannel, 0, gifbm_maxgain, 0)
+ ksend3 = fbm_param("send3", ichannel, 0, gifbm_maxgain, 0)
+ ksend4 = fbm_param("send4", ichannel, 0, gifbm_maxgain, 0)
+
+ kprefade1 = fbm_param("prefade1", ichannel, 0, 1, 0)
+ kprefade2 = fbm_param("prefade2", ichannel, 0, 1, 0)
+ kprefade3 = fbm_param("prefade3", ichannel, 0, 1, 0)
+ kprefade4 = fbm_param("prefade4", ichannel, 0, 1, 0)
+
+ klowcut = fbm_param("lowcut", ichannel, 0, 1, 0)
+ kmute = fbm_param("mute", ichannel, 0, 1, 0)
+ kvolume = fbm_param("volume", ichannel, 0, gifbm_maxgain)
+
+ asig dcblock asig
+ asig += noise(0.01, 0)
+ /*
+ asig pareq asig, keql_freq, keql_gain * ieqgainadd, keql_q, 1, 1
+ asig pareq asig, keqm_freq, keqm_gain * ieqgainadd, keqm_q, 0, 1
+ asig pareq asig, keqh_freq, keqh_gain * ieqgainadd, keqh_q, 2, 1
+ */
+ asig pareq asig, keql_freq, keql_gain * ieqgainadd, 0.7, 1
+ asig pareq asig, keqm_freq, keqm_gain * ieqgainadd, 0.7, 0
+ asig pareq asig, keqh_freq, keqh_gain * ieqgainadd, 0.7, 2
+ asig pareq asig, keqh_freq, keqh_gain * ieqgainadd, 0.7, 2
+
+ if (klowcut == 1) then
+ asig butterhp asig, 75
+ endif
+ asig butterlp asig, 17000
+ asig butterhp asig, 0.1
+
+ ;asig dam asig, 0.99, 0.9, 0.9, 0.01, 0.01
+
+ kvolume *= (1 - kmute)
+ asend1 = tanh(asig * ((kprefade1 == 1) ? ksend1 : ksend1 * kvolume))
+ asend2 = tanh(asig * ((kprefade2 == 1) ? ksend2 : ksend2 * kvolume))
+ asend3 = tanh(asig * ((kprefade3 == 1) ? ksend3 : ksend3 * kvolume))
+ asend4 = tanh(asig * ((kprefade4 == 1) ? ksend4 : ksend4 * kvolume))
+
+
+ asig fbm_fxinsert asig, ichannel, 0
+ asig fbm_fxinsert asig, ichannel, 1
+
+ asig tanh asig
+ asig *= kvolume
+ xout asig, asend1, asend2, asend3, asend4
+endop
+
+
+
+
+instr mixer
+ a1 init 0
+ a2 init 0
+ a3 init 0
+ a4 init 0
+
+ aout1, a1s1, a1s2, a1s3, a1s4 fbm_channel a1, 0
+ aout2, a2s1, a2s2, a2s3, a2s4 fbm_channel a2, 1
+ aout3, a3s1, a3s2, a3s3, a3s4 fbm_channel a3, 2
+ aout4, a4s1, a4s2, a4s3, a4s4 fbm_channel a4, 3
+ a1 = 0
+ a2 = 0
+ a3 = 0
+ a4 = 0
+
+ icrosstalk = 0.0001
+
+ a1 = a1s1 + a2s1 + a3s1 + a4s1
+ a2 = a1s2 + a2s2 + a3s2 + a4s2
+ a3 = a1s3 + a2s3 + a3s3 + a4s3
+ a4 = a1s4 + a2s4 + a3s4 + a4s4
+
+ a1 = a1 + (a2 * icrosstalk)
+ a2 = a2 + (a1 * icrosstalk) + (a3 * icrosstalk)
+ a3 = a3 + (a3 * icrosstalk) + (a4 * icrosstalk)
+ a4 = a4 + (a3 * icrosstalk)
+ aout = aout1 + aout2 + aout3 + aout4
+ aout tanh aout
+ aout pareq aout, 18000, 0.4, 0.7
+ aout dcblock aout * 0.25
+ aout butterlp aout, 17000
+ aout limit aout, -1, 1
+ outs aout, aout
+
+#ifndef WEB
+ chnset 0.01, "eqhighgain_0"
+ chnset 10000, "eqhighfreq_0"
+ chnset 0.71, "eqhighq_0"
+
+ chnset 3.7, "eqmidgain_0"
+ chnset 1100, "eqmidfreq_0"
+ chnset 0.71, "eqmidq_0"
+
+ chnset 6.4, "eqlowgain_0"
+ chnset 550, "eqlowfreq_0"
+ chnset 0.71, "eqlowq_0"
+
+ chnset 1, "prefade1_0"
+ chnset 1.1, "send1_0"
+ chnset 1.1, "volume_0"
+#end
+endin
+
+</CsInstruments>
+<CsScore>
+i"mixer" 0 36000
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/feedback/index.html b/site/app/feedback/index.html new file mode 100644 index 0000000..978b8b7 --- /dev/null +++ b/site/app/feedback/index.html @@ -0,0 +1,496 @@ +<html> + <head> + <script type="text/javascript" src="/code/jquery.js"></script> + <script type="text/javascript" src="../base/base.js"></script> + <script type="text/javascript" src="/code/input-knobs.js"></script> + <style type="text/css"> + body { + font-family: Sans-serif, arial; + font-size: 8pt; + background-color: #989898; + } + + td { + font-size: 8pt; + } + + .controlLabel { + font-size: 8pt; + text-align: center; + width: 100%; + } + + .controlValue { + font-size: 7pt; + text-align: center; + width: 100%; + } + + table { + border-spacing: 0; + } + + .innertd { + border-left: 1px solid #787878; + padding: 1px; + } + + .chantd { + border-left: 2px solid #454545; + padding: 1px; + } + + .smbutton { + font-size: 7pt; + border: none; + padding: 1px; + } + + #buttons { + position: absolute; + top: 0px; + left: 0px; + height: 5%; + width: 80%; + } + + #target { + position: absolute; + top: 5%; + left: 0px; + width: 80%; + height: 95px; + } + + #modulation { + position: absolute; + top: 0%; + left: 70%; + width: 30%; + padding: 10px; + height: 100%; + border-left: 1px solid black; + } + + #modulatehelp { + display: none; + } + + #begin { + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + background-color: #b5b5b5; + cursor: pointer; + z-index: 10; + } + + #begininner { + position: absolute; + text-align: center; + top: 20%; + left: 20%; + width: 60%; + font-size: 11pt; + } + + #loading { + position: fixed; + left: 0px; + top: 0px; + width: 100%; + height: 100%; + background-color: #b5b5b5; + cursor: pointer; + display: none; + z-index: 11; + } + + #loadinginner { + position: absolute; + text-align: center; + top: 20%; + left: 20%; + width: 60%; + font-size: 24pt; + } + + + </style> + <script type="text/javascript"> + var baseurl = "/controls/"; + var maxGain = 2; + var controls = []; + + function resetControls() { + for (let cn of controls) { + var c = cn.control; + var val = cn.dfault; + if (val) { + if (c.attr("type") == "checkbox") { + c.prop("checked", (val == 1)); + } else { + c.val(val); + } + } + c.trigger("change"); + } + } + + function randomiseControls() { + for (let cn of controls) { + var c = cn.control; + var min = parseFloat(c.attr("min")); + var max = parseFloat(c.attr("max")); + var step = parseFloat(c.attr("step")); + var val = (Math.random() * (max - min)) + min; + if (val % step != 0) { + if (step == 1) { + val = Math.round(val); + } else { + val = Math.ceil((val - min) / step) * step + min; + } + } + if (c.attr("type") == "checkbox") { + c.prop("checked", (val == 1)); + } else { + c.val(val); + } + c.trigger("change"); + } + } + + var randomiseTimeout; + var randomising = false; + function randomiseContinuous() { + var text; + if (randomising) { + randomising = false; + text = "Continuous random"; + clearTimeout(randomiseTimeout); + } else { + randomising = true; + text = "Stop"; + function doRandom() { + randomiseControls(); + if (randomising) { + setTimeout(doRandom, Math.round(Math.random() * 700) + 50); + } + } + doRandom(); + } + $("#randomiseContinuous").text(text); + } + + async function makeRow(rowdef) { + var row = $("<tr />"); + var showName = true; + for (let chan = 0; chan < 4; chan++) { // channel + var initial = true; + var showBorder = true; + var sectionName = null; + for (let def of rowdef) { + let elValue; + var className; + + if (!showName && initial) { + initial = false; + continue; + } + + if (showName) { + sectionName = def; + initial = false; + showName = false; + } + + if (showBorder) { + className = "chantd"; + showBorder = false; + } else { + className = "innertd"; + } + + var el = $("<td />").appendTo(row).addClass(className); + if (!def) continue; + + if (typeof(def) == "string") { + el.text(def); + } else { + var control = await getControl(def.control); + el.append(control); + var name = "Channel " + (chan + 1) + " " + ((sectionName) ? sectionName + " " : "") + def.name; + var dfault = (def.dfault) ? def.dfault: 0; + var min = (def.min) ? def.min: 0; + var max = (def.max) ? def.max: 1; + var step = (def.step) ? def.step: 0.000001; + controls.push({name: name, control: control, channel: def.channel + "_" + chan, dfault: dfault}); + + setTimeout(function() { + app.setControlChannel(def.channel + "_" + chan, (def.dfault) ? def.dfault: 0); + }, 100); + if (def.size) { + el.width(def.size).height(def.size); + } + + if (def.type && def.type == "button") { + step = 1; + } + + function updateControl() { + var val; + if ($(this).attr("type") == "checkbox") { + val = ($(this).is(":checked")) ? 1 : 0; + } else { + val = $(this).val(); + } + app.setControlChannel(def.channel + "_" + chan, val); + if (elValue) { + elValue.text(Math.round(val * 100) / 100); + } + } + + control.attr("step", step).attr("min", min).attr("max", max).val(dfault).on("input", updateControl).change(updateControl); + if (def.name && !def.noLabel) { + var elLabel = $("<div />").addClass("controlLabel").text(def.name); + el.append(elLabel); + } + if (!def.noValue) { + elValue = $("<div />").addClass("controlValue").text(dfault); + el.append(elValue); + } + } + } + } + return row; + } + + var modulationParameters = [ + {name: "Wave", channel: "modwave", options: ["Sine", "Square", "Saw", "Pulse", "Cosine", "Triangle"], dfault: 0}, + {name: "Frequency", channel: "modfreq", dfault: 1, min: 0.01, max: 10, step: 0.01}, + {name: "Amplitude", channel: "modamp", dfault: 1, min: 0, max: 1, step: 0.000001} + ]; + + + modulations = []; + + function createModulation(c) { + var tbl = $("<table />").css("width", "100%"); + var tb = $("<tbody />").appendTo(tbl); + var el = $("<div />").appendTo($("#modulationsData")); + var offButton = $("<button />").text("Remove").click(function() { + delete modulations[modulations.indexOf(c)]; + el.remove(); + app.setControlChannel(c.channel + "modulating", 0); + }); + app.setControlChannel(c.channel + "modulating", 1); + + el.append($("<hr />")).append(c.name).append(tbl).append(offButton); + var dfault; + for (let m of modulationParameters) { + var tr = $("<tr />").appendTo(tb); + tr.append($("<td />").text(m.name)); + var elInput; + if (m.options) { + elInput = $("<select />").change(function() { + app.setControlChannel(c.channel + m.channel, $(this).val()); + }); + for (var i in m.options) { + elInput.append($("<option />").text(m.options[i]).val(i)); + } + + dfault = (m.dfault) ? m.dfault : 0; + elInput.val(dfault).trigger("change"); + } else { + elInput = $("<input />").attr("type", "range").attr("min", m.min).attr("max", m.max).attr("step", m.step).val(m.dfault).on("input", function() { + app.setControlChannel(c.channel + m.channel, $(this).val()); + }); + elInput.trigger("input"); + dfault = m.dfault; + } + app.setControlChannel(c.channel + m.channel, dfault); + + $("<td />").append(elInput).appendTo(tr); + + } + } + + + var modulationsShown = false; + function modulateControls() { + var elBut = $("#modulate"); + var elHelp = $("#modulatehelp"); + + function done() { + elBut.text("Add new"); + elHelp.hide(); + modulationsShown = false; + for (let c of controls) { + c.control.css("opacity", 1).off("click").off("touchstart"); + } + } + + if (modulationsShown) { + done(); + } else { + elHelp.show(); + elBut.text("Exit assignment"); + modulationsShown = true; + for (let c of controls) { + function onSelect() { + if (!modulations.includes(c)) { + modulations.push(c); + done(); + createModulation(c); + } + } + c.control.css("opacity", 0.2).click(onSelect).on("touchstart", onSelect); + } + } + + } + + + async function makeTable() { + var tb = $("<tbody />").appendTo($("<table />").addClass("mainTable").appendTo($("#target"))); + var def = [ + ["EQ high", + {name: "Gain", channel: "eqhighgain", control: "timb_SM2018_SM_CUTE32-1", dfault: 0.7, min: 0.1, max: 1.1}, + {name: "Frequency", channel: "eqhighfreq", control: "timb_SM2018_SM_CUTE32-1", dfault: 12000, step: 1, min: 6000, max: 20000}, + {name: "Q", channel: "eqhighq", control: "timb_SM2018_SM_CUTE32-1", dfault: 0.71, min: 0.71, max: 0.9} + ], + ["EQ mid", + {name: "Gain", channel: "eqmidgain", control: "timb_SM2018_SM_CUTE32-1", dfault: 1, min: 0.01, max: maxGain}, + {name: "Frequency", channel: "eqmidfreq", control: "timb_SM2018_SM_CUTE32-1", dfault: 2000, step: 1, min: 800, max: 6000}, + {name: "Q", channel: "eqmidq", control: "timb_SM2018_SM_CUTE32-1", dfault: 0.71, min: 0.71, max: 0.9} + ], + ["EQ low", + {name: "Gain", channel: "eqlowgain", control: "timb_SM2018_SM_CUTE32-1", dfault: 1, min: 0.01, max: maxGain}, + {name: "Frequency", channel: "eqlowfreq", control: "timb_SM2018_SM_CUTE32-1", dfault: 200, step: 1, min: 50, max: 800}, + {name: "Q", channel: "eqlowq", control: "timb_SM2018_SM_CUTE32-1", dfault: 0.71, min: 0.71, max: 0.9} + ], + ["Prefade", + {name: "1", channel: "prefade1", control: "Timb_Grig2018_Controls--61b", type: "button", size: 12, noValue: true, noLabel: true}, + {name: "2", channel: "prefade2", control: "Timb_Grig2018_Controls--61b", type: "button", size: 12, noValue: true, noLabel: true}, + null + ], + ["Send", + {name: "1", channel: "send1", control: "timb_SM2018_SM_CUTE32-4", max: maxGain}, + {name: "2", channel: "send2", control: "timb_SM2018_SM_CUTE32-4", max: maxGain}, + null + ], + ["Prefade", + {name: "3", channel: "prefade3", control: "Timb_Grig2018_Controls--61b", type: "button", size: 12, noValue: true, noLabel: true}, + {name: "4", channel: "prefade4", control: "Timb_Grig2018_Controls--61b", type: "button", size: 12, noValue: true, noLabel: true}, + null + ], + ["Send", + {name: "3", channel: "send3", control: "timb_SM2018_SM_CUTE32-4", max: maxGain}, + {name: "4", channel: "send4", control: "timb_SM2018_SM_CUTE32-4", max: maxGain}, + null + ], + [null, + {name: "Mute", channel: "mute", control: "timb&HYRPEMUTE32", type: "button", noValue: true}, + {name: "Low cut", channel: "lowcut", control: "Timb_Grig2018_Controls--61b", type: "button", noValue: true}, + null + ], + [null, + null, + {name: "Volume", channel: "volume", control: "lbx_slider160_smoothblack_red_km", max: maxGain}, + null + ] + ]; + + + for (let d of def) { + var row = await makeRow(d); + tb.append(row); + }; + } + + + async function appendRandomControl() { + var all = await fetch("/controls/all.json"); + var json = await all.json(); + var item = json[Object.keys(json)[Math.round(Math.random() * (Object.keys(json).length - 1))]]; + var ctrl = await getControl(item); + $("#target").append(ctrl); + } + + async function getControl(name) { + if (typeof(name) == "string") { + var response = await fetch(baseurl + name + ".json"); + var json = await response.json(); + } else { + json = name; // for randomControl + } + + var element; + if (json.ctltype == 0) { + element = $("<input />").attr("type", "range").addClass("input-knob").attr("data-diameter", json.cellh).attr("data-src", baseurl + json.fn).attr("data-sprites", json.frames - 1); + } else if (json.ctltype == 1) { + element = $("<input />").attr("type", "range").addClass("input-slider").attr("data-height", json.cellh).attr("data-src", baseurl + json.fn).attr("data-width", json.cellw).attr("data-sprites", json.frames - 1); + } else if (json.ctltype == 2) { + element = $("<input />").attr("type", "checkbox").addClass("input-switch").attr("data-height", json.cellh).attr("data-width", json.cellw).attr("data-src", baseurl + json.fn); + } + return element; + } + + $(function(){ + makeTable(); + + + window.app = new CSApplication({ + csdUrl: "feedback.csd", + onPlay: function () { + $("#loading").hide(); + randomiseControls(); + resetControls(); + } + }); + + $("#randomise").click(randomiseControls); + $("#randomiseContinuous").click(randomiseContinuous); + $("#reset").click(resetControls); + $("#modulate").click(modulateControls); + + $("#begin").click(function() { + $("#begin").hide(); + $("#loading").show(); + app.play(); + }); + }); + </script> + </head> + <body> + <div id="begin"> + <div id="begininner"> + <h3>Feedback mixer simulation</h3> + <p>This application models a four channel audio mixer in a fed-back state. Often known as a 'no-input' mixer, + eccentric sounds can be induced from altering EQ and gain in the channel paths.<br /> + In this model, there are four auxilliary sends on each channel, which send input to the corresponding channel.<br /> + For example, increasing aux 1 on channel 1 will eventually lead to feedback. The randomise buttons at the top can + be used for quick shortcuts for creating sound, and using the modulations pane on the left allows any parameter to be modulated with a LFO. + </p> + <h2>Press to begin</h2> + </div> + </div> + <div id="loading"><div id="loadinginner">Loading audio engine</div></div> + <div id="buttons"> + <table><tbody><tr> + <td><button id="randomise">Randomise</button></td> + <td><button id="randomiseContinuous">Continuous random</button></td> + <!--<td><button id="reset">Reset</button></td>--> + </tr></tbody></table> + </div> + <div id="target"></div> + <div id="modulation"> + <h3>Modulations</h3> + <td><button id="modulate">Add new</button></td> + <div id="modulatehelp">Click on a parameter to enable modulation</div> + <div id="modulationsData"></div> + </div> + </body> +</html> diff --git a/site/app/ocsillator/index.html b/site/app/ocsillator/index.html new file mode 100644 index 0000000..f115bcc --- /dev/null +++ b/site/app/ocsillator/index.html @@ -0,0 +1,319 @@ +<html>
+<head>
+<script type="text/javascript" src="/code/jquery.js"></script>
+<script type="text/javascript" src="../base/base.js"></script>
+<script type="text/javascript">
+var appdata = {
+"instruments": [
+ {name: "Effemm bass", instr: "ocsinst_blockbass"},
+ {name: "Three Oh", instr: "ocsinst_303"},
+ {name: "Strung", instr: "ocsinst_strings"},
+ {name: "Harm", instr: "ocsinst_guitarharmonics"},
+ {name: "Cold nights", instr: "ocsinst_guitarharmonicsfx"},
+ {name: "Rhedos", instr: "ocsinst_rhodes1"},
+ {name: "Evolo", instr: "oscinst_pad1"},
+ {name: "Kaleb", instr: "oscinst_kalimba1"},
+ {name: "Freakperk", instr: "ocsinst_perc_freak", nvalue: true},
+ {name: "Canne", instr: "ocsinst_perc_case", nvalue: true},
+]};
+
+var Ocsillator = function(appdata) {
+ var elContainer = $("#main");
+ var elControls = $("#controls");
+ var elXy = $("#xy").css("background-color", "#121212");
+ var elNoteSelect = $("<select />").change(changeScale);
+ var elChordSelect = $("<select />").change(changeScale);
+ var elNoteRange = $("<input />").attr("type", "range").attr("min", 2).attr("max", 24).change(changeScale);
+ var elInstrumentSelect = $("<select />").change(changeInstrument);
+ var elDownload = $("<button />").text("Download").click(downloadFile);
+ var elRecord = $("<button />").text("Record").click(downloadFile);
+ var elPosition = $("<div />").css({width: "30px", height: "30px", "border-radius": "15px", "background-color": "#f5dd42", position: "absolute"}).hide();
+ var normaliseValue = false;
+ var notedata;
+ var uiNotes = [];
+ var mouseisdown;
+
+ function mousedown(e) {
+ mouseisdown = true;
+ elPosition.show();
+ handlePosition(e);
+ playInstrument();
+ }
+
+ function mousemove(e) {
+ if (!mouseisdown) return;
+ handlePosition(e);
+ }
+
+ function mouseup() {
+ mouseisdown = false;
+ elPosition.hide();
+ stopInstrument();
+ }
+
+ elXy.on("mousedown", mousedown).on("mousemove", mousemove).on("mouseup", mouseup).on("touchstart", function(e) {
+ mousedown(e.changedTouches[0]);
+ }).on("touchmove", function(e) {
+ mousemove(e.changedTouches[0]);
+ }).on("touchend", mouseup);
+
+ function handlePosition(e) {
+ var offs = elXy.offset();
+ var h = elXy.height();
+ var w = elXy.width();
+ var posX = e.clientX - offs.left;
+ var posY = e.clientY - offs.top;
+ if (posX < 0 || posX > w || posY < 0 || posY > h) return;
+ elPosition.css({left: (posX - 15) + "px", top: (posY - 15) + "px"});
+
+ var valX = posX / w;
+ var valY = 1 - (posY / h);
+
+ if (!normaliseValue) {
+ var note = uiNotes[Math.floor(valX * uiNotes.length)];
+ app.setControlChannel("note", note);
+ } else {
+ app.setControlChannel("valX", valX);
+ }
+ app.setControlChannel("valY", valY);
+ }
+
+ fetch("../base/notedata.json").then(function(r) {
+ r.json().then(function(j) {
+ notedata = j;
+ buildInputs();
+ });
+ });
+
+ function buildInputs() {
+ for (let n of notedata.notes) {
+ if (n[0] >= 24 && n[0] <= 84) {
+ $("<option />").val(n[0]).text(n[1]).appendTo(elNoteSelect);
+ }
+ }
+
+ for (let c in notedata.chords) {
+ $("<option />").val(c).text(notedata.chords[c].name).appendTo(elChordSelect);
+ }
+
+ for (let i in appdata.instruments) {
+ $("<option />").val(i).text(appdata.instruments[i].name).appendTo(elInstrumentSelect);
+ }
+
+ var tb = $("<tbody />").appendTo($("<table />").appendTo(elControls));
+ var tr = $("<tr />").appendTo(tb);
+ $("<td />").text("Base note").appendTo(tr);
+ $("<td />").text("Chord").appendTo(tr);
+ $("<td />").text("Note range").appendTo(tr);
+ $("<td />").text("Instrument").appendTo(tr);
+ $("<td />").appendTo(tr);
+
+ tr = $("<tr />").appendTo(tb);
+ $("<td />").append(elNoteSelect).appendTo(tr);
+ $("<td />").append(elChordSelect).appendTo(tr);
+ $("<td />").append(elNoteRange).appendTo(tr);
+ $("<td />").append(elInstrumentSelect).appendTo(tr);
+ $("<td />").append(elDownload).appendTo(tr);
+
+ elInstrumentSelect.trigger("change");
+ elNoteSelect.val(48);
+ elChordSelect.val(0);
+ elNoteRange.val(12);
+ changeScale();
+ }
+
+
+ function downloadFile() {
+
+ }
+
+ function recordStart() {
+ app.insertScore("ocsi_recordstart");
+ }
+
+ function recordStop() {
+ app.insertScore("ocsi_recordstop");
+ }
+
+ function recordClear() {
+ app.insertScore("ocsi_recordclear");
+ }
+
+ function changeInstrument() {
+ var instrument = appdata.instruments[elInstrumentSelect.val()];
+ if (instrument.nvalue) {
+ normaliseValue = instrument.nvalue;
+ } else {
+ normaliseValue = false;
+ }
+ app.insertScore("ocsi_setinstrument", [0, 1, instrument.instr]);
+ }
+
+
+ function playInstrument() {
+ app.insertScore("ocsi_play");
+ }
+
+ function stopInstrument() {
+ app.insertScore("ocsi_stop");
+ }
+
+ function changeScale() {
+ var noterange = elNoteRange.val();
+ var notenum = elNoteSelect.val();
+ var intervals = notedata.chords[elChordSelect.val()].intervals;
+ var intervalindex = 0;
+ var octave = 0;
+ var notes = [];
+ var note;
+ for (var i = 0; i < noterange; i++) {
+ note = parseInt(notenum) + (octave * 12) + parseInt(intervals[intervalindex]);
+ if (intervalindex < intervals.length - 1) {
+ intervalindex += 1;
+ } else {
+ intervalindex = 0;
+ octave += 1;
+ }
+ notes.push(note);
+ }
+ uiNotes = notes;
+ redraw();
+ }
+
+
+ function redraw() {
+ var w = window.innerWidth;
+ var h = window.innerHeight;
+ var size = Math.min(w, h);
+ elContainer.css({width: w, height: h});
+ var ch = Math.round(size * 0.1);
+ var xys = Math.round(size * 0.9);
+ elControls.css({width: w + "px", height: ch + "px"});
+ elXy.empty().css({width: xys + "px", height: xys + "px", top: ch + "px"}).append(elPosition);
+
+ var step = Math.round(xys / uiNotes.length);
+ for (var x = 0; x < xys; x += step) {
+ $("<div />").addClass("gridline").css({left: x + "px", height: xys + "px"}).appendTo(elXy);
+ }
+ }
+
+
+ window.onresize = redraw;
+};
+
+$(function() {
+ window.app = new CSApplication({
+ csdUrl: "ocsillator.csd",
+ onPlay: function () {
+ $("#loading").hide();
+ window.osc = new Ocsillator(appdata);
+ }
+ });
+ $("#begin").click(function() {
+ $("#begin").hide();
+ app.play();
+ });
+
+});
+
+</script>
+<style type="text/css">
+ body {
+ font-family: Arial, sans-serif;
+ user-select: none;
+ background-color: #a1a1a1;
+ }
+
+ .gridline {
+ width: 1px;
+ height: 1px;
+ position: absolute;
+ background-color: #33aa33;
+ z-index: 10;
+ }
+
+ #loading {
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ z-index: 20;
+ background-color: #344534;
+ }
+
+ #loading_inner {
+ left: 30%;
+ top: 30%;
+ width: 40%;
+ height: 40%;
+ text-align: center;
+ font-size: 48pt;
+ position: absolute
+
+ }
+
+ #begin {
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ z-index: 25;
+ text-align: center;
+ background-color: #344534;
+ cursor: pointer;
+ }
+
+ #begin_inner {
+ left: 30%;
+ top: 30%;
+ width: 40%;
+ height: 40%;
+ text-align: center;
+ font-size: 48pt;
+ position: absolute
+
+ }
+
+ #main {
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ }
+
+ #controls {
+ width: 100%;
+ height: 20%;
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ }
+
+ #xy {
+ position: absolute;
+ width: 80%;
+ height: 80%;
+ top: 20%;
+ left: 0px;
+ z-index: 1;
+ }
+
+</style>
+</head>
+<body>
+ <div id="loading">
+ <div id="loading_inner">Loading</div>
+ </div>
+ <div id="begin">
+ Ocsillator is inspired by the Korg Kaossilator.
+ <div id="begin_inner">Press to begin</div>
+ </div>
+ <div id="main">
+ <div id="controls"></div>
+ <div id="xy"></div>
+ </div>
+</body>
+</html>
diff --git a/site/app/ocsillator/ocsillator.csd b/site/app/ocsillator/ocsillator.csd new file mode 100644 index 0000000..4ad464b --- /dev/null +++ b/site/app/ocsillator/ocsillator.csd @@ -0,0 +1,183 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 16
+nchnls = 2
+nchnls_i = 1
+0dbfs = 2
+seed 0
+
+#include "interop.udo"
+#include "bussing.udo"
+#include "synth_instruments.udo"
+#include "synth_drums.udo"
+#include "sounddb.udo"
+#include "wavetables.udo"
+
+giocsicol_harmonics sounddb_getcollectionid "Guitar.Harmonics", 1
+
+isize = sr * 60
+giocsi_fnrecord[] fillarray ftgen(0, 0, isize, 2, 0), ftgen(0, 0, isize, 2, 0)
+giosci_loopend = isize
+giocsi_instrument = 0
+
+instr ocsi_recordstart
+ p3 = 99999
+ aL, aR bus_tap "ocsi"
+ apos lphasor 1, 0, giosci_loopend, 1
+ tablew aL, apos, giocsi_fnrecord[0]
+ tablew aR, apos, giocsi_fnrecord[1]
+endin
+
+instr ocsi_recordstop
+ turnoff2 "ocsi_recordstart", 0, 1
+ turnoff
+endin
+
+instr ocsi_recordclear
+
+endin
+
+
+opcode ocsi_defaultinput, kk, 0
+ kamp chnget "valY"
+ knote chnget "note"
+ xout kamp, knote
+endop
+
+instr ocsinst_blockbass
+ kamp, knote ocsi_defaultinput
+ aL, aR synth_fmbass1, cpsmidinn(knote) - 12
+ kenv linsegr 1, p3, 1, 0.2, 0
+ aL *= kenv * kamp
+ aR *= kenv * kamp
+ bus_mix("ocsi", aL, aR)
+endin
+
+
+instr ocsinst_303
+ ky, knote ocsi_defaultinput
+ ifilter = (chnget:i("valY") * 50) + 50
+ kdistortion = (1 - ky) + 1
+ aout synth_303 cpsmidinn(knote), ifilter, kdistortion
+ kenv linsegr 1, p3, 1, 0.2, 0
+ aout *= kenv
+ bus_mix("ocsi", aout, aout)
+endin
+
+instr ocsinst_strings
+ ky, knote ocsi_defaultinput
+ kfreq = cpsmidinn(knote)
+ aL synth_strings1 kfreq, 0.01 * random(0.5, 1.5) * ky * 4, 6 * random(0.5, 1.5) * ky, 0.1 * random(0.5, 1.5), 0.1 * random(0.5, 1.5)
+ aR synth_strings1 kfreq, 0.01 * random(0.5, 1.5) * ky * 4, 6 * random(0.5, 1.5) * ky, 0.1 * random(0.5, 1.5), 0.1 * random(0.5, 1.5)
+ kenv linsegr 1, p3, 1, 0.2, 0
+ aL *= kenv
+ aR *= kenv
+ bus_mix("ocsi", aL, aR)
+endin
+
+
+instr ocsinst_guitarharmonics
+ ky, knote ocsi_defaultinput
+ istartnote = chnget:i("note")
+ knote init istartnote
+ ifileid, ipitchratio sounddb_mel_nearestnote giocsicol_harmonics, chnget:i("note")
+ ifn, ichannels, iduration, irmsnorm sounddb_get ifileid
+ ipitchadjust = ipitchratio* (ftsr(ifn) / sr)
+ kpitch = (cpsmidinn(knote) / cpsmidinn(istartnote)) * ipitchadjust
+ krate = (ky * 10) + 1
+ apos = a(ky) * iduration;abs:k(oscil:k(iduration * 0.5, krate)) + (iduration * 0.1)
+ aL, aR sndwarpst 1, apos, a(port(kpitch, 0.01, ipitchadjust)), ifn, 0, 4410, 441, 4, gifnHanning, 1
+ kenv linsegr 0, 0.1, 1, p3 - 0.1, 1, 0.2, 0
+ aL *= kenv
+ aR *= kenv
+ bus_mix("ocsi", aL, aR)
+endin
+
+
+instr ocsinst_guitarharmonicsfx
+ ky, knote ocsi_defaultinput
+ istartnote = chnget:i("note")
+ knote init istartnote
+ ifileid, ipitchratio sounddb_mel_nearestnote giocsicol_harmonics, chnget:i("note")
+ ifn, ichannels, iduration, irmsnorm sounddb_get ifileid
+ ipitchadjust = ipitchratio * (ftsr(ifn) / sr)
+ kpitch = (cpsmidinn(knote) / cpsmidinn(istartnote)) * ipitchadjust
+ krate = (ky * 10) + 1
+ apos = ((a(ky) * abs:k(oscil:k(random(0.2, 1), random(2, 10)))) + 0.1) * iduration
+ aL, aR sndwarpst 1, apos, a(port(kpitch * 0.5, 0.01, ipitchadjust)), ifn, 0, 4410, 441, 1, gifnHanning, 1
+
+ ahL1, ahL2 hilbert2 aL, 1024, 256
+ amL, afmL fmanal ahL1, ahL2
+ aL oscil amL, afmL * 2
+
+ ahR1, ahR2 hilbert2 aR, 1024, 256
+ amR, afmR fmanal ahR1, ahL2
+ aR oscil amR, afmR * 2
+
+ aL butterhp aL, 500
+ aR butterhp aR, 500
+ ;aL reverb aL, 2 * (ky + 2)
+ ;aR reverb aR, 2 * (ky + 2)
+ aL tanh aL
+ aR tanh aR
+
+ kenv linsegr 1, p3 - 0.1, 1, 0.2, 0
+ aL *= kenv
+ aR *= kenv
+ bus_mix("ocsi", aL, aR)
+endin
+
+
+instr osci_recordplaystart
+ p3 = -1
+ apos lphasor 1, 0, giosci_loopend, 1
+ aL table3 apos, giocsi_fnrecord[0]
+ aR table3 apos, giocsi_fnrecord[1]
+ bus_mix("bufferplay", aL, aR)
+endin
+
+instr osci_recordplaystop
+ turnoff2 "osci_recordplaystart", 0, 1
+ turnoff
+endin
+
+instr ocsi_setinstrument
+ Sinstr = strget(p4)
+ turnoff2 giocsi_instrument, 0, 1
+ giocsi_instrument = nstrnum(Sinstr)
+ turnoff
+endin
+
+instr ocsi_play
+ schedule giocsi_instrument, 0, 99999
+ turnoff
+endin
+
+instr ocsi_stop
+ turnoff2 giocsi_instrument, 0, 1
+ turnoff
+endin
+
+instr ocsi_mixer
+ aLm, aRm bus_read "ocsi"
+ aLb, aRb bus_read "bufferplay"
+
+ aL = aLm + aLb
+ aR = aRm + aRb
+ outs aL, aR
+endin
+
+instr osci_boot
+ schedule "ocsi_mixer", 0, -1
+endin
+
+</CsInstruments>
+<CsScore>
+f0 z
+i"osci_boot" 0 1
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/partialemergence/effects_global.inc b/site/app/partialemergence/effects_global.inc new file mode 100644 index 0000000..c765743 --- /dev/null +++ b/site/app/partialemergence/effects_global.inc @@ -0,0 +1,150 @@ +#ifndef INC_GLOBALEFFECTS_INSTR
+#define INC_GLOBALEFFECTS_INSTR ##
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence
+ by Richard Knight 2022
+
+ Installation submission for the International Csound Conference 2022
+
+ Global effects
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/*
+ Reverb
+*/
+instr global_reverb1
+ aL, aR bus_read "reverb1"
+ aL, aR freeverb aL, aR, 0.8, 0.6
+ bus_mix("master", aL, aR)
+endin
+
+
+/*
+ Delay 1
+*/
+instr global_delay1
+ aL, aR bus_read "delay1"
+ ;aL *= abs(oscil(1, 1))
+ ;aR *= abs(oscil(1, 1))
+ kfeedback = abs:k(oscil:k(0.5, 4)) + 0.2
+
+ aLdlr delayr 0.8
+ kdeltime = abs(oscil(0.02, 0.04)) + 0.1
+ aLdel deltapi kdeltime + 0.002
+ delayw aL + (aLdel * kfeedback)
+ aRdlr delayr 0.8
+ aRdel deltapi kdeltime + 0.001
+ delayw aR + (aRdel * kfeedback)
+ bus_mix("master", aLdel, aRdel)
+endin
+
+
+/*
+ Delay 2
+*/
+instr global_delay2
+ aL, aR bus_read "delay2"
+ ifreq1 = 0.25
+ kfdbkL = abs(oscil(0.8, 1.63))
+ kfdbkR = abs(oscil(0.8, 1.67))
+
+ atimeL = abs(oscil(0.2, ifreq1)) + 0.01
+ atimeR = abs(oscil(0.2, ifreq1)) + 0.01
+
+ aLdlr delayr 1
+ aLdel deltapi atimeL
+ aLdel butterhp aLdel, 130
+ delayw aL + (aLdel * kfdbkL)
+
+ aRdlr delayr 1
+ aRdel deltapi atimeR
+ aRdel butterhp aRdel, 130
+ delayw aR + (aRdel * kfdbkR)
+
+ bus_mix("master", aLdel, aRdel)
+endin
+
+
+
+/*
+ Cyclical PVS sampler
+*/
+instr global_pvsamp1
+ aL, aR bus_read "pvsamp1"
+ ir = 512
+ iscales[] fillarray 0.25, 0.5, 1, 2, 4
+ ksampling init 1
+ ktime = timeinsts()
+ ksamplestarttime init 0
+ kplaystarttime init 0
+ imaxlength = 6
+ ksamplelength init random(2, imaxlength)
+ kplaylength init random(2, imaxlength)
+ krevsend init random(0, 0.4)
+ kdotune init (random(0, 1) > 0.8) ? 1 : 0
+ kdohpf init round(random(0, 1))
+ khpfreq init random(100, 2000)
+ kreadrate init random(0.005, 0.3)
+ kscale init iscales[round(random(0, lenarray(iscales) - 1))]
+
+ if (ksampling == 1) then
+ fL1 pvsanal aL, ir, ir/4, ir, 1
+ fR1 pvsanal aR, ir, ir/4, ir, 1
+
+ ibufL, ktL pvsbuffer fL1, imaxlength
+ ibufR, ktR pvsbuffer fR1, imaxlength
+
+ if (ktime - ksamplestarttime >= ksamplelength) then
+ ksampling = 0
+ kplaylength = random:k(2, imaxlength*0.9)
+ kplaystarttime = ktime
+ kdohpf = round:k(random:k(0, 1))
+ khpfreq = random:k(100, 2000)
+ kdotune = (random:k(0, 1) > 0.8) ? 1 : 0
+ krevsend = random:k(0, 0.6)
+ kreadrate = random:k(0.005, 0.3)
+ if (random:k(0, 1) >= 0.7) then
+ kscale = iscales[round:k(random:k(0, lenarray(iscales) - 1))]
+ endif
+ endif
+ endif
+
+ if (ksampling == 0 && ktime - kplaystarttime >= kplaylength) then
+ ksampling = 1
+ ksamplestarttime = ktime
+ ksamplelength = random:k(2, imaxlength)
+ endif
+
+ ktime = abs:k(oscil:k(1, kreadrate))
+
+ kplaylengthp = port(kplaylength, 0.1)
+ fL2 pvsbufread ktime*kplaylengthp, ibufL
+ fR2 pvsbufread ktime*kplaylengthp, ibufR
+
+ kscalep = port(kscale, 0.1)
+ fL3 pvscale fL2, kscalep
+ fR3 pvscale fR2, kscalep
+
+ aL pvsynth fL3
+ aR pvsynth fR3
+
+ if (kdotune == 1) then
+ aL, aR mel_tune_portamento aL*0.8, aR*0.8, gifnSine, 16, 1024, 4
+ endif
+
+ if (kdohpf == 1) then
+ aL butterhp aL, khpfreq
+ aR butterhp aR, khpfreq
+ endif
+
+ bus_mix("reverb1", aL*krevsend, aR*krevsend)
+ bus_mix("master", aL, aR)
+endin
+
+
+
+
+#end
diff --git a/site/app/partialemergence/index.html b/site/app/partialemergence/index.html new file mode 100644 index 0000000..5b7cedd --- /dev/null +++ b/site/app/partialemergence/index.html @@ -0,0 +1,39 @@ +<html> + <head> + <script type="text/javascript" src="/code/jquery.js"></script> + <script type="text/javascript" src="../base/base.js"></script> + <script type="text/javascript"> + + $(function(){ + + window.app = new CSApplication({ + manualSoundCollections: true, + csdUrl: "partialemergence.csd", + onPlay: function () { + $("#loading").hide(); + }, + files: [ + "progressions/progression1.fnmlmel","progressions/progression2.fnmlmel","progressions/progression3.fnmlmel","sounds/Kalimba/60.0.mp3","sounds/Kalimba/60.1.mp3","sounds/Kalimba/60.2.mp3","sounds/Kalimba/60.3.mp3","sounds/Kalimba/62.0.mp3","sounds/Kalimba/62.1.mp3","sounds/Kalimba/62.2.mp3","sounds/Kalimba/62.3.mp3","sounds/Kalimba/64.0.mp3","sounds/Kalimba/64.1.mp3","sounds/Kalimba/64.2.mp3","sounds/Kalimba/64.3.mp3","sounds/Kalimba/65.0.mp3","sounds/Kalimba/65.1.mp3","sounds/Kalimba/65.2.mp3","sounds/Kalimba/65.3.mp3","sounds/Kalimba/65.4.mp3","sounds/Kalimba/67.0.mp3","sounds/Kalimba/67.1.mp3","sounds/Kalimba/67.2.mp3","sounds/Kalimba/67.3.mp3","sounds/Kalimba/67.4.mp3","sounds/Kalimba/69.0.mp3","sounds/Kalimba/69.1.mp3","sounds/Kalimba/69.2.mp3","sounds/Kalimba/69.3.mp3","sounds/Kalimba/69.4.mp3","sounds/Kalimba/71.0.mp3","sounds/Kalimba/71.1.mp3","sounds/Kalimba/71.2.mp3","sounds/Kalimba/71.3.mp3","sounds/Kalimba/71.4.mp3","sounds/Kalimba/72.0.mp3","sounds/Kalimba/72.1.mp3","sounds/Kalimba/72.2.mp3","sounds/Kalimba/72.3.mp3","sounds/Kalimba/74.0.mp3","sounds/Kalimba/74.1.mp3","sounds/Kalimba/74.2.mp3","sounds/Kalimba/74.3.mp3","sounds/Kalimba/76.0.mp3","sounds/Kalimba/76.1.mp3","sounds/Kalimba/76.2.mp3","sounds/Kalimba/76.3.mp3","sounds/Kalimba/77.0.mp3","sounds/Kalimba/77.1.mp3","sounds/Kalimba/77.2.mp3","sounds/Kalimba/77.3.mp3","sounds/Kalimba/77.4.mp3","sounds/Kalimba/79.0.mp3","sounds/Kalimba/79.1.mp3","sounds/Kalimba/79.2.mp3","sounds/Kalimba/79.3.mp3","sounds/Kalimba/81.0.mp3","sounds/Kalimba/81.1.mp3","sounds/Kalimba/81.2.mp3","sounds/Kalimba/81.3.mp3","sounds/Kalimba/81.4.mp3","sounds/Kalimba/83.0.mp3","sounds/Kalimba/83.1.mp3","sounds/Kalimba/83.2.mp3","sounds/Kalimba/83.3.mp3","sounds/Kalimba/83.4.mp3","sounds/Kalimba/84.0.mp3","sounds/Kalimba/84.1.mp3","sounds/Kalimba/84.2.mp3","sounds/Kalimba/84.3.mp3","sounds/Kalimba/86.0.mp3","sounds/Kalimba/86.1.mp3","sounds/Kalimba/86.2.mp3","sounds/Kalimba/86.3.mp3","sounds/Kalimba/88.0.mp3","sounds/Kalimba/88.1.mp3","sounds/Kalimba/88.2.mp3","sounds/MusicBox/68.0.mp3","sounds/MusicBox/68.1.mp3","sounds/MusicBox/68.2.mp3","sounds/MusicBox/68.3.mp3","sounds/MusicBox/68.4.mp3","sounds/MusicBox/68.5.mp3","sounds/MusicBox/70.0.mp3","sounds/MusicBox/70.1.mp3","sounds/MusicBox/70.2.mp3","sounds/MusicBox/70.3.mp3","sounds/MusicBox/70.4.mp3","sounds/MusicBox/72.0.mp3","sounds/MusicBox/72.1.mp3","sounds/MusicBox/72.2.mp3","sounds/MusicBox/72.3.mp3","sounds/MusicBox/73.0.mp3","sounds/MusicBox/73.1.mp3","sounds/MusicBox/73.2.mp3","sounds/MusicBox/75.0.mp3","sounds/MusicBox/75.1.mp3","sounds/MusicBox/75.2.mp3","sounds/MusicBox/77.0.mp3","sounds/MusicBox/77.1.mp3","sounds/MusicBox/77.2.mp3","sounds/MusicBox/77.3.mp3","sounds/MusicBox/79.0.mp3","sounds/MusicBox/79.1.mp3","sounds/MusicBox/79.2.mp3","sounds/MusicBox/79.3.mp3","sounds/MusicBox/80.0.mp3","sounds/MusicBox/80.1.mp3","sounds/MusicBox/80.2.mp3","sounds/MusicBox/80.3.mp3","sounds/MusicBox/82.0.mp3","sounds/MusicBox/82.1.mp3","sounds/MusicBox/82.2.mp3","sounds/MusicBox/82.3.mp3","sounds/MusicBox/84.0.mp3","sounds/MusicBox/84.1.mp3","sounds/MusicBox/84.2.mp3","sounds/MusicBox/84.3.mp3","sounds/MusicBox/85.0.mp3","sounds/MusicBox/85.1.mp3","sounds/MusicBox/85.2.mp3","sounds/MusicBox/85.3.mp3","sounds/MusicBox/87.0.mp3","sounds/MusicBox/87.1.mp3","sounds/MusicBox/87.2.mp3","sounds/MusicBox/87.3.mp3","sounds/MusicBox/87.4.mp3","sounds/MusicBox/89.0.mp3","sounds/MusicBox/89.1.mp3","sounds/MusicBox/89.2.mp3","sounds/MusicBox/89.3.mp3","sounds/MusicBox/91.0.mp3","sounds/MusicBox/91.1.mp3","sounds/MusicBox/91.2.mp3","sounds/MusicBox/92.0.mp3","sounds/MusicBox/92.1.mp3","sounds/MusicBox/92.2.mp3","sounds/Water/Droplets/1.mp3","sounds/Water/Droplets/10.mp3","sounds/Water/Droplets/100.mp3","sounds/Water/Droplets/101.mp3","sounds/Water/Droplets/102.mp3","sounds/Water/Droplets/103.mp3","sounds/Water/Droplets/104.mp3","sounds/Water/Droplets/105.mp3","sounds/Water/Droplets/106.mp3","sounds/Water/Droplets/107.mp3","sounds/Water/Droplets/108.mp3","sounds/Water/Droplets/109.mp3","sounds/Water/Droplets/11.mp3","sounds/Water/Droplets/110.mp3","sounds/Water/Droplets/111.mp3","sounds/Water/Droplets/112.mp3","sounds/Water/Droplets/113.mp3","sounds/Water/Droplets/114.mp3","sounds/Water/Droplets/115.mp3","sounds/Water/Droplets/116.mp3","sounds/Water/Droplets/117.mp3","sounds/Water/Droplets/118.mp3","sounds/Water/Droplets/119.mp3","sounds/Water/Droplets/12.mp3","sounds/Water/Droplets/120.mp3","sounds/Water/Droplets/121.mp3","sounds/Water/Droplets/122.mp3","sounds/Water/Droplets/123.mp3","sounds/Water/Droplets/124.mp3","sounds/Water/Droplets/125.mp3","sounds/Water/Droplets/126.mp3","sounds/Water/Droplets/127.mp3","sounds/Water/Droplets/128.mp3","sounds/Water/Droplets/129.mp3","sounds/Water/Droplets/13.mp3","sounds/Water/Droplets/130.mp3","sounds/Water/Droplets/131.mp3","sounds/Water/Droplets/132.mp3","sounds/Water/Droplets/133.mp3","sounds/Water/Droplets/134.mp3","sounds/Water/Droplets/135.mp3","sounds/Water/Droplets/136.mp3","sounds/Water/Droplets/137.mp3","sounds/Water/Droplets/138.mp3","sounds/Water/Droplets/139.mp3","sounds/Water/Droplets/14.mp3","sounds/Water/Droplets/140.mp3","sounds/Water/Droplets/141.mp3","sounds/Water/Droplets/142.mp3","sounds/Water/Droplets/143.mp3","sounds/Water/Droplets/144.mp3","sounds/Water/Droplets/145.mp3","sounds/Water/Droplets/146.mp3","sounds/Water/Droplets/147.mp3","sounds/Water/Droplets/148.mp3","sounds/Water/Droplets/149.mp3","sounds/Water/Droplets/15.mp3","sounds/Water/Droplets/150.mp3","sounds/Water/Droplets/151.mp3","sounds/Water/Droplets/152.mp3","sounds/Water/Droplets/153.mp3","sounds/Water/Droplets/154.mp3","sounds/Water/Droplets/155.mp3","sounds/Water/Droplets/156.mp3","sounds/Water/Droplets/157.mp3","sounds/Water/Droplets/158.mp3","sounds/Water/Droplets/159.mp3","sounds/Water/Droplets/16.mp3","sounds/Water/Droplets/160.mp3","sounds/Water/Droplets/161.mp3","sounds/Water/Droplets/162.mp3","sounds/Water/Droplets/163.mp3","sounds/Water/Droplets/164.mp3","sounds/Water/Droplets/165.mp3","sounds/Water/Droplets/166.mp3","sounds/Water/Droplets/167.mp3","sounds/Water/Droplets/168.mp3","sounds/Water/Droplets/169.mp3","sounds/Water/Droplets/17.mp3","sounds/Water/Droplets/170.mp3","sounds/Water/Droplets/171.mp3","sounds/Water/Droplets/172.mp3","sounds/Water/Droplets/173.mp3","sounds/Water/Droplets/174.mp3","sounds/Water/Droplets/175.mp3","sounds/Water/Droplets/176.mp3","sounds/Water/Droplets/177.mp3","sounds/Water/Droplets/178.mp3","sounds/Water/Droplets/179.mp3","sounds/Water/Droplets/18.mp3","sounds/Water/Droplets/180.mp3","sounds/Water/Droplets/181.mp3","sounds/Water/Droplets/182.mp3","sounds/Water/Droplets/183.mp3","sounds/Water/Droplets/184.mp3","sounds/Water/Droplets/185.mp3","sounds/Water/Droplets/186.mp3","sounds/Water/Droplets/187.mp3","sounds/Water/Droplets/188.mp3","sounds/Water/Droplets/189.mp3","sounds/Water/Droplets/19.mp3","sounds/Water/Droplets/190.mp3","sounds/Water/Droplets/191.mp3","sounds/Water/Droplets/192.mp3","sounds/Water/Droplets/193.mp3","sounds/Water/Droplets/194.mp3","sounds/Water/Droplets/195.mp3","sounds/Water/Droplets/196.mp3","sounds/Water/Droplets/197.mp3","sounds/Water/Droplets/198.mp3","sounds/Water/Droplets/199.mp3","sounds/Water/Droplets/2.mp3","sounds/Water/Droplets/20.mp3","sounds/Water/Droplets/200.mp3","sounds/Water/Droplets/201.mp3","sounds/Water/Droplets/202.mp3","sounds/Water/Droplets/203.mp3","sounds/Water/Droplets/204.mp3","sounds/Water/Droplets/205.mp3","sounds/Water/Droplets/206.mp3","sounds/Water/Droplets/207.mp3","sounds/Water/Droplets/208.mp3","sounds/Water/Droplets/209.mp3","sounds/Water/Droplets/21.mp3","sounds/Water/Droplets/210.mp3","sounds/Water/Droplets/211.mp3","sounds/Water/Droplets/212.mp3","sounds/Water/Droplets/213.mp3","sounds/Water/Droplets/214.mp3","sounds/Water/Droplets/215.mp3","sounds/Water/Droplets/216.mp3","sounds/Water/Droplets/217.mp3","sounds/Water/Droplets/218.mp3","sounds/Water/Droplets/219.mp3","sounds/Water/Droplets/22.mp3","sounds/Water/Droplets/220.mp3","sounds/Water/Droplets/221.mp3","sounds/Water/Droplets/222.mp3","sounds/Water/Droplets/223.mp3","sounds/Water/Droplets/224.mp3","sounds/Water/Droplets/225.mp3","sounds/Water/Droplets/226.mp3","sounds/Water/Droplets/227.mp3","sounds/Water/Droplets/228.mp3","sounds/Water/Droplets/229.mp3","sounds/Water/Droplets/23.mp3","sounds/Water/Droplets/230.mp3","sounds/Water/Droplets/231.mp3","sounds/Water/Droplets/232.mp3","sounds/Water/Droplets/233.mp3","sounds/Water/Droplets/234.mp3","sounds/Water/Droplets/235.mp3","sounds/Water/Droplets/236.mp3","sounds/Water/Droplets/237.mp3","sounds/Water/Droplets/238.mp3","sounds/Water/Droplets/239.mp3","sounds/Water/Droplets/24.mp3","sounds/Water/Droplets/240.mp3","sounds/Water/Droplets/241.mp3","sounds/Water/Droplets/242.mp3","sounds/Water/Droplets/243.mp3","sounds/Water/Droplets/244.mp3","sounds/Water/Droplets/245.mp3","sounds/Water/Droplets/246.mp3","sounds/Water/Droplets/247.mp3","sounds/Water/Droplets/248.mp3","sounds/Water/Droplets/249.mp3","sounds/Water/Droplets/25.mp3","sounds/Water/Droplets/250.mp3","sounds/Water/Droplets/251.mp3","sounds/Water/Droplets/252.mp3","sounds/Water/Droplets/253.mp3","sounds/Water/Droplets/254.mp3","sounds/Water/Droplets/255.mp3","sounds/Water/Droplets/256.mp3","sounds/Water/Droplets/257.mp3","sounds/Water/Droplets/258.mp3","sounds/Water/Droplets/259.mp3","sounds/Water/Droplets/26.mp3","sounds/Water/Droplets/260.mp3","sounds/Water/Droplets/261.mp3","sounds/Water/Droplets/262.mp3","sounds/Water/Droplets/263.mp3","sounds/Water/Droplets/264.mp3","sounds/Water/Droplets/265.mp3","sounds/Water/Droplets/266.mp3","sounds/Water/Droplets/267.mp3","sounds/Water/Droplets/268.mp3","sounds/Water/Droplets/269.mp3","sounds/Water/Droplets/27.mp3","sounds/Water/Droplets/270.mp3","sounds/Water/Droplets/271.mp3","sounds/Water/Droplets/272.mp3","sounds/Water/Droplets/273.mp3","sounds/Water/Droplets/274.mp3","sounds/Water/Droplets/275.mp3","sounds/Water/Droplets/276.mp3","sounds/Water/Droplets/277.mp3","sounds/Water/Droplets/278.mp3","sounds/Water/Droplets/279.mp3","sounds/Water/Droplets/28.mp3","sounds/Water/Droplets/280.mp3","sounds/Water/Droplets/281.mp3","sounds/Water/Droplets/282.mp3","sounds/Water/Droplets/283.mp3","sounds/Water/Droplets/284.mp3","sounds/Water/Droplets/285.mp3","sounds/Water/Droplets/286.mp3","sounds/Water/Droplets/287.mp3","sounds/Water/Droplets/288.mp3","sounds/Water/Droplets/289.mp3","sounds/Water/Droplets/29.mp3","sounds/Water/Droplets/290.mp3","sounds/Water/Droplets/291.mp3","sounds/Water/Droplets/292.mp3","sounds/Water/Droplets/293.mp3","sounds/Water/Droplets/294.mp3","sounds/Water/Droplets/295.mp3","sounds/Water/Droplets/296.mp3","sounds/Water/Droplets/297.mp3","sounds/Water/Droplets/298.mp3","sounds/Water/Droplets/299.mp3","sounds/Water/Droplets/3.mp3","sounds/Water/Droplets/30.mp3","sounds/Water/Droplets/300.mp3","sounds/Water/Droplets/301.mp3","sounds/Water/Droplets/302.mp3","sounds/Water/Droplets/303.mp3","sounds/Water/Droplets/304.mp3","sounds/Water/Droplets/305.mp3","sounds/Water/Droplets/306.mp3","sounds/Water/Droplets/307.mp3","sounds/Water/Droplets/308.mp3","sounds/Water/Droplets/309.mp3","sounds/Water/Droplets/31.mp3","sounds/Water/Droplets/310.mp3","sounds/Water/Droplets/311.mp3","sounds/Water/Droplets/312.mp3","sounds/Water/Droplets/313.mp3","sounds/Water/Droplets/314.mp3","sounds/Water/Droplets/315.mp3","sounds/Water/Droplets/316.mp3","sounds/Water/Droplets/317.mp3","sounds/Water/Droplets/318.mp3","sounds/Water/Droplets/319.mp3","sounds/Water/Droplets/32.mp3","sounds/Water/Droplets/320.mp3","sounds/Water/Droplets/321.mp3","sounds/Water/Droplets/322.mp3","sounds/Water/Droplets/323.mp3","sounds/Water/Droplets/324.mp3","sounds/Water/Droplets/325.mp3","sounds/Water/Droplets/326.mp3","sounds/Water/Droplets/327.mp3","sounds/Water/Droplets/328.mp3","sounds/Water/Droplets/329.mp3","sounds/Water/Droplets/33.mp3","sounds/Water/Droplets/330.mp3","sounds/Water/Droplets/331.mp3","sounds/Water/Droplets/332.mp3","sounds/Water/Droplets/333.mp3","sounds/Water/Droplets/334.mp3","sounds/Water/Droplets/335.mp3","sounds/Water/Droplets/336.mp3","sounds/Water/Droplets/337.mp3","sounds/Water/Droplets/338.mp3","sounds/Water/Droplets/339.mp3","sounds/Water/Droplets/34.mp3","sounds/Water/Droplets/340.mp3","sounds/Water/Droplets/341.mp3","sounds/Water/Droplets/342.mp3","sounds/Water/Droplets/343.mp3","sounds/Water/Droplets/344.mp3","sounds/Water/Droplets/345.mp3","sounds/Water/Droplets/346.mp3","sounds/Water/Droplets/347.mp3","sounds/Water/Droplets/348.mp3","sounds/Water/Droplets/349.mp3","sounds/Water/Droplets/35.mp3","sounds/Water/Droplets/350.mp3","sounds/Water/Droplets/351.mp3","sounds/Water/Droplets/352.mp3","sounds/Water/Droplets/353.mp3","sounds/Water/Droplets/354.mp3","sounds/Water/Droplets/355.mp3","sounds/Water/Droplets/356.mp3","sounds/Water/Droplets/357.mp3","sounds/Water/Droplets/358.mp3","sounds/Water/Droplets/359.mp3","sounds/Water/Droplets/36.mp3","sounds/Water/Droplets/360.mp3","sounds/Water/Droplets/361.mp3","sounds/Water/Droplets/362.mp3","sounds/Water/Droplets/363.mp3","sounds/Water/Droplets/364.mp3","sounds/Water/Droplets/365.mp3","sounds/Water/Droplets/366.mp3","sounds/Water/Droplets/367.mp3","sounds/Water/Droplets/368.mp3","sounds/Water/Droplets/369.mp3","sounds/Water/Droplets/37.mp3","sounds/Water/Droplets/370.mp3","sounds/Water/Droplets/371.mp3","sounds/Water/Droplets/372.mp3","sounds/Water/Droplets/373.mp3","sounds/Water/Droplets/374.mp3","sounds/Water/Droplets/375.mp3","sounds/Water/Droplets/376.mp3","sounds/Water/Droplets/377.mp3","sounds/Water/Droplets/378.mp3","sounds/Water/Droplets/379.mp3","sounds/Water/Droplets/38.mp3","sounds/Water/Droplets/380.mp3","sounds/Water/Droplets/381.mp3","sounds/Water/Droplets/382.mp3","sounds/Water/Droplets/383.mp3","sounds/Water/Droplets/384.mp3","sounds/Water/Droplets/385.mp3","sounds/Water/Droplets/386.mp3","sounds/Water/Droplets/387.mp3","sounds/Water/Droplets/388.mp3","sounds/Water/Droplets/389.mp3","sounds/Water/Droplets/39.mp3","sounds/Water/Droplets/390.mp3","sounds/Water/Droplets/391.mp3","sounds/Water/Droplets/392.mp3","sounds/Water/Droplets/393.mp3","sounds/Water/Droplets/394.mp3","sounds/Water/Droplets/395.mp3","sounds/Water/Droplets/396.mp3","sounds/Water/Droplets/397.mp3","sounds/Water/Droplets/398.mp3","sounds/Water/Droplets/399.mp3","sounds/Water/Droplets/4.mp3","sounds/Water/Droplets/40.mp3","sounds/Water/Droplets/400.mp3","sounds/Water/Droplets/401.mp3","sounds/Water/Droplets/402.mp3","sounds/Water/Droplets/403.mp3","sounds/Water/Droplets/404.mp3","sounds/Water/Droplets/405.mp3","sounds/Water/Droplets/406.mp3","sounds/Water/Droplets/407.mp3","sounds/Water/Droplets/408.mp3","sounds/Water/Droplets/409.mp3","sounds/Water/Droplets/41.mp3","sounds/Water/Droplets/410.mp3","sounds/Water/Droplets/411.mp3","sounds/Water/Droplets/412.mp3","sounds/Water/Droplets/413.mp3","sounds/Water/Droplets/414.mp3","sounds/Water/Droplets/415.mp3","sounds/Water/Droplets/416.mp3","sounds/Water/Droplets/417.mp3","sounds/Water/Droplets/418.mp3","sounds/Water/Droplets/419.mp3","sounds/Water/Droplets/42.mp3","sounds/Water/Droplets/420.mp3","sounds/Water/Droplets/421.mp3","sounds/Water/Droplets/422.mp3","sounds/Water/Droplets/423.mp3","sounds/Water/Droplets/424.mp3","sounds/Water/Droplets/425.mp3","sounds/Water/Droplets/426.mp3","sounds/Water/Droplets/427.mp3","sounds/Water/Droplets/428.mp3","sounds/Water/Droplets/429.mp3","sounds/Water/Droplets/43.mp3","sounds/Water/Droplets/430.mp3","sounds/Water/Droplets/431.mp3","sounds/Water/Droplets/432.mp3","sounds/Water/Droplets/433.mp3","sounds/Water/Droplets/434.mp3","sounds/Water/Droplets/435.mp3","sounds/Water/Droplets/436.mp3","sounds/Water/Droplets/437.mp3","sounds/Water/Droplets/438.mp3","sounds/Water/Droplets/439.mp3","sounds/Water/Droplets/44.mp3","sounds/Water/Droplets/440.mp3","sounds/Water/Droplets/441.mp3","sounds/Water/Droplets/442.mp3","sounds/Water/Droplets/443.mp3","sounds/Water/Droplets/444.mp3","sounds/Water/Droplets/445.mp3","sounds/Water/Droplets/446.mp3","sounds/Water/Droplets/447.mp3","sounds/Water/Droplets/448.mp3","sounds/Water/Droplets/449.mp3","sounds/Water/Droplets/45.mp3","sounds/Water/Droplets/450.mp3","sounds/Water/Droplets/451.mp3","sounds/Water/Droplets/452.mp3","sounds/Water/Droplets/453.mp3","sounds/Water/Droplets/454.mp3","sounds/Water/Droplets/455.mp3","sounds/Water/Droplets/456.mp3","sounds/Water/Droplets/457.mp3","sounds/Water/Droplets/458.mp3","sounds/Water/Droplets/459.mp3","sounds/Water/Droplets/46.mp3","sounds/Water/Droplets/460.mp3","sounds/Water/Droplets/461.mp3","sounds/Water/Droplets/462.mp3","sounds/Water/Droplets/463.mp3","sounds/Water/Droplets/464.mp3","sounds/Water/Droplets/465.mp3","sounds/Water/Droplets/466.mp3","sounds/Water/Droplets/467.mp3","sounds/Water/Droplets/468.mp3","sounds/Water/Droplets/469.mp3","sounds/Water/Droplets/47.mp3","sounds/Water/Droplets/470.mp3","sounds/Water/Droplets/471.mp3","sounds/Water/Droplets/472.mp3","sounds/Water/Droplets/473.mp3","sounds/Water/Droplets/474.mp3","sounds/Water/Droplets/475.mp3","sounds/Water/Droplets/476.mp3","sounds/Water/Droplets/477.mp3","sounds/Water/Droplets/478.mp3","sounds/Water/Droplets/479.mp3","sounds/Water/Droplets/48.mp3","sounds/Water/Droplets/480.mp3","sounds/Water/Droplets/481.mp3","sounds/Water/Droplets/482.mp3","sounds/Water/Droplets/483.mp3","sounds/Water/Droplets/484.mp3","sounds/Water/Droplets/485.mp3","sounds/Water/Droplets/486.mp3","sounds/Water/Droplets/487.mp3","sounds/Water/Droplets/488.mp3","sounds/Water/Droplets/489.mp3","sounds/Water/Droplets/49.mp3","sounds/Water/Droplets/490.mp3","sounds/Water/Droplets/491.mp3","sounds/Water/Droplets/492.mp3","sounds/Water/Droplets/493.mp3","sounds/Water/Droplets/494.mp3","sounds/Water/Droplets/495.mp3","sounds/Water/Droplets/496.mp3","sounds/Water/Droplets/497.mp3","sounds/Water/Droplets/498.mp3","sounds/Water/Droplets/499.mp3","sounds/Water/Droplets/5.mp3","sounds/Water/Droplets/50.mp3","sounds/Water/Droplets/500.mp3","sounds/Water/Droplets/501.mp3","sounds/Water/Droplets/502.mp3","sounds/Water/Droplets/503.mp3","sounds/Water/Droplets/504.mp3","sounds/Water/Droplets/505.mp3","sounds/Water/Droplets/506.mp3","sounds/Water/Droplets/507.mp3","sounds/Water/Droplets/508.mp3","sounds/Water/Droplets/509.mp3","sounds/Water/Droplets/51.mp3","sounds/Water/Droplets/510.mp3","sounds/Water/Droplets/511.mp3","sounds/Water/Droplets/512.mp3","sounds/Water/Droplets/513.mp3","sounds/Water/Droplets/514.mp3","sounds/Water/Droplets/515.mp3","sounds/Water/Droplets/516.mp3","sounds/Water/Droplets/517.mp3","sounds/Water/Droplets/518.mp3","sounds/Water/Droplets/519.mp3","sounds/Water/Droplets/52.mp3","sounds/Water/Droplets/520.mp3","sounds/Water/Droplets/521.mp3","sounds/Water/Droplets/522.mp3","sounds/Water/Droplets/523.mp3","sounds/Water/Droplets/524.mp3","sounds/Water/Droplets/525.mp3","sounds/Water/Droplets/526.mp3","sounds/Water/Droplets/527.mp3","sounds/Water/Droplets/528.mp3","sounds/Water/Droplets/529.mp3","sounds/Water/Droplets/53.mp3","sounds/Water/Droplets/530.mp3","sounds/Water/Droplets/531.mp3","sounds/Water/Droplets/532.mp3","sounds/Water/Droplets/533.mp3","sounds/Water/Droplets/534.mp3","sounds/Water/Droplets/535.mp3","sounds/Water/Droplets/536.mp3","sounds/Water/Droplets/537.mp3","sounds/Water/Droplets/538.mp3","sounds/Water/Droplets/539.mp3","sounds/Water/Droplets/54.mp3","sounds/Water/Droplets/540.mp3","sounds/Water/Droplets/541.mp3","sounds/Water/Droplets/542.mp3","sounds/Water/Droplets/543.mp3","sounds/Water/Droplets/545.mp3","sounds/Water/Droplets/546.mp3","sounds/Water/Droplets/547.mp3","sounds/Water/Droplets/548.mp3","sounds/Water/Droplets/549.mp3","sounds/Water/Droplets/55.mp3","sounds/Water/Droplets/550.mp3","sounds/Water/Droplets/551.mp3","sounds/Water/Droplets/552.mp3","sounds/Water/Droplets/553.mp3","sounds/Water/Droplets/554.mp3","sounds/Water/Droplets/555.mp3","sounds/Water/Droplets/556.mp3","sounds/Water/Droplets/557.mp3","sounds/Water/Droplets/558.mp3","sounds/Water/Droplets/559.mp3","sounds/Water/Droplets/56.mp3","sounds/Water/Droplets/560.mp3","sounds/Water/Droplets/561.mp3","sounds/Water/Droplets/562.mp3","sounds/Water/Droplets/563.mp3","sounds/Water/Droplets/564.mp3","sounds/Water/Droplets/565.mp3","sounds/Water/Droplets/566.mp3","sounds/Water/Droplets/567.mp3","sounds/Water/Droplets/568.mp3","sounds/Water/Droplets/569.mp3","sounds/Water/Droplets/57.mp3","sounds/Water/Droplets/570.mp3","sounds/Water/Droplets/571.mp3","sounds/Water/Droplets/572.mp3","sounds/Water/Droplets/573.mp3","sounds/Water/Droplets/574.mp3","sounds/Water/Droplets/575.mp3","sounds/Water/Droplets/576.mp3","sounds/Water/Droplets/577.mp3","sounds/Water/Droplets/578.mp3","sounds/Water/Droplets/579.mp3","sounds/Water/Droplets/58.mp3","sounds/Water/Droplets/59.mp3","sounds/Water/Droplets/6.mp3","sounds/Water/Droplets/60.mp3","sounds/Water/Droplets/61.mp3","sounds/Water/Droplets/62.mp3","sounds/Water/Droplets/63.mp3","sounds/Water/Droplets/64.mp3","sounds/Water/Droplets/65.mp3","sounds/Water/Droplets/66.mp3","sounds/Water/Droplets/67.mp3","sounds/Water/Droplets/68.mp3","sounds/Water/Droplets/69.mp3","sounds/Water/Droplets/7.mp3","sounds/Water/Droplets/70.mp3","sounds/Water/Droplets/71.mp3","sounds/Water/Droplets/72.mp3","sounds/Water/Droplets/73.mp3","sounds/Water/Droplets/74.mp3","sounds/Water/Droplets/75.mp3","sounds/Water/Droplets/76.mp3","sounds/Water/Droplets/77.mp3","sounds/Water/Droplets/78.mp3","sounds/Water/Droplets/79.mp3","sounds/Water/Droplets/8.mp3","sounds/Water/Droplets/80.mp3","sounds/Water/Droplets/81.mp3","sounds/Water/Droplets/82.mp3","sounds/Water/Droplets/83.mp3","sounds/Water/Droplets/84.mp3","sounds/Water/Droplets/85.mp3","sounds/Water/Droplets/86.mp3","sounds/Water/Droplets/87.mp3","sounds/Water/Droplets/88.mp3","sounds/Water/Droplets/89.mp3","sounds/Water/Droplets/9.mp3","sounds/Water/Droplets/90.mp3","sounds/Water/Droplets/91.mp3","sounds/Water/Droplets/92.mp3","sounds/Water/Droplets/93.mp3","sounds/Water/Droplets/94.mp3","sounds/Water/Droplets/95.mp3","sounds/Water/Droplets/96.mp3","sounds/Water/Droplets/97.mp3","sounds/Water/Droplets/98.mp3","sounds/Water/Droplets/99.mp3","sounds/Water/Paddling/1.mp3","sounds/Water/Paddling/10.mp3","sounds/Water/Paddling/100.mp3","sounds/Water/Paddling/11.mp3","sounds/Water/Paddling/12.mp3","sounds/Water/Paddling/13.mp3","sounds/Water/Paddling/14.mp3","sounds/Water/Paddling/15.mp3","sounds/Water/Paddling/16.mp3","sounds/Water/Paddling/17.mp3","sounds/Water/Paddling/18.mp3","sounds/Water/Paddling/19.mp3","sounds/Water/Paddling/2.mp3","sounds/Water/Paddling/20.mp3","sounds/Water/Paddling/21.mp3","sounds/Water/Paddling/22.mp3","sounds/Water/Paddling/23.mp3","sounds/Water/Paddling/24.mp3","sounds/Water/Paddling/25.mp3","sounds/Water/Paddling/26.mp3","sounds/Water/Paddling/27.mp3","sounds/Water/Paddling/28.mp3","sounds/Water/Paddling/29.mp3","sounds/Water/Paddling/3.mp3","sounds/Water/Paddling/30.mp3","sounds/Water/Paddling/31.mp3","sounds/Water/Paddling/32.mp3","sounds/Water/Paddling/33.mp3","sounds/Water/Paddling/34.mp3","sounds/Water/Paddling/35.mp3","sounds/Water/Paddling/36.mp3","sounds/Water/Paddling/37.mp3","sounds/Water/Paddling/38.mp3","sounds/Water/Paddling/39.mp3","sounds/Water/Paddling/4.mp3","sounds/Water/Paddling/40.mp3","sounds/Water/Paddling/41.mp3","sounds/Water/Paddling/42.mp3","sounds/Water/Paddling/43.mp3","sounds/Water/Paddling/44.mp3","sounds/Water/Paddling/45.mp3","sounds/Water/Paddling/46.mp3","sounds/Water/Paddling/47.mp3","sounds/Water/Paddling/48.mp3","sounds/Water/Paddling/49.mp3","sounds/Water/Paddling/5.mp3","sounds/Water/Paddling/50.mp3","sounds/Water/Paddling/51.mp3","sounds/Water/Paddling/52.mp3","sounds/Water/Paddling/53.mp3","sounds/Water/Paddling/54.mp3","sounds/Water/Paddling/55.mp3","sounds/Water/Paddling/56.mp3","sounds/Water/Paddling/57.mp3","sounds/Water/Paddling/58.mp3","sounds/Water/Paddling/59.mp3","sounds/Water/Paddling/6.mp3","sounds/Water/Paddling/60.mp3","sounds/Water/Paddling/61.mp3","sounds/Water/Paddling/62.mp3","sounds/Water/Paddling/63.mp3","sounds/Water/Paddling/64.mp3","sounds/Water/Paddling/65.mp3","sounds/Water/Paddling/66.mp3","sounds/Water/Paddling/67.mp3","sounds/Water/Paddling/68.mp3","sounds/Water/Paddling/69.mp3","sounds/Water/Paddling/7.mp3","sounds/Water/Paddling/70.mp3","sounds/Water/Paddling/71.mp3","sounds/Water/Paddling/72.mp3","sounds/Water/Paddling/73.mp3","sounds/Water/Paddling/74.mp3","sounds/Water/Paddling/75.mp3","sounds/Water/Paddling/76.mp3","sounds/Water/Paddling/77.mp3","sounds/Water/Paddling/78.mp3","sounds/Water/Paddling/79.mp3","sounds/Water/Paddling/8.mp3","sounds/Water/Paddling/80.mp3","sounds/Water/Paddling/81.mp3","sounds/Water/Paddling/82.mp3","sounds/Water/Paddling/83.mp3","sounds/Water/Paddling/84.mp3","sounds/Water/Paddling/85.mp3","sounds/Water/Paddling/86.mp3","sounds/Water/Paddling/87.mp3","sounds/Water/Paddling/88.mp3","sounds/Water/Paddling/89.mp3","sounds/Water/Paddling/9.mp3","sounds/Water/Paddling/90.mp3","sounds/Water/Paddling/91.mp3","sounds/Water/Paddling/92.mp3","sounds/Water/Paddling/93.mp3","sounds/Water/Paddling/94.mp3","sounds/Water/Paddling/95.mp3","sounds/Water/Paddling/96.mp3","sounds/Water/Paddling/97.mp3","sounds/Water/Paddling/98.mp3","sounds/Water/Paddling/99.mp3" + ] + }); + + $("#begin").click(function() { + $("#begin").hide(); + $("#loading").show(); + app.play(); + }); + }); + </script> + </head> + <body> + <div id="loading"> + <h3>Loading</h3> + </div> + <div id="begin"> + <div id="begininner"> + <h3>Partial Emergence</h3> + <h2>Press to begin</h2> + </div> + </div> + </body> +</html> diff --git a/site/app/partialemergence/instruments_hybrid.inc b/site/app/partialemergence/instruments_hybrid.inc new file mode 100644 index 0000000..1d9f77f --- /dev/null +++ b/site/app/partialemergence/instruments_hybrid.inc @@ -0,0 +1,254 @@ +#ifndef INC_HYBRID_INSTR
+#define INC_HYBRID_INSTR ##
+
+#include "/instruments_water.inc"
+#include "/instruments_idiophone.inc"
+#include "/array_tools.udo"
+#include "/wavetables.udo"
+#include "/soundxdb.udo"
+#include "/sequencing_melodic.udo"
+
+; reson
+instr note_hybrid1
+ inote = p4
+
+ ifreq = cpsmidinn(inote)
+ ifileid = arr_random(gisnd_waterdrop)
+
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ ipitch = random(0.8, 1.6)
+
+ itdur = (idur / ipitch) + random(0.2, 0.5)
+ p3 = itdur
+ ;aL, aR loscil 1, ipitch, ifn, 1
+ atime line 0, p3, idur*0.9
+ aL, aR mincer atime, 1, ipitch, ifn, 0, 128 ; 1024
+ aLr resony aL, ifreq, 2, random(8, 16), 10
+ aRr resony aL, ifreq, 2, random(8, 16), 10
+
+ aLr pareq aLr, ifreq, 0.4, 0.7
+ aRr pareq aRr, ifreq, 0.4, 0.7
+
+ aL balance aLr, aL
+ aR balance aRr, aR
+ aL dcblock aL
+ aR dcblock aR
+
+ kamp linseg 1, itdur*0.9, 1, itdur*0.1, 0
+
+ iamp = random(0.7, 1)
+ ipan = random(0, 1)
+ aL *= kamp * iamp * ipan
+ aR *= kamp * iamp * (1-ipan)
+ bus_mix("pvsamp1", aL*random(0, 0.3), aR*random(0, 0.3))
+ bus_mix("reverb1", aL*0.1, aR*0.1)
+ bus_mix("delay2", aL*random(0, 0.01), aR*random(0, 0.01))
+ bus_mix("master", aL, aR)
+endin
+
+
+instr phrase_hybrid1
+ if (random(0, 1) > 0.5) then
+ ifreqstart = random(1, 10)
+ ifreqend = random(1, 10)
+ else
+ ifreqstart = random(1, 10)
+ ifreqend = random(1, 10)
+ endif
+ kfreq linseg ifreqstart, p3, ifreqend
+
+ kamp init 1
+ ktrig metro kfreq
+ if (ktrig == 1) then
+ knote = min:k(mel_randomnote:k() + (round:k(random:k(-2, 2)) * 12), 127)
+ if (random:k(0, 1) >= 0.5) then
+ schedulek("note_idiophone1", random:k(0, 0.1), 0.1, knote, kamp*2)
+ else
+ schedulek("note_hybrid1", random:k(0, 0.1), 0.1, knote)
+ endif
+ endif
+endin
+
+
+/*
+ Chord changing from idiophone to drops
+
+ p4 one note (0 = play one note, 1 = play chord)
+*/
+instr phrase_hybrid2
+ ionenote = p4
+
+ if (ionenote == 1) then
+ knote init mel_randomnote() + (round(random(-2, 4)) * 12)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ ifreqstart = random(10, 30)
+ ifreqend = random(2, 10)
+ else
+ ifreqstart = random(2, 10)
+ ifreqend = random(10, 30)
+ endif
+ kfreq linseg ifreqstart, p3, ifreqend
+
+ kamp linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ ktransition line 1, p3, 0
+
+ ktrig metro kfreq
+ if (ktrig == 1) then
+ if (random:k(0, 1) >= ktransition) then
+ if (ionenote != 1) then
+ knote = mel_randomnote:k() + (round:k(random:k(-2, 4)) * 12)
+ endif
+ schedulek("note_idiophone1", random:k(0, 0.1), 0.1, min:k(knote, 127), kamp*2)
+ else
+ schedulek("note_drop1", random:k(0, 0.1), 0.1)
+ endif
+ endif
+endin
+
+
+opcode portchord_drop, aa, iio
+ ifreqmult, ireadmode, index xin
+
+ ifileid = arr_random(gisnd_waterdrop)
+ ifftsize = 16
+
+ ifn = gisounddb[ifileid][0]
+ ichannels = gisounddb[ifileid][1]
+ idur = gisounddb[ifileid][2]
+ irmsnorm = gisounddb[ifileid][3]
+
+ kampb table index, gimel_amps
+ kfreq table index, gimel_freqs
+
+ kamp portk kampb, (i(gkseq_beattime) * gimel_portamento_beatratio) ; fade out when change
+
+ kpitch = line(random(0.8, 1.2), p3, random(0.8, 1.2))
+
+ istart = random(0.05, 0.2)
+ iend = random(istart+0.1, 0.8)
+ atime = abs(oscil(iend - istart, random(0.001, 0.1), gifnSine, random(0, 1))) + istart
+
+ klfo = oscil:k(random(0.0001, 0.009), random(1, 5)) + 1
+ kfreq *= klfo
+
+ aL init 0
+ aR init 0
+ if (kamp != 0) then
+ if (ireadmode == 0) then
+ aLm, aRm mincer atime*idur, kamp, kpitch, ifn, 0, ifftsize
+ else
+ aLm, aRm sndwarpst kamp, atime*idur, kpitch, ifn, 0, 4410, 441, 8, gifnHalfSine, 1
+ endif
+ aL resony aLm, kfreq*ifreqmult, 2, random(8, 16), 10
+ aR resony aRm, kfreq*ifreqmult, 2, random(8, 16), 10
+ aL balance aL, aLm
+ aR balance aR, aRm
+ aL butterhp aL, 210
+ aR butterhp aR, 210
+ endif
+ ipan = random(0, 1)
+
+ ;aL *= (1 - irmsnorm) * 0.5 * ipan
+ ;aR *= (1 - irmsnorm) * 0.5 * (1-ipan)
+
+ ; recursion for all chord parts
+ if (index + 1 < ftlen(gimel_amps)) then
+ aLx, aRx portchord_drop ifreqmult, ireadmode, index + 1
+ aL += aLx
+ aR += aRx
+ endif
+ xout aL, aR
+endop
+
+
+
+instr phrase_hybridstretch1
+ kamp linsegr 1, p3, 1, 1, 0
+ kampx3 init 0.2
+ kreverb1 init 0
+ kreverb2 init 0
+ kreverb3 init 0
+ aL1, aR1 portchord_drop 0.5, 1
+ ;aL2, aR2 portchord_drop 1, 1
+ aL3, aR3 portchord_drop 4, 1
+ k3amp = abs:k(oscil:k(1, 0.1))
+
+ ;aL = (aL1 + aL2 + (aL3 * port(k3amp, 1))) * kamp
+ ;aR = (aR1 + aR2 + (aR3 * port(k3amp, 1))) * kamp
+
+ aL = (aL1 + (aL3 * port(k3amp, 1))) * kamp
+ aR = (aR1 + (aR3 * port(k3amp, 1))) * kamp
+
+ kchangemetro = metro(0.2)
+ if (kchangemetro == 1) then
+ if (random:k(0, 1) > 0.2) then
+ kampx3 = random:k(0.2, 1)
+ endif
+ if (random:k(0, 1) > 0.5) then
+ kreverb1 = random:k(0, 0.4)
+ endif
+ if (random:k(0, 1) > 0.5) then
+ kreverb2 = random:k(0, 0.4)
+ endif
+ if (random:k(0, 1) > 0.5) then
+ kreverb3 = random:k(0, 0.4)
+ endif
+ endif
+
+ aL pareq aL, 1000, 0.4, 0.7
+ aR pareq aR, 1000, 0.4, 0.7
+
+ bus_mix("reverb1", aL1*kreverb1, aR1*kreverb1)
+ ;bus_mix("reverb1", aL2*kreverb2, aR2*kreverb2)
+ bus_mix("reverb1", aL3*kreverb3, aR3*kreverb3)
+ bus_mix("master", aL, aR)
+endin
+
+
+/*
+; pvsmorph
+instr note_hybrid1x
+ inote = p4
+
+ ifileidBox, ipitchBox sounddb_mel_nearestnote gicol_idiophone, inote
+ ifileidWater = arr_random(gisnd_waterdrop)
+
+ ifnBox = gisounddb[ifileidBox][0]
+ idurBox = gisounddb[ifileidBox][2]
+ ifnWater = gisounddb[ifileidWater][0]
+ idurWater = gisounddb[ifileidWater][2]
+
+ ipitchWater = random(0.8, 1)
+
+ p3 = min((idurWater / ipitchWater), (idurBox / ipitchBox))
+
+ aboxL, aboxR loscil 1, ipitchBox, ifnBox, 1
+ awaterL, awaterR loscil 1, ipitchWater, ifnWater, 1
+
+ ir = 1024
+ fboxL pvsanal aboxL, ir, ir/4, ir, 1
+ fboxR pvsanal aboxR, ir, ir/4, ir, 1
+ fwaterL pvsanal awaterL, ir, ir/4, ir, 1
+ fwaterR pvsanal awaterR, ir, ir/4, ir, 1
+ fL pvsmorph fboxL, fwaterL, 1, 0
+ fR pvsmorph fboxR, fwaterR, 1, 0
+ aL pvsynth fL
+ aR pvsynth fR
+
+ kamp linseg 1, p3*0.9, 1, p3*0.1, 0
+
+ iamp = 5
+
+ aL *= kamp * iamp
+ aR *= kamp * iamp
+ bus_mix("pvsamp1", aL*random(0, 0.1), aR*random(0, 0.1))
+ bus_mix("reverb1", aL*random(0, 0.1), aR*random(0, 0.1))
+ bus_mix("master", aL, aR)
+endin
+*/
+
+#end
diff --git a/site/app/partialemergence/instruments_idiophone.inc b/site/app/partialemergence/instruments_idiophone.inc new file mode 100644 index 0000000..f939ad9 --- /dev/null +++ b/site/app/partialemergence/instruments_idiophone.inc @@ -0,0 +1,707 @@ +#ifndef INC_MUSICBOX_INSTR
+#define INC_MUSICBOX_INSTR ##
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence
+ by Richard Knight 2022
+
+ Installation submission for the International Csound Conference 2022
+
+ Idiophone instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "/soundxdb.udo"
+#include "/array_tools.udo"
+#include "/sequencing_melodic.udo"
+#include "/sequencing_melodic_portamento.udo"
+#include "/bussing.udo"
+#include "/frequency_tools.udo"
+#include "/instrument_portchord.udo"
+#include "/instrument_gchord1.udo"
+#include "/wavetables.udo"
+
+
+; sound collections
+gicol_musicbox sounddb_getcollectionid "MusicBox"
+gicol_kalimba sounddb_getcollectionid "Kalimba"
+gicol_idiophone = gicol_musicbox
+gicol_idiophone_other = gicol_kalimba
+
+opcode idiophone_change, 0, 0
+ if (random(0, 1) >= 0.5) then
+ gicol_idiophone = gicol_musicbox
+ gicol_idiophone_other = gicol_kalimba
+ else
+ gicol_idiophone = gicol_kalimba
+ gicol_idiophone_other = gicol_musicbox
+ endif
+endop
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Sample playback initiation instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+instr note_idiophone_randtime
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone, mel_randomnote()
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ ;p3 = random(4, 8)
+
+ ipitch = round(random(1, 2)) * ipitchratio
+ ktime init random(0, idur)
+ aL, aR mincer a(port(ktime, 0.001, random(0, idur))), 1, ipitch, ifn, 0, 256 ;64
+
+ if (random:k(0, 1) > 0.1) then
+ ktime = random:k(0, idur)
+ endif
+
+
+ kamp linseg 1, p3*0.8, 1, p3*0.2, 0
+ aL *= kamp
+ aR *= kamp
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("delay1", aL*random(0, 0.3), aR*random(0, 0.3))
+ endif
+
+ bus_mix("reverb1", aL*random(0.2, 0.8), aR*random(0.2, 0.8))
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL*0.6, aR*0.6)
+ endif
+
+ bus_mix("master", aL, aR)
+endin
+
+
+/*
+ Idiophone chord
+
+ p4 one note (0 = play one note, 1 = play chord)
+*/
+instr phrase_idiophone1
+ ionenote = p4
+
+ if (ionenote == 1) then
+ knote init mel_randomnote() + (round(random(-2, 4)) * 12)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ ifreqstart = random(10, 30)
+ ifreqend = random(2, 15)
+ else
+ ifreqstart = random(2, 10)
+ ifreqend = random(10, 30)
+ endif
+ kfreq linseg ifreqstart, p3, ifreqend
+ kamp linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+
+ ktrig metro kfreq
+ if (ktrig == 1) then
+ if (ionenote != 1) then
+ knote = mel_randomnote:k() + (round:k(random:k(-2, 4)) * 12)
+ endif
+ schedulek("note_idiophone1", random:k(0, 0.1), 0.1, min:k(knote, 127), kamp*2)
+ endif
+endin
+
+
+/*
+ Idiophone chord using portamento note frequencies
+
+ p4 one note (0 = play one note, 1 = play chord)
+*/
+instr phrase_idiophone2
+ ionenote = p4
+ ilen = mel_length() * random(1, 10)
+ p3 = ilen
+
+ if (ionenote == 1) then
+ itlen = table:i(0, gimel_current_notes)
+ index = round(random(1, itlen-1))
+ kindex init index
+ knote init table(index, gimel_current_notes)
+ knoteaugment init (round(random(-2, 4)) * 12)
+ endif
+
+ kfreq linseg random(20, 60), ilen, random(2, 10)
+
+ kamp linseg 1, p3, 0
+ if (random(0, 1) > 0.5) then
+ kamp = 1-kamp
+ endif
+
+ ktrig metro kfreq
+ if (ktrig == 1) then
+ if (ionenote != 1) then
+ klen = table:k(0, gimel_current_notes)
+ kindex = round:k(random:k(1, klen-1))
+ knote = table:k(kindex, gimel_current_notes)
+ knoteaugment = (round:k(random:k(-2, 4)) * 12)
+ endif
+
+ kportfreq = table:k(kindex-1, gimel_freqs)
+ kportamp = table:k(kindex-1, gimel_amps)
+
+ if (kportfreq != cpsmidinn:k(knote)) then
+ kscale = cpsmidinn:k(knote) / kportfreq
+ else
+ kscale = 1
+ endif
+ schedulek("note_idiophone2", random:k(0, 0.1), 1, min:k(knote+knoteaugment, 127), kamp*kportamp, kscale)
+ endif
+endin
+
+
+/*
+ Stretch idiophone chord
+
+ p4 mode (0 = flipflop loop, 1 = linear loop)
+*/
+instr phrase_idiophone_stretch1
+ imode = p4
+ ilen = p3
+ index = 1
+ inoteaugment = min((round(random(-1, 4)) * 12), 127)
+ while (index < table:i(0, gimel_current_notes)) do
+ inote = table(index, gimel_current_notes)
+ schedule("note_idiophonestretch1", 0, ilen, inote + inoteaugment, imode)
+ index += 1
+ od
+ turnoff
+endin
+
+
+/*
+ Stretch idiophone box chord
+
+ p4 mode (0 = flipflop loop, 1 = linear loop)
+*/
+instr phrase_idiophone_stretch2
+ imode = p4
+ ilen = p3
+ index = 1
+ while (index < table:i(0, gimel_current_notes)) do
+ inote = table(index, gimel_current_notes)
+ schedule("note_idiophonestretch2", 0, ilen, inote, imode, 0, 1) ; no low pass, out to note_idiophonestretch2 bus, mincer read
+ schedule("note_idiophonestretch2", 0, ilen, inote-12, imode, 1, 0) ; low pass, master out, sndwarp read
+ index += 1
+ od
+ turnoff
+endin
+
+
+instr phrase_idiophone_stretch3
+ ksendDelay1 init 0
+ ksendReverb1 init 0.3
+ ksendPV1 init 0
+ kampx4 init 0
+ kamp linsegr 0, 0.5, 1, p3-0.5, 1, 1, 0
+
+ ; cpu saving: first arg 0 = sndwarp, 1 = mincer
+ aL1, aR1 portchord_sound gicol_idiophone, 0, 0.5, 512
+ aL2, aR2 portchord_sound gicol_idiophone, 0, 1, 1024
+ aL3, aR3 portchord_sound gicol_idiophone, 0, 2, 512
+
+ aL = (aL3 * portk(kampx4, 2) + (aL1 + aL2)) * kamp
+ aR = (aR3 * portk(kampx4, 2) + (aR1 + aR2)) * kamp
+
+ kchangemetro = metro(0.2)
+ if (kchangemetro == 1) then
+ if (random:k(0, 1) > 0.6) then
+ ksendDelay1 = random:k(0, 0.8)
+ endif
+
+ if (random:k(0, 1) > 0.6) then
+ ksendReverb1 = random:k(0.3, 0.8)
+ endif
+
+ if (random:k(0, 1) > 0.6) then
+ ksendPV1 = random:k(0, 0.8)
+ endif
+
+ if (random:k(0, 1) > 0.6) then
+ kampx4 = random:k(0, 1.5)
+ endif
+ endif
+
+ ksendDelay1p = port(ksendDelay1, 1)
+ ksendReverb1p = port(ksendReverb1, 1)
+ ksendPV1p = port(ksendPV1, 1)
+
+ bus_mix("delay1", aL*ksendDelay1p, aR*ksendDelay1p)
+ bus_mix("reverb1", aL*ksendReverb1p, aR*ksendReverb1p)
+ bus_mix("pvsamp1", aL*ksendPV1p, aR*ksendPV1p)
+ bus_mix("master", aL, aR)
+endin
+
+
+instr phrase_idiophone_stretch4
+ iamp = 0.5
+ klpf1 init 22050
+ klpf2 init 22050
+
+ ichangechance = random(0.1, 0.6)
+ icompressmode = 2 ; 0 = none ; 1 = harshwall ; 2 = normal
+ aL1, aR1 fnmi_gchord1 gicol_idiophone, 1, 3, icompressmode, ichangechance, 2, 0 ; 1 is mincer
+ aL2, aR2 fnmi_gchord1 gicol_idiophone, 1, 3, icompressmode, ichangechance, 1, 0
+
+ klpf1p port klpf1, 3
+ klpf2p port klpf2, 3
+ aL1 butterlp aL1, klpf1p
+ aR1 butterlp aR1, klpf1p
+ aL2 butterlp aL2, klpf2p
+ aR2 butterlp aR2, klpf2p
+ kchangemetro = metro(0.2)
+ if (kchangemetro == 1) then
+ if (random:k(0, 1) > 0.6) then
+ klpf1 = random:k(400, 22050)
+ endif
+
+ if (random:k(0, 1) > 0.6) then
+ klpf2 = random:k(400, 22050)
+ endif
+ endif
+
+ aL = (aL1 + aL2) * iamp
+ aR = (aR1 + aR2) * iamp
+
+
+ bus_mix("master", aL, aR)
+ bus_mix("reverb1", aL*0.4, aR*0.4)
+ bus_mix("pvsamp1", aL*0.1, aR*0.1)
+endin
+
+
+/*
+ Play a short glissando, possibly ascending or descending
+*/
+instr phrase_idiophone_gliss1
+ iamp = p4
+ ilen = table:i(0, gimel_current_notes)
+ itime = 0
+ imultreal = 1
+ imaxmult = 6
+ iascending = round(random(0, 1))
+ if (iascending == 1) then
+ iincrement = 1
+ istartindex = 1
+ imult = 1
+ else
+ iincrement = -1
+ istartindex = ilen
+ imult = imaxmult
+ endif
+
+ while (imultreal <= imaxmult) do
+ indexreal = 1
+ index = istartindex
+ while (indexreal < ilen) do
+ inote = (table:i(index, gimel_current_notes)-12)+(12*imult)
+ if (inote >= 127 || inote <= 0) then
+ goto complete
+ endif
+ schedule("note_idiophone1", itime, 0.1, inote, iamp, gicol_idiophone_other)
+ itime += random(0.05, 0.1)
+ indexreal += 1
+ index += iincrement
+ od
+ imult += iincrement
+ imultreal += 1
+ od
+complete:
+ turnoff
+endin
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Transition instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+instr transition_idiophone_randtime
+ iriseratio = p4
+ kamp expseg 0.00001, p3*iriseratio, 1, p3*(1-iriseratio), 0.00001
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone_other, mel_randomnote()
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ ipitch = round(random(1, 2)) * ipitchratio
+ ktime init random(0, idur)
+ aL, aR mincer a(port(ktime, 0.001, random(0, idur))), 1, ipitch, ifn, 0, 256 ;64
+
+ if (random:k(0, 1) > 0.1) then
+ ktime = random:k(0, idur)
+ endif
+
+ aL *= kamp * 3
+ aR *= kamp * 3
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("delay1", aL*random(0, 0.3), aR*random(0, 0.3))
+ endif
+
+ bus_mix("reverb1", aL*random(0.4, 0.8), aR*random(0.4, 0.8))
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL*0.6, aR*0.6)
+ endif
+
+ bus_mix("master", aL, aR)
+endin
+
+
+instr transition_idiophone_gliss1
+ iriseratio = p4
+ kamp expseg 0.00001, p3*iriseratio, 1, p3*(1-iriseratio), 0.00001
+ kmetro metro 20
+ kmult init 0
+ kincrement init 1
+ kindex init 1
+
+ if (kmetro == 1) then
+ knote = min:k((table:k(kindex, gimel_current_notes))+(12*kmult), 127)
+ schedulek("note_idiophone1", random:k(0, 0.1), 0.1, knote, kamp*3.5, gicol_idiophone_other)
+
+ kmaxnotes = table:k(0, gimel_current_notes)
+ if ((kindex < kmaxnotes - 1 && kincrement == 1) || (kindex > 1 && kincrement == -1)) then
+ kindex += kincrement
+ else
+ kindex = (kincrement == 1) ? 1 : kmaxnotes - 1
+ kmult += kincrement
+ if (kmult >= 4) then
+ kmult = 4
+ kincrement = -1
+ elseif (kmult < 0) then
+ kmult = 0
+ kincrement = 1
+ endif
+ endif
+
+ endif
+endin
+
+
+instr transition_idiophone_stretch1
+ iriseratio = p4
+ kamp expseg 0.00001, p3*iriseratio, 1, p3*(1-iriseratio), 0.00001
+
+ inotestart = mel_randomnote()
+ inoteend = mel_randomnote()
+
+ if (random(0, 1) >= 0.5) then
+ inotestart += 12
+ endif
+
+ if (random(0, 1) >= 0.5) then
+ inoteend += 12
+ endif
+
+
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone_other, inotestart
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ istart = random(0.01, 0.1)
+ iend = random(istart+0.05, 0.3)
+ atime = abs(oscil(iend-istart, random(0.001, 0.1), gifnSine, random(0, 1)))
+ atime *= idur
+ apitchratio line ipitchratio, p3, (ipitchratio * (cpsmidinn(inoteend) / cpsmidinn(inotestart)))
+
+ isndwarpadjust = (ftsr(ifn) / sr) ; adjustment for sndwarp required
+ aL, aR sndwarpst kamp, atime, apitchratio*isndwarpadjust, ifn, istart, 4096, 128, 2, gifnHalfSine, 1
+
+ bus_mix("reverb1", aL*random(0, 0.8), aR*random(0, 0.8))
+ bus_mix("pvsamp1", aL*random(0, 0.2), aR*random(0, 0.2))
+ bus_mix("master", aL*1.7, aR*1.7)
+endin
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Sample playback note instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/*
+ Play idiophone note with stochastic transforms and sends
+
+ p4 midi note number
+ p5 amplitude (0 to 1)
+ p6 optional collection, defaults to gicol_idiophone
+*/
+instr note_idiophone1
+ inote = p4
+ iamp = p5 * 0.2
+ icollection = (p6 == 0) ? gicol_idiophone : p6
+ iamp *= random(0.6, 1)
+ ifileid, ipitchratio sounddb_mel_nearestnote icollection, inote
+
+ if (active:i(p1) < 50 && (abs(ipitchratio) > 1.8 || random(0, 1) > 0.8)) then
+ iloscilratio = 1
+ idopvs = 1
+ else
+ iloscilratio = ipitchratio
+ idopvs = 0
+ endif
+
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ p3 = idur / iloscilratio
+ kamp linseg iamp, p3*0.6, iamp, p3*0.4, 0
+ ;ktime line random(0, 0.2), p3, p3
+ ;aL, aR sndwarpst kamp, ktime, iloscilratio, isound[0], 0, 441*random(1, 100), 44*random(1, 10), 4, gifnHalfSine, 1
+ aL, aR loscil kamp, iloscilratio, ifn, 1
+
+ if (idopvs == 1) then
+ if (random(0, 1) > 0.75) then
+ ipitchratio *= pow(2, int(random(1, 4)))
+ endif
+ ir = 512
+ fL1 pvsanal aL, ir, ir/2, ir, 1
+ fR1 pvsanal aR, ir, ir/2, ir, 1
+ fL2 pvscale fL1, ipitchratio
+ fR2 pvscale fR1, ipitchratio
+ aL pvsynth fL2
+ aR pvsynth fR2
+ endif
+
+ ipan = random(0, 1)
+ aL *= ipan
+ aR *= (1-ipan)
+
+ if (random(0, 1) > 0.6) then
+ aL pareq aL, random(100, 4000), random(0.3, 1.1), 0.7
+ aR pareq aR, random(100, 4000), random(0.3, 1.1), 0.7
+ endif
+
+ if (random(0, 1) > 0.9) then
+ bus_mix("delay1", aL*random(0.1, 0.4), aR*random(0.1, 0.4))
+ endif
+
+ if (random(0, 1) > 0.8) then
+ ;krenv linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ bus_mix("reverb1", aL*random(0.1, 0.7), aR*random(0.1, 0.7))
+ endif
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL*random(0.5, 0.8), aR*random(0.5, 0.8))
+ endif
+
+ bus_mix("master", aL, aR)
+
+endin
+
+
+
+
+/*
+ Play idiophone note with stochastic transforms and sends
+
+ p4 midi note number
+ p5 amplitude (0 to 1)
+ p6 pitchscale: amount to scale pitch by (for portamento augmentation)
+*/
+instr note_idiophone2
+ inote = p4
+ iamp = p5 * 0.2
+ ipitchscale = p6
+
+ iamp *= random(0.6, 1)
+ kamp linseg iamp, p3*0.6, iamp, p3*0.4, 0
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone, inote
+
+ kpitchratio init ipitchratio * ipitchscale
+
+ kpitchenv = abs:k(oscil:k(random(0.001, 0.01), random(0.1, 4), gifnSine, random(0, 1))) + 1
+ kpitchratio += kpitchenv
+
+ if (kpitchratio > 1.8 || random(0, 1) > 0.8) then
+ kloscilratio init 1
+ idopvs = 1
+ else
+ kloscilratio = kpitchratio
+ idopvs = 0
+ endif
+
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ p3 = idur
+ ;ktime line random(0, 0.2), p3, p3
+ ;aL, aR sndwarpst kamp, ktime, iloscilratio, isound[0], 0, 441*random(1, 100), 44*random(1, 10), 4, gifnHalfSine, 1
+ aL, aR loscil kamp, kloscilratio, ifn, 1
+
+ if (idopvs == 1) then
+ if (random(0, 1) > 0.5) then
+ kpitchratio *= pow(2, int(random(1, 4)))
+ endif
+ ir = 512
+ fL1 pvsanal aL, ir, ir/4, ir, 1
+ fR1 pvsanal aR, ir, ir/4, ir, 1
+ fL2 pvscale fL1, kpitchratio
+ fR2 pvscale fR1, kpitchratio
+ aL pvsynth fL2
+ aR pvsynth fR2
+ endif
+
+ ipan random 0, 1
+ aL *= ipan
+ aR *= (1-ipan)
+
+ if (random(0, 1) > 0.8) then
+ kdenv linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ bus_mix("delay1", aL*kdenv, aR*kdenv)
+ endif
+
+ if (random(0, 1) > 0.8) then
+ krenv linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ bus_mix("reverb1", aL*krenv, aR*krenv)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL, aR)
+ endif
+
+ bus_mix("master", aL, aR)
+
+endin
+
+
+
+/*
+ Play held/stretched idiophone note with stochastic transforms and sends
+
+ p4 midi note number
+ p5 mode (0 = forwards and reverse, 1 = linear forwards)
+*/
+instr note_idiophonestretch1
+ inote = p4
+ imode = p5
+ iamp = 0.6
+ kamp linseg 0, p3*0.2, iamp, p3*0.6, iamp, p3*0.2, 0
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone, inote
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ ipitchratio *= (ftsr(ifn) / sr) ; adjustment for sndwarp required
+
+ if (imode == 0) then
+ istart = random(0, 0.3)
+ iend = random(istart+0.1, 0.5)
+ atime = abs(oscil(iend-istart, random(0.001, 0.1), gifnSine, random(0, 1)))
+ else
+ istart = 0
+ iend = random(0.1, 0.99)
+ atime = (phasor(random(10, 40)) * (iend-istart))
+ endif
+
+
+ if (random(0, 1) > 0.5) then
+ alfo = oscil(random(0.0001, 0.0009), random(4, 10)) + 1
+ apitchratio = ipitchratio * alfo
+ else
+ apitchratio init ipitchratio
+ endif
+
+ atime *= idur
+
+ aL, aR sndwarpst kamp, atime, apitchratio, ifn, istart, 441*random(1, 100), 44*random(1, 10), 8, gifnHalfSine, 1
+
+ aL butterhp aL, 150
+ aR butterhp aR, 150
+
+ if (random(0, 1) > 0.5) then
+ atemp = aL
+ aL = aR
+ aR = atemp
+ endif
+
+ if (random(0, 1) > 0.2) then
+ krenv linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ bus_mix("reverb1", aL*krenv, aR*krenv)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL, aR)
+ endif
+
+ bus_mix("master", aL, aR)
+endin
+
+
+
+
+instr note_idiophonestretch2
+ inote = p4
+ imode = p5
+ ilpmode = p6
+ ireadmode = p7 ; 0 = sndwarp, 1 = mincer
+ iamp = 0.4
+ kamp linseg 0, p3*0.2, iamp, p3*0.6, iamp, p3*0.2, 0
+ ifileid, ipitchratio sounddb_mel_nearestnote gicol_idiophone, inote
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ if (imode == 0) then
+ istart = random(0.05, 0.2)
+ iend = random(istart+0.1, 0.8)
+ atime = abs(oscil(iend-istart, random(0.001, 0.1), gifnSine, random(0, 1)))
+ else
+ istart = 0
+ iend = random(0.1, 0.99)
+ atime = (phasor(random(10, 40)) * (iend-istart))
+ endif
+
+ if (random(0, 1) > 0.4) then
+ alfo = oscil(random(0.0001, 0.001), random(4, 10)) + 1
+ apitchratio = ipitchratio * alfo
+ else
+ apitchratio init 1
+ endif
+
+ atime *= idur
+
+ if (ireadmode == 0) then
+ isndwarpadjust = (ftsr(ifn) / sr) ; adjustment for sndwarp required
+ aL, aR sndwarpst kamp, atime, apitchratio*isndwarpadjust, ifn, istart, 4096, 128, 2, gifnHalfSine, 1
+ else
+ aL, aR mincer atime+istart, kamp, k(apitchratio), ifn, 0, 512
+ endif
+
+ ipan = random(0, 1)
+ aL *= (1-ipan)
+ aR *= (ipan)
+
+ aLh butterhp aL, 150
+ aRh butterhp aR, 150
+
+
+ if (random(0, 1) > 0.8) then
+ krenv linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ bus_mix("reverb1", aLh*krenv, aRh*krenv)
+ endif
+
+ if (random(0, 1) > 0.7) then
+ bus_mix("pvsamp1", aLh, aRh)
+ endif
+
+ if (ilpmode == 0) then
+ bus_mix("note_idiophonestretch2", aLh, aRh)
+ elseif (ilpmode == 1) then
+ aL butterlp aL, 500
+ aR butterlp aR, 500
+ bus_mix("master", aL*0.8, aR*0.8)
+ endif
+endin
+
+
+
+
+#end
diff --git a/site/app/partialemergence/instruments_synthesis.inc b/site/app/partialemergence/instruments_synthesis.inc new file mode 100644 index 0000000..9053c11 --- /dev/null +++ b/site/app/partialemergence/instruments_synthesis.inc @@ -0,0 +1,108 @@ +#ifndef INC_SYNTHESIS_INSTR
+#define INC_SYNTHESIS_INSTR ##
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence
+ by Richard Knight 2022
+
+ Installation submission for the International Csound Conference 2022
+
+ Synthesis instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/*
+ Bass note 1
+*/
+instr note_bass1
+ index = (p4 == -1) ? random(0, 2) : p4
+ kfreq table index, gimel_freqs
+ kfreq *= 0.25
+ kamp table index, gimel_amps
+ kenv linseg 0, p3*0.01, 1, p3*0.99, 1
+ kamp *= kenv * 0.19
+
+ aphs1 phasor kfreq/2
+ aphs2 phasor kfreq/2
+ koda = abs(oscil(random(0, 2), random(0, 1)))
+ a1 tablei aphs1, gifnSine, 1, 0, 1
+
+ av1L = abs:a(oscil:a(3, 0.1))
+ aL tablei (aphs2+a1)+av1L+koda, gifnSine, 1, 0, 1
+ av1R = abs:a(oscil:a(4, 0.05))
+ aR tablei (aphs2+a1)+av1R+koda, gifnSine, 1, 0, 1
+ kfi linseg 0, p3*0.2, 1, p3*0.8, 1
+
+ ilpfreq = random(100, 1000)
+ aL butterlp aL, ilpfreq
+ aR butterlp aR, ilpfreq
+
+ if (random(0, 1) > 0.4) then
+ kamp *= abs:k(oscil:k(0.9, random(0.01, 0.1))) + 0.1
+ endif
+
+ bus_mix("reverb1", aL*kamp*0.7, aR*kamp*0.7)
+ bus_mix("master", aL*kamp, aR*kamp)
+endin
+
+
+
+
+opcode fmsxosc, a, k
+ kfreq xin
+ ifn = gifnSine
+ kfreqoffset = abs:k(oscil:k(1, 0.001))
+
+ aoda = abs:a(oscil:a(random(0.01, 1), random(0.001, 1)))
+ aphs1 phasor kfreq
+ aphs2 phasor kfreq + kfreqoffset
+ a1 tablei aphs1, ifn, 1, 0, 1
+ a2 tablei aphs2, ifn, 1, 0, 1
+ av = abs:a(oscil:a(0.1, 0.01, gifnSine, random(0, 1)))
+ aa1 tablei (aphs1+a1)+av+aoda, gifnSine, 1, 0, 1
+ aa2 tablei (aphs2+a2)+av+aoda, gifnSine, 1, 0, 1
+
+ adelt = abs:a(oscil:a(50, 0.005))
+ aa1 vdelay aa1, adelt, 50
+ xout (aa1 + aa2)
+endop
+
+
+instr note_bass2
+ index = p4 + 1
+ ifreq = cpsmidinn(tab_i(index, gimel_current_notes))
+
+ ifreq *= 0.125
+
+
+ if (random(0, 1) < 0.5) then
+ ifreq *= 0.5
+ endif
+
+ aL fmsxosc ifreq
+ aR fmsxosc ifreq
+
+ kamp = abs:k(oscil:k(1, random(0.005, 0.01), gifnSine, random(0, 0.5)))
+ klpf = abs:k(oscil:k(6000, random(0.009, 0.05), gifnSine, 0.2)) + 100
+
+ aL = butterlp(aL*kamp, klpf)
+ aR = butterlp(aR*kamp, klpf)
+
+ aL pareq aL, 100, 0.1, 0.7
+ aR pareq aR, 100, 0.1, 0.7
+
+ kenv linseg 0, p3*0.1, 1, p3*0.9, 0
+
+ if (random(0, 1) > 0.4) then
+ kenv *= abs:k(oscil:k(0.9, random(0.01, 0.1))) + 0.1
+ endif
+
+ aL *= 0.19 * kenv
+ aR *= 0.19 * kenv
+
+ bus_mix("master", aL, aR)
+endin
+
+
+#end
diff --git a/site/app/partialemergence/instruments_water.inc b/site/app/partialemergence/instruments_water.inc new file mode 100644 index 0000000..bf38576 --- /dev/null +++ b/site/app/partialemergence/instruments_water.inc @@ -0,0 +1,240 @@ +#ifndef INC_WATER_INSTR
+#define INC_WATER_INSTR ##
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence
+ by Richard Knight 2022
+
+ Installation submission for the International Csound Conference 2022
+
+ Water instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "/soundxdb.udo"
+#include "/array_tools.udo"
+#include "/sequencing_melodic.udo"
+#include "/sequencing_melodic_portamento.udo"
+#include "/bussing.udo"
+#include "/frequency_tools.udo"
+#include "/wavetables.udo"
+
+; sound collections
+gisnd_waterpaddling[] sounddb_getcollection "Water.Paddling"
+gisnd_waterdrop[] sounddb_getcollection "Water.Droplet"
+
+
+instr play_waterpaddling1
+ ifileid = arr_random(gisnd_waterpaddling)
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+
+ kfreqshift init -100
+ ipitch = random(0.5, 1.2)
+ ktime init random(0, idur)
+ aL, aR mincer a(port(ktime, 0.1, random(0, idur))), 1, ipitch, ifn, 0, pow(2, round(random(4, 7))) ;64
+
+ aL, aR freqshift1 aL, aR, port(kfreqshift, 0.2)
+
+ if (random:k(0, 1) > 0.2) then
+ ktime = random:k(0, idur)
+ endif
+
+ if (random:k(0, 1) > 0.2) then
+ kfreqshift = random(-1000, -100)
+ endif
+
+ kamp linseg 1, p3*0.8, 1, p3*0.2, 0
+ aL *= kamp * 1.8
+ aR *= kamp * 1.8
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("delay1", aL*random(0, 0.3), aR*random(0, 0.3))
+ endif
+
+ if (random(0, 1) > 0.3) then
+ bus_mix("reverb1", aL*random(0.2, 0.8), aR*random(0.2, 0.8))
+ endif
+
+ if (random(0, 1) > 0.5) then
+ bus_mix("pvsamp1", aL*0.6, aR*0.6)
+ endif
+
+ bus_mix("master", aL, aR)
+endin
+
+
+instr _phrase_waterbubbler1_item
+ ipitch = p4
+ iamp = p5
+ ioutmain = p6
+ ifileid = arr_random(gisnd_waterdrop)
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ p3 = idur / ipitch
+ kamp linseg 1, p3*0.8, 1, p3*0.2, 0
+ kamp *= iamp
+ aL, aR loscil kamp, ipitch, ifn, 1
+ aL, aR freqshift1 aL, aR, random(-1000, -400)
+ ipan = random(0, 1)
+
+ if (random(0, 1) > 0.5) then
+ aLr resony aL, table:k(0, gimel_freqs)*2, 4, 16, 10
+ aRr resony aL, table:k(0, gimel_freqs)*2, 4, 16, 10
+ aL balance aLr, aL
+ aR balance aRr, aR
+ aL dcblock aL
+ aR dcblock aR
+ endif
+
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("delay1", aL*0.2, aR*0.2)
+ endif
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("reverb1", aL*0.5, aR*0.5)
+ endif
+
+ if (random(0, 1) > 0.8) then
+ bus_mix("pvsamp1", aL, aR)
+ endif
+
+ Schannel = (ioutmain == 1) ? "main" : "phrase_waterbubbler"
+ bus_mix(Schannel, aL*(1-ipan), aR*ipan)
+endin
+
+
+instr phrase_waterbubbler1
+ ioutmain = p4
+ kamp linseg 0, p3*0.1, 1, p3*0.8, 1, p3*0.1, 0
+ iamp = random(0.25, 0.5)
+ kamp *= iamp
+ kfreq = abs:k(oscil:k(30, 0.01)) + 10
+ kmetro metro kfreq
+ if (kmetro == 1) then
+ schedulek("_phrase_waterbubbler1_item", random:k(0, 0.2), 1, random:k(0.8, 1.2), random:k(0.5, 1)*kamp, ioutmain)
+ endif
+endin
+
+
+instr note_drop1
+ ifileid = arr_random(gisnd_waterdrop)
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ ipitch = random(0.6, 1.3)
+ p3 = idur / ipitch
+ aL, aR loscil 1, ipitch, ifn, 1
+ kamp linseg 1, p3*0.9, 1, p3*0.1, 0
+ iamp = random(0.7, 1)
+ ipan = random(0, 1)
+ aL *= kamp * iamp * ipan
+ aR *= kamp * iamp * (1-ipan)
+ bus_mix("pvsamp1", aL*random(0, 0.3), aR*random(0, 0.3))
+ bus_mix("reverb1", aL*random(0, 0.2), aR*random(0, 0.2))
+ bus_mix("master", aL, aR)
+endin
+
+
+instr _phrase_droproll1_item
+ ifileid = arr_random(gisnd_waterdrop)
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ ipitch = random(0.1, 1.3)
+ p3 = idur / ipitch
+ aL, aR loscil 1, ipitch, ifn, 1
+ kamp linseg 1, p3*0.9, 1, p3*0.1, 0
+ ipan = random(0, 1)
+ aL *= kamp * ipan
+ aR *= kamp * (1-ipan)
+ bus_mix("droproll1_item", aL, aR)
+ bus_mix("pvsamp1", aL*random(0, 0.5), aR*random(0, 0.5))
+endin
+
+instr phrase_droproll1
+ iamp = p4
+ ifreq1 = random(0.00001, 20)
+ kmetrofreq expseg ifreq1, p3, 19.99 - ifreq1
+ klpf linseg random(4000, 22050), p3, random(4000, 22050)
+ kamp linseg 0, p3*0.3, 1, p3*0.4, 1, p3*0.3, 0
+ kmetro metro kmetrofreq
+ if (kmetro == 1) then
+ schedulek("_phrase_droproll1_item", random:k(0, 0.2), 1)
+ endif
+
+ aL, aR bus_read "droproll1_item"
+ aL butterlp aL, klpf
+ aR butterlp aR, klpf
+ aL *= kamp * 0.7 * iamp
+ aR *= kamp * 0.7 * iamp
+ bus_mix("reverb1", aL*0.2, aR*0.2)
+ bus_mix("master", aL, aR)
+endin
+
+
+instr transition_droplets1
+ iriseratio = p4
+ kamp expseg 0.00001, p3*iriseratio, 1, p3*(1-iriseratio), 0.00001
+ kmetro metro 30
+ if (kmetro == 1) then
+ schedulek("_phrase_droproll1_item", random:k(0, 0.2), 1)
+ endif
+
+ aL, aR bus_read "droproll1_item"
+ aL *= kamp * 2.5
+ aR *= kamp * 2.5
+ bus_mix("reverb1", aL*0.43, aR*0.43)
+ bus_mix("master", aL, aR)
+endin
+
+
+instr transition_waterbubbler1
+ ioutmain = p4
+ iriseratio = p4
+ kamp expseg 0.00001, p3*iriseratio, 1, p3*(1-iriseratio), 0.00001
+ kfreq = abs:k(oscil:k(30, 0.01)) + 10
+ kmetro metro kfreq
+ if (kmetro == 1) then
+ schedulek("_phrase_waterbubbler1_item", random:k(0, 0.2), 1, random:k(0.8, 1.2), random:k(0.5, 1)*kamp, 1)
+ endif
+endin
+
+
+instr phrase_dropstretch1
+ ireadpitch = p4
+ ido_reson = p5
+ ifades = p6
+ iresonfreqratio = p7
+ ifileid = arr_random(gisnd_waterdrop)
+ ifn = gisounddb[ifileid][0]
+ idur = gisounddb[ifileid][2]
+ istart = random(0, idur*0.2)
+ iend = random(idur*0.4, idur*0.8) ; 0.3, 0.4
+ atime = abs:a(oscil:a(iend-istart, random(0.001, 0.1), gifnSine, random(0, 1)))
+ kenv = abs:k(oscil:k(0.8, random(0.01, 0.1), gifnSine, random(0, 1))) + 0.2
+
+ aL, aR sndwarpst 1, atime, ireadpitch, ifn, istart, 441*random(1, 10), 44*random(1, 10), 8, gifnHalfSine, 1
+
+ if (ifades == 1) then
+ kamp linseg 0, p3*0.25, 1, p3*0.5, 1, p3*0.25, 0
+ else
+ kamp linsegr 1, p3, 1, 2, 0
+ endif
+ aL *= kamp * kenv
+ aR *= kamp * kenv
+
+ if (ido_reson == 1) then
+ aLr resony aL, table:k(0, gimel_freqs)*2*iresonfreqratio, 2, 16, 10
+ aRr resony aR, table:k(1, gimel_freqs)*2*iresonfreqratio, 2, 16, 10 ; *4*
+ aL balance butterhp(aLr, 50), aL
+ aR balance butterhp(aRr, 50), aR
+ endif
+
+ aL pareq aL, 1000, 0.4, 0.75
+ aR pareq aR, 1000, 0.4, 0.75
+
+ bus_mix("master", aL, aR)
+endin
+
+
+#end
diff --git a/site/app/partialemergence/partialemergence.csd b/site/app/partialemergence/partialemergence.csd new file mode 100644 index 0000000..5be063c --- /dev/null +++ b/site/app/partialemergence/partialemergence.csd @@ -0,0 +1,238 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+-m0
+-d
+</CsOptions>
+<CsLicence>
+Creative Commons Attribution-NonCommercial-ShareAlike (CC BY-NC-SA)
+</CsLicence>
+<CsShortLicence>
+2
+</CsShortLicence>
+<CsInstruments>
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence: Web port
+ by Richard Knight 2022, 2025
+
+ Installation submission for the International Csound Conference 2022
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+sr = 44100
+ksmps = 128
+nchnls = 2
+0dbfs = 2.5
+seed 0
+
+; set DEBUG to enable lag detection and linear progression
+;#define DEBUG ##
+
+; initial progression; macro used by sequencing_melodic_persistence.udo
+#define MEL_INITPATH #/progression1.fnmlmel#
+
+; SONICS includes
+#include "/soundexport.xdb" ; sound database extract
+#include "/soundxdb.udo"
+#include "/array_tools.udo"
+#include "/sequencing.udo"
+#include "/sequencing_melodic.udo"
+#include "/sequencing_melodic_portamento.udo"
+#include "/sequencing_melodic_persistence.pe.udo"
+#include "/bussing.udo"
+#include "/instrument_sineblips.udo"
+#ifdef DEBUG
+#include "/lagdetect.udo"
+#endif
+
+; installation specific includes
+#include "/effects_global.inc"
+#include "/instruments_water.inc"
+#include "/instruments_idiophone.inc"
+#include "/instruments_hybrid.inc"
+#include "/instruments_synthesis.inc"
+#include "/sequence_sections.inc"
+
+
+/*
+ Sections:
+ Array index of dimension 1 corresponds to "sequencer_s%d" instrument, where %d is the index
+
+ Array index of dimension 2:
+ 0 duration minimum
+ 1 duration maximum
+ 2 follow section A
+ 3 follow section A/B chance ratio (0 = always A, 1 = always B)
+ 4 action section 2
+*/
+gisections[][] init 18, 5
+
+#ifdef DEBUG
+gisections fillarray\ ; test linear progression
+ 60, 90, 1, 0.3, 1 ,\ ; 0 idiophone single notes
+ 60, 90, 2, 0.3, 2 ,\ ; 1 idiophone chords, alternate mel sections with stretch chords
+ 60, 90, 3, 0.5, 3 ,\ ; 2 bass, idiophone single notes
+ 60, 90, 4, 0.2, 4 ,\ ; 3 bass, idiophone chords
+ 60, 90, 5, 0.3, 5 ,\ ; 4 resonated drop stretch and idiophone notes/stretch
+ 60, 90, 6, 0.3, 6 ,\ ; 5 resonated drop stretch
+ 60, 90, 7, 0.5, 7 ,\ ; 6 tuned drops, stretch chords
+ 60, 90, 8, 0.7, 8 ,\ ; 7 tuned drops, stretch chords more prominent
+ 60, 90, 9, 0.7, 9 ,\ ; 8 drop stretch
+ 60, 90, 10, 0.5, 10,\ ; 9 low portamento chords
+ 60, 90, 11, 0.5, 11,\ ; 10 glitch chord, sines, drops
+ 60, 90, 12, 0.5, 12,\ ; 11 water drops, low minimal chords, resonated drops, stretch water
+ 60, 90, 13, 0.5, 13,\ ; 12 minimal, resonated drops
+ 60, 90, 14, 0.5, 14,\ ; 13 reson drops buildup
+ 60, 90, 15, 0.5, 15,\ ; 14 low drop resonated portamento chords
+ 60, 90, 16, 0.2, 16,\ ; 15 water to idiophone
+ 60, 90, 17, 0.5, 17,\ ; 16 idiophone/drop resonated chords, slower
+ 30, 60, 0, 0.5, 0 ; 17 water paddling hits, resonated drop stretch
+
+#else
+gisections fillarray\ ; live progression
+ 43 ,95 ,1 ,0.2 ,2 ,\ ; 0 idiophone single notes
+ 63 ,125 ,2 ,0.3 ,12 ,\ ; 1 idiophone chords, alternate mel sections with stretch chords
+ 42 ,110 ,3 ,0.2 ,4 ,\ ; 2 bass, idiophone single notes
+ 76 ,134 ,4 ,0.2 ,5 ,\ ; 3 bass, idiophone chords
+ 61 ,92 ,5 ,0.15 ,13 ,\ ; 4 resonated drop stretch and idiophone notes/stretch
+ 57 ,93 ,11 ,0.2 ,6 ,\ ; 5 resonated drop stretch
+ 47 ,105 ,5 ,0.8 ,7 ,\ ; 6 tuned drops, stretch chords
+ 61 ,101 ,14 ,0.7 ,8 ,\ ; 7 tuned drops, stretch chords more prominent
+ 67 ,105 ,5 ,0.8 ,9 ,\ ; 8 drop stretch
+ 53 ,113 ,13 ,0.4 ,1 ,\ ; 9 low portamento chords
+ 65 ,124 ,15 ,0.3 ,0 ,\ ; 10 glitch chord, sines, drops
+ 58 ,113 ,8 ,0.5 ,12 ,\ ; 11 water drops, low minimal chords, resonated drops, stretch water
+ 81 ,153 ,15 ,0.5 ,14 ,\ ; 12 minimal, resonated drops
+ 69 ,112 ,17 ,0.8 ,10 ,\ ; 13 reson drops buildup
+ 62 ,103 ,3 ,0.4 ,9 ,\ ; 14 low drop resonated portamento chords
+ 54 ,101 ,16 ,0.2 ,5 ,\ ; 15 water to idiophone
+ 71 ,116 ,17 ,0.4 ,4 ,\ ; 16 idiophone/drop resonated chords, slower
+ 33 ,66 ,6 ,0.5 ,7 ; 17 water paddling hits, resonated drop stretch
+#endif
+
+; initial section
+ginitsection = 0
+
+
+; possible melodic progressions
+gSprogressions[] fillarray "progression1.fnmlmel", "progression2.fnmlmel", "progression3.fnmlmel"
+gicurrentprogression init 0
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Control instruments
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+/*
+ Call all performance instruments accordingly
+*/
+instr boot
+ gkseq_tempo init 100
+ SbootInstrs[] fillarray "audio_output", "sequencer_main", "global_delay1", "global_delay2", "global_reverb1", "global_pvsamp1"
+ index = 0
+ while (index < lenarray(SbootInstrs)) do
+ schedule(SbootInstrs[index], 0, -1)
+ index += 1
+ od
+ gimel_portamento_beatratio = 4
+ turnoff
+endin
+
+
+
+/*
+ Master output mastering/processing
+*/
+instr audio_output
+ ; gkmastervolume
+ aL, aR bus_read "master"
+ iexcite = 1
+ aL += (exciter(aL, 3000, 20000, 10, 10)*iexcite)
+ aR += (exciter(aR, 3000, 20000, 10, 10)*iexcite)
+ bus_masterout(aL, aR)
+endin
+
+
+/*
+ Set random melodic progression
+*/
+instr set_progression
+ index = int(random(0, lenarray(gSprogressions)))
+
+ ; only set if it differs from current
+ if (index != gicurrentprogression) then
+ gicurrentprogression = index
+ Sprogression = gSprogressions[index]
+ prints sprintf("Progression change: %s\n", Sprogression)
+ subinstrinit "mel_loadstate_fs", strcat("/", Sprogression)
+ endif
+ turnoff
+endin
+
+
+
+/*
+ Main section sequencer
+*/
+instr sequencer_main
+
+ ; set up initial instrument at init time
+ initduration = random(gisections[ginitsection][0], gisections[ginitsection][1])
+ ksection init ginitsection
+ ksectiontime init initduration
+ schedule(sprintf("sequencer_s%d", ginitsection), 0, initduration)
+ prints sprintf("Section %d\n", ginitsection)
+
+ ; react to section changes at k-rate
+ kabstime timeinsts
+ klaststarttime init 0
+
+ ; if current section time is up, schedule next
+ if (kabstime - klaststarttime >= ksectiontime) then
+
+ ; determine next section based on follow action threshold
+ kchance = random:k(0, 1)
+ if (kchance <= gisections[ksection][3]) then
+ ksection = gisections[ksection][4]
+ else
+ ksection = gisections[ksection][2]
+ endif
+
+ ; get duration between specified min and max
+ ksectiontime = random:k(gisections[ksection][0], gisections[ksection][1]) + random:k(0.5, 1)
+
+ ; schedule section subsequencer and print status
+ schedulek sprintfk("sequencer_s%d", ksection), 0, ksectiontime
+ printf "Section %d\n", ksection+random:k(1, 4), ksection
+
+ ; set a new chord progression if relevant
+ if (random:k(0, 1) >= 0.5) then
+ schedulek("set_progression", 0, 1)
+ endif
+
+ if (random:k(0, 1) > 0.5) then
+ seq_settempo(random:k(20, 100))
+ endif
+
+ klaststarttime = kabstime
+ endif
+
+#ifdef DEBUG
+ ; write lag detection report for debugging
+ if (lagdetect:k() == 1) then
+ fprintks "lagreport.txt", "Lag in section %d at %f\n", ksection, kabstime - klaststarttime
+ endif
+#endif
+
+endin
+
+</CsInstruments>
+<CsScore>
+f0 z
+i"boot" 0.5 1 ; delay to account for initial melodic progression load
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/partialemergence/progression1.fnmlmel b/site/app/partialemergence/progression1.fnmlmel new file mode 100644 index 0000000..7ca446d --- /dev/null +++ b/site/app/partialemergence/progression1.fnmlmel @@ -0,0 +1,499 @@ +======= TABLE 181 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 181
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+34.000000
+32.000000
+33.000000
+3.000000
+35.000000
+26.000000
+60.000000
+30.000000
+40.000000
+37.000000
+21.000000
+45.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 182 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 182
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+62.000000
+64.000000
+63.000000
+62.000000
+65.000000
+64.000000
+55.000000
+61.000000
+59.000000
+60.000000
+51.000000
+61.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 183 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 183
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+16.000000
+16.000000
+16.000000
+16.000000
+16.000000
+16.000000
+5.000000
+6.000000
+5.000000
+6.000000
+7.000000
+6.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 184 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 184
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 185 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 185
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+2.000000
+3.000000
+1.000000
+3.000000
+0.000000
+0.000000
+1.000000
+1.000000
+0.000000
+1.000000
+1.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 186 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 186
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.300030
+0.250025
+0.271427
+0.264326
+0.278528
+0.185719
+0.497453
+0.837786
+0.111774
+0.788161
+0.979394
+0.297689
+0.000000
+---------END OF TABLE---------------
+======= TABLE 187 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 187
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 188 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 188
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 189 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 189
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.988438
+0.803298
+0.267835
+0.115002
+0.595937
+0.194793
+0.411357
+0.076671
+0.079459
+0.619064
+0.151164
+0.298788
+0.000000
+---------END OF TABLE---------------
+======= TABLE 190 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 190
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.557413
+0.136986
+0.224130
+0.863673
+0.276111
+0.312208
+0.743491
+0.531141
+0.294368
+0.661400
+0.132212
+0.595441
+0.000000
+---------END OF TABLE---------------
+======= TABLE 191 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 191
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.537405
+0.751374
+0.839415
+0.150858
+0.332917
+0.607242
+0.670816
+0.179500
+0.587496
+0.202448
+0.185102
+0.186244
+0.000000
+---------END OF TABLE---------------
+======= TABLE 192 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 192
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.575499
+0.750085
+0.812289
+0.618174
+0.608552
+0.745880
+0.431868
+0.373672
+0.769305
+0.505552
+0.333007
+0.579707
+0.000000
+---------END OF TABLE---------------
+======= TABLE 180 size: 4 values ======
+flen: 4
+lenmask: 3
+lobits: 22
+lomask: 4194303
+lodiv: 0.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 4
+nchnls: 1
+fno: 180
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+3.000000
+4.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
diff --git a/site/app/partialemergence/progression2.fnmlmel b/site/app/partialemergence/progression2.fnmlmel new file mode 100644 index 0000000..f923471 --- /dev/null +++ b/site/app/partialemergence/progression2.fnmlmel @@ -0,0 +1,499 @@ +======= TABLE 181 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 181
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+28.000000
+22.000000
+38.000000
+3.000000
+26.000000
+22.000000
+60.000000
+30.000000
+40.000000
+37.000000
+21.000000
+45.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 182 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 182
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+62.000000
+60.000000
+64.000000
+59.000000
+60.000000
+62.000000
+55.000000
+61.000000
+59.000000
+60.000000
+51.000000
+61.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 183 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 183
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+16.000000
+16.000000
+16.000000
+16.000000
+16.000000
+16.000000
+5.000000
+6.000000
+5.000000
+6.000000
+7.000000
+6.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 184 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 184
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 185 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 185
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+3.000000
+3.000000
+2.000000
+0.000000
+3.000000
+2.000000
+0.000000
+1.000000
+1.000000
+0.000000
+1.000000
+1.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 186 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 186
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.207121
+0.235724
+0.335734
+0.221422
+0.328533
+0.350035
+0.497453
+0.837786
+0.111774
+0.788161
+0.979394
+0.297689
+0.000000
+---------END OF TABLE---------------
+======= TABLE 187 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 187
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 188 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 188
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 189 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 189
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.988438
+0.803298
+0.267835
+0.115002
+0.595937
+0.194793
+0.411357
+0.076671
+0.079459
+0.619064
+0.151164
+0.298788
+0.000000
+---------END OF TABLE---------------
+======= TABLE 190 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 190
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.557413
+0.136986
+0.224130
+0.863673
+0.276111
+0.312208
+0.743491
+0.531141
+0.294368
+0.661400
+0.132212
+0.595441
+0.000000
+---------END OF TABLE---------------
+======= TABLE 191 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 191
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.537405
+0.751374
+0.839415
+0.150858
+0.332917
+0.607242
+0.670816
+0.179500
+0.587496
+0.202448
+0.185102
+0.186244
+0.000000
+---------END OF TABLE---------------
+======= TABLE 192 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 192
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.575499
+0.750085
+0.812289
+0.618174
+0.608552
+0.745880
+0.431868
+0.373672
+0.769305
+0.505552
+0.333007
+0.579707
+0.000000
+---------END OF TABLE---------------
+======= TABLE 180 size: 4 values ======
+flen: 4
+lenmask: 3
+lobits: 22
+lomask: 4194303
+lodiv: 0.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 4
+nchnls: 1
+fno: 180
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+3.000000
+4.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
diff --git a/site/app/partialemergence/progression3.fnmlmel b/site/app/partialemergence/progression3.fnmlmel new file mode 100644 index 0000000..13c3fb9 --- /dev/null +++ b/site/app/partialemergence/progression3.fnmlmel @@ -0,0 +1,499 @@ +======= TABLE 181 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 181
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+32.000000
+55.000000
+22.000000
+38.000000
+4.000000
+65.000000
+70.000000
+38.000000
+20.000000
+49.000000
+39.000000
+3.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 182 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 182
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+62.000000
+60.000000
+61.000000
+62.000000
+68.000000
+60.000000
+49.000000
+65.000000
+48.000000
+70.000000
+56.000000
+67.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 183 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 183
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+16.000000
+16.000000
+16.000000
+16.000000
+6.000000
+7.000000
+7.000000
+5.000000
+4.000000
+4.000000
+6.000000
+7.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 184 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 184
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+2.000000
+3.000000
+1.000000
+0.000000
+0.000000
+1.000000
+0.000000
+0.000000
+1.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 185 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 185
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+2.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 186 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 186
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.307554
+0.357136
+0.707171
+0.728573
+0.084509
+0.169596
+0.885151
+0.288933
+0.202831
+0.941209
+0.984722
+0.862226
+0.000000
+---------END OF TABLE---------------
+======= TABLE 187 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 187
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+1.000000
+1.000000
+1.000000
+1.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 188 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 188
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
+======= TABLE 189 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 189
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.637370
+0.477515
+0.610804
+0.255917
+0.000580
+0.741288
+0.816668
+0.482911
+0.573710
+0.074436
+0.383590
+0.574237
+0.000000
+---------END OF TABLE---------------
+======= TABLE 190 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 190
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.434636
+0.374966
+0.983574
+0.458653
+0.134855
+0.340593
+0.568193
+0.225512
+0.393867
+0.265349
+0.197277
+0.143899
+0.000000
+---------END OF TABLE---------------
+======= TABLE 191 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 191
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.725425
+0.528734
+0.681142
+0.693358
+0.639010
+0.240893
+0.587257
+0.530698
+0.638681
+0.089535
+0.930179
+0.320513
+0.000000
+---------END OF TABLE---------------
+======= TABLE 192 size: 12 values ======
+flen: 12
+lenmask: -1
+lobits: 0
+lomask: 0
+lodiv: 1.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 12
+nchnls: 1
+fno: 192
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.427121
+0.874527
+0.221614
+0.615462
+0.492275
+0.271279
+0.723552
+0.246397
+0.027398
+0.670098
+0.345080
+0.875814
+0.000000
+---------END OF TABLE---------------
+======= TABLE 180 size: 4 values ======
+flen: 4
+lenmask: 3
+lobits: 22
+lomask: 4194303
+lodiv: 0.000000
+cvtbas: 0.000000
+cpscvt: 0.000000
+loopmode1: 0
+loopmode2: 0
+begin1: 0
+end1: 0
+begin2: 0
+end2: 0
+soundend: 0
+flenfrms: 4
+nchnls: 1
+fno: 180
+gen01args.gen01: 0.000000
+gen01args.ifilno: 0.000000
+gen01args.iskptim: 0.000000
+gen01args.iformat: 0.000000
+gen01args.channel: 0.000000
+gen01args.sample_rate: 44100.000000
+---------END OF HEADER--------------
+0.000000
+1.000000
+0.000000
+0.000000
+0.000000
+---------END OF TABLE---------------
diff --git a/site/app/partialemergence/sequence_sections.inc b/site/app/partialemergence/sequence_sections.inc new file mode 100644 index 0000000..b281a04 --- /dev/null +++ b/site/app/partialemergence/sequence_sections.inc @@ -0,0 +1,439 @@ +#ifndef INC_SECTION_SEQ
+#define INC_SECTION_SEQ ##
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ Partial Emergence
+ by Richard Knight 2022
+
+ Installation submission for the International Csound Conference 2022
+
+ Section subsequencers
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#include "/bussing.udo"
+#include "/instruments_water.inc"
+#include "/instruments_idiophone.inc"
+#include "/instruments_synthesis.inc"
+
+
+/*
+ Pause the melodic progression for the duration of the calling instrumnet
+*/
+opcode pause_melprogression, 0, 0
+ gkmel_pause = 1
+ if (lastcycle() == 1) then
+ gkmel_pause = 0
+ endif
+endop
+
+
+/*
+ Call an instrument for outward transition; p4 is passed as the rise ratio of total duration
+*/
+opcode transition_out, 0, S
+ Sinstrument xin
+ iduration = random(4, min(12, p3*0.5))
+ iriseratio = random(0.5, 0.9)
+ schedule(Sinstrument, p3 - (iduration * iriseratio), iduration, iriseratio)
+endop
+
+
+/*
+ Call an instrument for inward transition; p4 is passed as short duration for an almost immediate attack
+*/
+opcode transition_in, 0, S
+ Sinstrument xin
+ iduration = random(3, min(10, p3*0.25))
+ schedule(Sinstrument, 0, iduration, 0.03)
+endop
+
+
+instr sequencer_s0
+ transition_in("transition_idiophone_randtime")
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(5, 10)
+ idur = (idur + itime > imaxlen) ? imaxlen - itime : idur
+ schedule("phrase_idiophone1", itime, idur, 1)
+ itime += random(idur*0.6, idur*0.8)
+ od
+ transition_out("transition_idiophone_stretch1")
+endin
+
+
+instr sequencer_s1
+ schedule("phrase_idiophone_stretch1", 0, i(gkseq_beattime) * i(gkmel_section_change_due), 0)
+ schedule("phrase_idiophone1", 0, i(gkseq_beattime) * i(gkmel_section_change_due), 1)
+
+ kdo init 0
+ if (gkmel_section_change == 1) then
+ klen = mel_length:k()
+ schedulek("phrase_idiophone_stretch1", 0, klen*random:k(1, 1.5), 0)
+
+ if (kdo == 0) then
+ schedulek("phrase_idiophone1", 0, klen*random:k(1, 1.3), 0) ; chords
+ kdo = 1
+ else
+ kdo = 0
+ endif
+ endif
+ transition_out("transition_idiophone_randtime")
+endin
+
+
+instr sequencer_s2
+
+ schedule("note_bass1", 0, p3, 0)
+ schedule("phrase_idiophone1", 0, i(gkseq_beattime) * i(gkmel_section_change_due), 1)
+
+ if (gkmel_section_change == 1) then
+ klen = mel_length:k()
+ schedulek("phrase_idiophone1", 0, klen, 1) ; single note only
+ schedulek("phrase_idiophone_stretch1", 0, klen*1.3, 0)
+ endif
+
+ if (lastcycle:k() == 1) then
+ turnoff2("note_bass1", 0, 1)
+ endif
+
+endin
+
+
+instr sequencer_s3
+ schedule("note_bass1", 0, p3, 0)
+ schedule("phrase_idiophone_stretch1", 0, i(gkseq_beattime) * i(gkmel_section_change_due), 1)
+
+ if (gkmel_section_change == 1) then
+ klen = mel_length:k()
+ schedulek("phrase_idiophone1", 0, klen, 0) ; chords
+ schedulek("phrase_idiophone_stretch1", 0, klen*0.8, 1)
+ endif
+
+ if (lastcycle:k() == 1) then
+ turnoff2("note_bass1", 0, 1)
+ endif
+
+endin
+
+
+instr sequencer_s4
+ idiophone_change()
+ schedule("phrase_dropstretch1", 0, i(gkseq_beattime) * 2 * i(gkmel_section_change_due), random(0.5, 1.5), 1, 1, 0.5)
+ if (gkmel_section_change == 1) then
+ klen = mel_length:k()
+ schedulek("phrase_idiophone1", 0, klen, 1) ; single note only
+ schedulek("phrase_idiophone_stretch1", 0, klen*1.3, 1)
+ endif
+ transition_out("transition_waterbubbler1")
+endin
+
+
+instr sequencer_s5
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(5, 20)
+ schedule("phrase_dropstretch1", itime, idur, random(0.5, 1.5), 1, 1, 1)
+ if (random(0, 1) > 0.5) then
+ schedule("phrase_dropstretch1", itime + random(0, 5), idur, random(0.5, 1.5), 1, 1, 2)
+ endif
+
+ if (random(0, 1) > 0.5) then ; no reson
+ schedule("phrase_dropstretch1", itime + random(0, 5), idur, random(0.5, 1.5), 0, 1, 1)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ schedule("phrase_waterbubbler1", itime, idur, 1)
+ endif
+
+ if (random(0, 1) > 0.5) then
+ schedule("play_waterpaddling1", itime + random(0, 5), 1)
+ endif
+
+ itime += idur * random(0.5, 0.8)
+ od
+endin
+
+
+instr sequencer_s6
+ schedule("phrase_dropstretch1", 0, i(gkseq_beattime) * 1.5 * i(gkmel_section_change_due), random(0.5, 1.5), 0, 1, 1)
+
+ if (gkmel_section_change == 1) then
+ ;turnoff2 "phrase_idiophone_stretch2", 0, 1
+ schedulek("phrase_idiophone_stretch2", 0, mel_length:k()*1.3, 0)
+ schedulek("phrase_waterbubbler1", 0, mel_length:k(), 0)
+ endif
+
+ awL, awR bus_read "phrase_waterbubbler"
+ amL, amR bus_read "note_idiophonestretch2"
+
+ ir = 256
+ irm = 2
+ fwL pvsanal awL, ir, ir/irm, ir, 1
+ fwR pvsanal awR, ir, ir/irm, ir, 1
+ fmL pvsanal amL, ir, ir/irm, ir, 1
+ fmR pvsanal amR, ir, ir/irm, ir, 1
+ fxL pvsmorph fwL, fmL, 0, 1
+ fxR pvsmorph fwR, fmR, 0, 1
+ aL pvsynth fxL
+ aR pvsynth fxR
+ kamp linseg 0, p3*0.01, 1, p3*0.98, 1, p3*0.01, 0 ; has click at start
+ bus_mix("main", aL*kamp, aR*kamp)
+endin
+
+
+instr sequencer_s7
+ idiophone_change()
+ schedule("phrase_dropstretch1", 0, i(gkseq_beattime) * 1.5 * i(gkmel_section_change_due), random(0.5, 1.5), 1, 1, 8)
+ if (gkmel_section_change == 1) then
+ schedulek("phrase_idiophone_stretch2", 0, mel_length:k()*1.3, 0)
+ schedulek("phrase_waterbubbler1", 0, mel_length:k(), 1)
+ endif
+
+ aL, aR bus_read "note_idiophonestretch2"
+ bus_mix("delay1", aL*0.2, aR*0.2)
+ bus_mix("main", aL*0.8, aR*0.8)
+ transition_out("transition_idiophone_randtime")
+endin
+
+
+instr sequencer_s8
+ pause_melprogression()
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(p3*0.1, p3*0.3)
+ idur = (idur + itime > imaxlen) ? imaxlen - itime : idur
+ schedule("phrase_dropstretch1", itime, idur, random(0.5, 1.5), 1, 1, 0.5)
+ if (random(0, 1) > 0.5) then
+ schedule("phrase_dropstretch1", itime + random(0, 5), idur, random(0.5, 1.5), 1, 1, 2)
+ endif
+
+ if (random(0, 1) > 0.5) then ; no reson
+ schedule("phrase_dropstretch1", itime + random(0, 5), idur, random(0.5, 1.5), 0, 1, 1)
+ endif
+
+ if (random(0, 1) > 0.2) then
+ schedule("play_waterpaddling1", itime + random(0, 5), random(0.5, 6))
+ if (random(0, 1) > 0.6) then
+ schedule("play_waterpaddling1", itime + random(0, 5), random(0.5, 6))
+ endif
+ endif
+ itime += idur * random(0.5, 1.2)
+ od
+ transition_out("transition_idiophone_gliss1")
+endin
+
+
+instr sequencer_s9
+ transition_in("transition_idiophone_stretch1")
+ idiophone_change()
+ gimel_portamento_beatratio = 0.4
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(5, 20)
+ idur = (idur + itime > imaxlen) ? imaxlen - itime : idur
+ schedule("phrase_idiophone_stretch3", itime, idur)
+ itime += idur
+ od
+ transition_out("transition_idiophone_stretch1")
+endin
+
+
+instr sequencer_s10
+ transition_in("transition_idiophone_randtime")
+ gimel_portamento_beatratio = 0.4
+ schedule("phrase_idiophone_stretch4", 0, p3)
+ schedule("note_bass1", 0, p3, 0)
+
+ kmetrofreq = abs:k(oscil:k(5, 0.01)) + 0.1
+ knotemetro = metro(kmetrofreq)
+ if (knotemetro == 1) then
+ if (random:k(0, 1) > 0.8) then
+ kstart = random:k(0, 0.3)
+ schedulek("note_hybrid1", kstart, 1, mel_randomnote:k())
+ ;schedulek("_note_idiophone1", kstart, 0.1, mel_randomnote:k()+12, random:k(2, 7))
+ ;schedulek("note_drop1", kstart, 0.5)
+ endif
+ endif
+
+ kdroprollmetro = metro(0.1)
+ if (kdroprollmetro == 1 && random:k(0, 1) > 0.5) then
+ schedulek("fnmi_sineblips", random:k(0, 2), random:k(3, 10), "reverb1")
+ schedulek("phrase_droproll1", random:k(0, 2), random:k(3, 10), 1)
+ endif
+
+endin
+
+
+instr sequencer_s11
+ transition_in("transition_idiophone_gliss1")
+ ; resonated droplets
+ kmetrofreq = abs:k(oscil:k(3, 0.01)) + 0.1
+ knotemetro = metro(kmetrofreq)
+ if (knotemetro == 1) then
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0, 0.3), 1, mel_randomnote:k())
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0.3, 1), 1, mel_randomnote:k()+12)
+ endif
+ endif
+ endif
+
+ ; water droplets
+ kdroprollmetro = metro(0.2)
+ if (kdroprollmetro == 1 && random:k(0, 1) > 0.5) then
+ schedulek("phrase_droproll1", random:k(0, 2), random:k(3, 10), 0.2)
+ endif
+
+ ; subtle notes
+ if (gkmel_section_change == 1) then
+ schedulek("note_idiophonestretch1", random:k(0, 2), random:k(4, 12), mel_randomnote:k()-12, 0)
+ schedulek("note_idiophonestretch1", random:k(0, 2), random:k(4, 12), mel_randomnote:k()-12, 0)
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_idiophonestretch1", random:k(0, 2), random:k(4, 12), mel_randomnote:k()-12, 0)
+ schedulek("note_idiophonestretch1", random:k(0, 2), random:k(4, 12), mel_randomnote:k()-12, 0)
+ endif
+
+ ; paddling stretch
+ schedulek("play_waterpaddling1", random:k(0, 2), random:k(3, 15))
+
+ ; bass note
+ if (random:k(0, 1) > 0.4) then
+ klen = mel_length:k()
+ schedulek("note_bass2", random:k(0, 3), random:k(klen, klen*1.5), 0)
+ endif
+ endif
+endin
+
+
+instr sequencer_s12
+ kmetrofreq = abs:k(oscil:k(3, 0.01)) + 0.1
+ knotemetro = metro(kmetrofreq)
+ if (knotemetro == 1) then
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0, 0.3), 1, mel_randomnote:k()-12)
+ endif
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0.3, 1), 1, mel_randomnote:k())
+ endif
+ if (random:k(0, 1) > 0.5) then
+ kstart = random:k(0.3, 1)
+ schedulek("note_hybrid1", kstart, 1, mel_randomnote:k()+24)
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_drop1", kstart, 1)
+ endif
+ endif
+ if (random:k(0, 1) > 0.9) then
+ schedulek("phrase_dropstretch1", random:k(0, 3), random:k(4, 7), 2, round:k(random:k(0, 1)), 1, 2)
+ schedulek("note_bass2", random:k(0, 3), random:k(4, 5), 0)
+ endif
+ endif
+ schedule("phrase_droproll1", 0, 1, 2.4)
+endin
+
+
+instr sequencer_s13
+ if (random(0, 1) >= 0.5) then
+ pause_melprogression()
+ endif
+ idiophone_change()
+ iplayidiophone = round(random(0, 1))
+ kmetrofreq expseg 0.3, p3, 20
+ knotemetro = metro(kmetrofreq)
+ if (knotemetro == 1) then
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0, 0.3), 1, mel_randomnote:k()+12)
+ if (iplayidiophone == 1 && active:k("note_idiophonestretch1") == 0) then
+ schedulek("note_idiophonestretch1", random:k(0, 2), random:k(1, 3), mel_randomnote:k()-12, 0)
+ endif
+ endif
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_hybrid1", random:k(0.3, 1), 1, mel_randomnote:k())
+ endif
+ if (random:k(0, 1) > 0.5) then
+ kstart = random:k(0.3, 1)
+ schedulek("note_hybrid1", kstart, 1, mel_randomnote:k()-12)
+ if (random:k(0, 1) > 0.5) then
+ schedulek("note_drop1", kstart, 1)
+ endif
+ endif
+ endif
+ schedule("phrase_droproll1", 0, 1.3, 2.4)
+endin
+
+
+instr sequencer_s14
+ gimel_portamento_beatratio = 0.2
+ imaxlen = p3
+ iplaydrops = round(random(0, 1))
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(5, 20)
+ idur = (idur + itime > imaxlen) ? imaxlen - itime : idur
+ schedule("phrase_hybridstretch1", itime, idur)
+ if (iplaydrops == 1) then
+ schedule("phrase_droproll1", itime, idur, 0.4)
+ endif
+ itime += idur
+ od
+
+ ; play one music box glissando just before the next mel section change
+ kglissset init 0
+ if (kglissset == 0 && gkmel_section_change == 1) then
+ schedulek("phrase_idiophone_gliss1", mel_length:k()-0.5, 1, 3)
+ kglissset = 1
+ endif
+
+ ; water transition out
+ transition_out("transition_droplets1")
+endin
+
+
+instr sequencer_s15
+ transition_in("transition_idiophone_gliss1")
+ idiophone_change()
+ pause_melprogression()
+
+ ;schedule("phrase_idiophone1", 0, p3, 0)
+ schedule("phrase_hybrid2", 0, p3, 0)
+ transition_out("transition_waterbubbler1")
+endin
+
+
+instr sequencer_s16
+ idiophone_change()
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ idur = random(5, 20)
+ idur = (idur + itime > imaxlen) ? imaxlen - itime : idur
+ schedule("phrase_hybrid1", itime, idur)
+ itime += idur
+ od
+ transition_out("transition_idiophone_gliss1")
+endin
+
+
+instr sequencer_s17
+ pause_melprogression()
+ imaxlen = p3
+ itime = 0
+ while (itime < imaxlen) do
+ schedule("note_idiophone_randtime", itime+random(0, 1), random(2, 5))
+ schedule("note_idiophone_randtime", itime+random(0, 4), random(2, 5))
+ schedule("play_waterpaddling1", itime+random(0, 1), random(1, 2))
+ itime += random(5, 20)
+ od
+
+ schedule("phrase_dropstretch1", 0, p3, 1, 1, 1, 1)
+ schedule("phrase_dropstretch1", 0, p3, 2, 1, 1, 0.5)
+ transition_out("transition_droplets1")
+endin
+
+
+
+#end
diff --git a/site/app/partialemergence/sequencing_melodic_persistence.pe.udo b/site/app/partialemergence/sequencing_melodic_persistence.pe.udo new file mode 100644 index 0000000..a75b2d4 --- /dev/null +++ b/site/app/partialemergence/sequencing_melodic_persistence.pe.udo @@ -0,0 +1,54 @@ +#ifndef UDO_MELSEQUENCINGPERSIST
+#define UDO_MELSEQUENCINGPERSIST ##
+/*
+ Melodic sequencer persistence: saving/loading from files and database
+ Slim excerpt for Partial Emergence
+
+ This file is part of the SONICS UDO collection by Richard Knight 2021, 2022, 2025
+ License: GPL-2.0-or-later
+ http://1bpm.net
+*/
+
+#include "/sequencing_melodic.udo"
+#include "/array_tools.udo"
+
+/*
+ Load state from file
+
+ p4 path to load from
+*/
+instr mel_loadstate_fs
+ Spath = p4
+ isize = -1
+ iline = 0
+
+ ftload Spath, 1,\
+ gimel_chords, gimel_notes,
+ gimel_lengths, gimel_action1,\
+ gimel_action2, gimel_actionthreshold,\
+ gimel_active, gimel_importance,\
+ gimel_mod1, gimel_mod2,\
+ gimel_mod3, gimel_mod4,\
+ gimel_state
+
+ gkmel_futures_refresh_trig = 1
+ turnoff
+endin
+
+
+
+; if MEL_INITPATH is set, load the specified progression data accordingly
+#ifdef MEL_HASINIT
+instr _mel_persistence_init
+#ifdef MEL_INITPATH
+ subinstrinit "mel_loadstate_fs", "$MEL_INITPATH"
+#end
+ alwayson "_mel_manager"
+ turnoff
+endin
+schedule "_mel_persistence_init", 0, 60
+
+; end MEL_HASINIT
+#end
+
+#end
diff --git a/site/app/partialemergence/soundexport.xdb b/site/app/partialemergence/soundexport.xdb new file mode 100644 index 0000000..8f45260 --- /dev/null +++ b/site/app/partialemergence/soundexport.xdb @@ -0,0 +1,4538 @@ +; SONICS DB extract 1.0, exported from database on/at 2022-10-05 22:43:39.470067+01
+#define XDB_SET ##
+#define XDB_MINNOTE #0#
+gSxdb_collections[] fillarray "Water.Droplet", "Water.Paddling", "MusicBox", "Kalimba"
+gixdb_collectionsfn[] fillarray ftgen(0,0,-578,-2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,397,398,399,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,436,437,438,439,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577), ftgen(0,0,-100,-2,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596,597,598,599,600,601,602,603,604,605,606,607,608,609,610,611,612,613,614,615,616,617,618,619,620,621,622,623,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,641,642,643,644,645,646,647,648,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677), ftgen(0,0,-60,-2,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737), ftgen(0,0,-74,-2,738,739,740,741,742,743,744,745,746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,806,807,808,809,810,811)
+gisounddb[][] init 812, 4
+gisounddb[0][0] ftgen 0,0,0,1,"sounds/Water/Droplets/392.mp3",0,0,0
+gisounddb[1][0] ftgen 0,0,0,1,"sounds/Water/Droplets/378.mp3",0,0,0
+gisounddb[2][0] ftgen 0,0,0,1,"sounds/Water/Droplets/45.mp3",0,0,0
+gisounddb[3][0] ftgen 0,0,0,1,"sounds/Water/Droplets/130.mp3",0,0,0
+gisounddb[4][0] ftgen 0,0,0,1,"sounds/Water/Droplets/344.mp3",0,0,0
+gisounddb[5][0] ftgen 0,0,0,1,"sounds/Water/Droplets/576.mp3",0,0,0
+gisounddb[6][0] ftgen 0,0,0,1,"sounds/Water/Droplets/60.mp3",0,0,0
+gisounddb[7][0] ftgen 0,0,0,1,"sounds/Water/Droplets/491.mp3",0,0,0
+gisounddb[8][0] ftgen 0,0,0,1,"sounds/Water/Droplets/59.mp3",0,0,0
+gisounddb[9][0] ftgen 0,0,0,1,"sounds/Water/Droplets/530.mp3",0,0,0
+gisounddb[10][0] ftgen 0,0,0,1,"sounds/Water/Droplets/160.mp3",0,0,0
+gisounddb[11][0] ftgen 0,0,0,1,"sounds/Water/Droplets/466.mp3",0,0,0
+gisounddb[12][0] ftgen 0,0,0,1,"sounds/Water/Droplets/178.mp3",0,0,0
+gisounddb[13][0] ftgen 0,0,0,1,"sounds/Water/Droplets/258.mp3",0,0,0
+gisounddb[14][0] ftgen 0,0,0,1,"sounds/Water/Droplets/81.mp3",0,0,0
+gisounddb[15][0] ftgen 0,0,0,1,"sounds/Water/Droplets/217.mp3",0,0,0
+gisounddb[16][0] ftgen 0,0,0,1,"sounds/Water/Droplets/488.mp3",0,0,0
+gisounddb[17][0] ftgen 0,0,0,1,"sounds/Water/Droplets/38.mp3",0,0,0
+gisounddb[18][0] ftgen 0,0,0,1,"sounds/Water/Droplets/309.mp3",0,0,0
+gisounddb[19][0] ftgen 0,0,0,1,"sounds/Water/Droplets/182.mp3",0,0,0
+gisounddb[20][0] ftgen 0,0,0,1,"sounds/Water/Droplets/543.mp3",0,0,0
+gisounddb[21][0] ftgen 0,0,0,1,"sounds/Water/Droplets/5.mp3",0,0,0
+gisounddb[22][0] ftgen 0,0,0,1,"sounds/Water/Droplets/482.mp3",0,0,0
+gisounddb[23][0] ftgen 0,0,0,1,"sounds/Water/Droplets/358.mp3",0,0,0
+gisounddb[24][0] ftgen 0,0,0,1,"sounds/Water/Droplets/454.mp3",0,0,0
+gisounddb[25][0] ftgen 0,0,0,1,"sounds/Water/Droplets/260.mp3",0,0,0
+gisounddb[26][0] ftgen 0,0,0,1,"sounds/Water/Droplets/298.mp3",0,0,0
+gisounddb[27][0] ftgen 0,0,0,1,"sounds/Water/Droplets/180.mp3",0,0,0
+gisounddb[28][0] ftgen 0,0,0,1,"sounds/Water/Droplets/502.mp3",0,0,0
+gisounddb[29][0] ftgen 0,0,0,1,"sounds/Water/Droplets/512.mp3",0,0,0
+gisounddb[30][0] ftgen 0,0,0,1,"sounds/Water/Droplets/479.mp3",0,0,0
+gisounddb[31][0] ftgen 0,0,0,1,"sounds/Water/Droplets/532.mp3",0,0,0
+gisounddb[32][0] ftgen 0,0,0,1,"sounds/Water/Droplets/85.mp3",0,0,0
+gisounddb[33][0] ftgen 0,0,0,1,"sounds/Water/Droplets/289.mp3",0,0,0
+gisounddb[34][0] ftgen 0,0,0,1,"sounds/Water/Droplets/413.mp3",0,0,0
+gisounddb[35][0] ftgen 0,0,0,1,"sounds/Water/Droplets/453.mp3",0,0,0
+gisounddb[36][0] ftgen 0,0,0,1,"sounds/Water/Droplets/75.mp3",0,0,0
+gisounddb[37][0] ftgen 0,0,0,1,"sounds/Water/Droplets/88.mp3",0,0,0
+gisounddb[38][0] ftgen 0,0,0,1,"sounds/Water/Droplets/77.mp3",0,0,0
+gisounddb[39][0] ftgen 0,0,0,1,"sounds/Water/Droplets/157.mp3",0,0,0
+gisounddb[40][0] ftgen 0,0,0,1,"sounds/Water/Droplets/245.mp3",0,0,0
+gisounddb[41][0] ftgen 0,0,0,1,"sounds/Water/Droplets/474.mp3",0,0,0
+gisounddb[42][0] ftgen 0,0,0,1,"sounds/Water/Droplets/404.mp3",0,0,0
+gisounddb[43][0] ftgen 0,0,0,1,"sounds/Water/Droplets/343.mp3",0,0,0
+gisounddb[44][0] ftgen 0,0,0,1,"sounds/Water/Droplets/239.mp3",0,0,0
+gisounddb[45][0] ftgen 0,0,0,1,"sounds/Water/Droplets/381.mp3",0,0,0
+gisounddb[46][0] ftgen 0,0,0,1,"sounds/Water/Droplets/251.mp3",0,0,0
+gisounddb[47][0] ftgen 0,0,0,1,"sounds/Water/Droplets/569.mp3",0,0,0
+gisounddb[48][0] ftgen 0,0,0,1,"sounds/Water/Droplets/475.mp3",0,0,0
+gisounddb[49][0] ftgen 0,0,0,1,"sounds/Water/Droplets/462.mp3",0,0,0
+gisounddb[50][0] ftgen 0,0,0,1,"sounds/Water/Droplets/290.mp3",0,0,0
+gisounddb[51][0] ftgen 0,0,0,1,"sounds/Water/Droplets/70.mp3",0,0,0
+gisounddb[52][0] ftgen 0,0,0,1,"sounds/Water/Droplets/224.mp3",0,0,0
+gisounddb[53][0] ftgen 0,0,0,1,"sounds/Water/Droplets/164.mp3",0,0,0
+gisounddb[54][0] ftgen 0,0,0,1,"sounds/Water/Droplets/274.mp3",0,0,0
+gisounddb[55][0] ftgen 0,0,0,1,"sounds/Water/Droplets/105.mp3",0,0,0
+gisounddb[56][0] ftgen 0,0,0,1,"sounds/Water/Droplets/531.mp3",0,0,0
+gisounddb[57][0] ftgen 0,0,0,1,"sounds/Water/Droplets/39.mp3",0,0,0
+gisounddb[58][0] ftgen 0,0,0,1,"sounds/Water/Droplets/135.mp3",0,0,0
+gisounddb[59][0] ftgen 0,0,0,1,"sounds/Water/Droplets/281.mp3",0,0,0
+gisounddb[60][0] ftgen 0,0,0,1,"sounds/Water/Droplets/494.mp3",0,0,0
+gisounddb[61][0] ftgen 0,0,0,1,"sounds/Water/Droplets/147.mp3",0,0,0
+gisounddb[62][0] ftgen 0,0,0,1,"sounds/Water/Droplets/561.mp3",0,0,0
+gisounddb[63][0] ftgen 0,0,0,1,"sounds/Water/Droplets/461.mp3",0,0,0
+gisounddb[64][0] ftgen 0,0,0,1,"sounds/Water/Droplets/430.mp3",0,0,0
+gisounddb[65][0] ftgen 0,0,0,1,"sounds/Water/Droplets/328.mp3",0,0,0
+gisounddb[66][0] ftgen 0,0,0,1,"sounds/Water/Droplets/331.mp3",0,0,0
+gisounddb[67][0] ftgen 0,0,0,1,"sounds/Water/Droplets/316.mp3",0,0,0
+gisounddb[68][0] ftgen 0,0,0,1,"sounds/Water/Droplets/141.mp3",0,0,0
+gisounddb[69][0] ftgen 0,0,0,1,"sounds/Water/Droplets/124.mp3",0,0,0
+gisounddb[70][0] ftgen 0,0,0,1,"sounds/Water/Droplets/556.mp3",0,0,0
+gisounddb[71][0] ftgen 0,0,0,1,"sounds/Water/Droplets/510.mp3",0,0,0
+gisounddb[72][0] ftgen 0,0,0,1,"sounds/Water/Droplets/449.mp3",0,0,0
+gisounddb[73][0] ftgen 0,0,0,1,"sounds/Water/Droplets/138.mp3",0,0,0
+gisounddb[74][0] ftgen 0,0,0,1,"sounds/Water/Droplets/62.mp3",0,0,0
+gisounddb[75][0] ftgen 0,0,0,1,"sounds/Water/Droplets/192.mp3",0,0,0
+gisounddb[76][0] ftgen 0,0,0,1,"sounds/Water/Droplets/361.mp3",0,0,0
+gisounddb[77][0] ftgen 0,0,0,1,"sounds/Water/Droplets/21.mp3",0,0,0
+gisounddb[78][0] ftgen 0,0,0,1,"sounds/Water/Droplets/40.mp3",0,0,0
+gisounddb[79][0] ftgen 0,0,0,1,"sounds/Water/Droplets/205.mp3",0,0,0
+gisounddb[80][0] ftgen 0,0,0,1,"sounds/Water/Droplets/301.mp3",0,0,0
+gisounddb[81][0] ftgen 0,0,0,1,"sounds/Water/Droplets/315.mp3",0,0,0
+gisounddb[82][0] ftgen 0,0,0,1,"sounds/Water/Droplets/393.mp3",0,0,0
+gisounddb[83][0] ftgen 0,0,0,1,"sounds/Water/Droplets/417.mp3",0,0,0
+gisounddb[84][0] ftgen 0,0,0,1,"sounds/Water/Droplets/348.mp3",0,0,0
+gisounddb[85][0] ftgen 0,0,0,1,"sounds/Water/Droplets/42.mp3",0,0,0
+gisounddb[86][0] ftgen 0,0,0,1,"sounds/Water/Droplets/256.mp3",0,0,0
+gisounddb[87][0] ftgen 0,0,0,1,"sounds/Water/Droplets/533.mp3",0,0,0
+gisounddb[88][0] ftgen 0,0,0,1,"sounds/Water/Droplets/410.mp3",0,0,0
+gisounddb[89][0] ftgen 0,0,0,1,"sounds/Water/Droplets/226.mp3",0,0,0
+gisounddb[90][0] ftgen 0,0,0,1,"sounds/Water/Droplets/435.mp3",0,0,0
+gisounddb[91][0] ftgen 0,0,0,1,"sounds/Water/Droplets/299.mp3",0,0,0
+gisounddb[92][0] ftgen 0,0,0,1,"sounds/Water/Droplets/98.mp3",0,0,0
+gisounddb[93][0] ftgen 0,0,0,1,"sounds/Water/Droplets/139.mp3",0,0,0
+gisounddb[94][0] ftgen 0,0,0,1,"sounds/Water/Droplets/397.mp3",0,0,0
+gisounddb[95][0] ftgen 0,0,0,1,"sounds/Water/Droplets/95.mp3",0,0,0
+gisounddb[96][0] ftgen 0,0,0,1,"sounds/Water/Droplets/396.mp3",0,0,0
+gisounddb[97][0] ftgen 0,0,0,1,"sounds/Water/Droplets/560.mp3",0,0,0
+gisounddb[98][0] ftgen 0,0,0,1,"sounds/Water/Droplets/399.mp3",0,0,0
+gisounddb[99][0] ftgen 0,0,0,1,"sounds/Water/Droplets/233.mp3",0,0,0
+gisounddb[100][0] ftgen 0,0,0,1,"sounds/Water/Droplets/559.mp3",0,0,0
+gisounddb[101][0] ftgen 0,0,0,1,"sounds/Water/Droplets/552.mp3",0,0,0
+gisounddb[102][0] ftgen 0,0,0,1,"sounds/Water/Droplets/511.mp3",0,0,0
+gisounddb[103][0] ftgen 0,0,0,1,"sounds/Water/Droplets/74.mp3",0,0,0
+gisounddb[104][0] ftgen 0,0,0,1,"sounds/Water/Droplets/174.mp3",0,0,0
+gisounddb[105][0] ftgen 0,0,0,1,"sounds/Water/Droplets/460.mp3",0,0,0
+gisounddb[106][0] ftgen 0,0,0,1,"sounds/Water/Droplets/171.mp3",0,0,0
+gisounddb[107][0] ftgen 0,0,0,1,"sounds/Water/Droplets/149.mp3",0,0,0
+gisounddb[108][0] ftgen 0,0,0,1,"sounds/Water/Droplets/203.mp3",0,0,0
+gisounddb[109][0] ftgen 0,0,0,1,"sounds/Water/Droplets/504.mp3",0,0,0
+gisounddb[110][0] ftgen 0,0,0,1,"sounds/Water/Droplets/323.mp3",0,0,0
+gisounddb[111][0] ftgen 0,0,0,1,"sounds/Water/Droplets/423.mp3",0,0,0
+gisounddb[112][0] ftgen 0,0,0,1,"sounds/Water/Droplets/210.mp3",0,0,0
+gisounddb[113][0] ftgen 0,0,0,1,"sounds/Water/Droplets/431.mp3",0,0,0
+gisounddb[114][0] ftgen 0,0,0,1,"sounds/Water/Droplets/30.mp3",0,0,0
+gisounddb[115][0] ftgen 0,0,0,1,"sounds/Water/Droplets/295.mp3",0,0,0
+gisounddb[116][0] ftgen 0,0,0,1,"sounds/Water/Droplets/406.mp3",0,0,0
+gisounddb[117][0] ftgen 0,0,0,1,"sounds/Water/Droplets/100.mp3",0,0,0
+gisounddb[118][0] ftgen 0,0,0,1,"sounds/Water/Droplets/579.mp3",0,0,0
+gisounddb[119][0] ftgen 0,0,0,1,"sounds/Water/Droplets/505.mp3",0,0,0
+gisounddb[120][0] ftgen 0,0,0,1,"sounds/Water/Droplets/329.mp3",0,0,0
+gisounddb[121][0] ftgen 0,0,0,1,"sounds/Water/Droplets/162.mp3",0,0,0
+gisounddb[122][0] ftgen 0,0,0,1,"sounds/Water/Droplets/534.mp3",0,0,0
+gisounddb[123][0] ftgen 0,0,0,1,"sounds/Water/Droplets/12.mp3",0,0,0
+gisounddb[124][0] ftgen 0,0,0,1,"sounds/Water/Droplets/44.mp3",0,0,0
+gisounddb[125][0] ftgen 0,0,0,1,"sounds/Water/Droplets/548.mp3",0,0,0
+gisounddb[126][0] ftgen 0,0,0,1,"sounds/Water/Droplets/527.mp3",0,0,0
+gisounddb[127][0] ftgen 0,0,0,1,"sounds/Water/Droplets/473.mp3",0,0,0
+gisounddb[128][0] ftgen 0,0,0,1,"sounds/Water/Droplets/314.mp3",0,0,0
+gisounddb[129][0] ftgen 0,0,0,1,"sounds/Water/Droplets/8.mp3",0,0,0
+gisounddb[130][0] ftgen 0,0,0,1,"sounds/Water/Droplets/103.mp3",0,0,0
+gisounddb[131][0] ftgen 0,0,0,1,"sounds/Water/Droplets/46.mp3",0,0,0
+gisounddb[132][0] ftgen 0,0,0,1,"sounds/Water/Droplets/520.mp3",0,0,0
+gisounddb[133][0] ftgen 0,0,0,1,"sounds/Water/Droplets/109.mp3",0,0,0
+gisounddb[134][0] ftgen 0,0,0,1,"sounds/Water/Droplets/550.mp3",0,0,0
+gisounddb[135][0] ftgen 0,0,0,1,"sounds/Water/Droplets/300.mp3",0,0,0
+gisounddb[136][0] ftgen 0,0,0,1,"sounds/Water/Droplets/367.mp3",0,0,0
+gisounddb[137][0] ftgen 0,0,0,1,"sounds/Water/Droplets/456.mp3",0,0,0
+gisounddb[138][0] ftgen 0,0,0,1,"sounds/Water/Droplets/145.mp3",0,0,0
+gisounddb[139][0] ftgen 0,0,0,1,"sounds/Water/Droplets/365.mp3",0,0,0
+gisounddb[140][0] ftgen 0,0,0,1,"sounds/Water/Droplets/34.mp3",0,0,0
+gisounddb[141][0] ftgen 0,0,0,1,"sounds/Water/Droplets/407.mp3",0,0,0
+gisounddb[142][0] ftgen 0,0,0,1,"sounds/Water/Droplets/271.mp3",0,0,0
+gisounddb[143][0] ftgen 0,0,0,1,"sounds/Water/Droplets/305.mp3",0,0,0
+gisounddb[144][0] ftgen 0,0,0,1,"sounds/Water/Droplets/272.mp3",0,0,0
+gisounddb[145][0] ftgen 0,0,0,1,"sounds/Water/Droplets/332.mp3",0,0,0
+gisounddb[146][0] ftgen 0,0,0,1,"sounds/Water/Droplets/287.mp3",0,0,0
+gisounddb[147][0] ftgen 0,0,0,1,"sounds/Water/Droplets/93.mp3",0,0,0
+gisounddb[148][0] ftgen 0,0,0,1,"sounds/Water/Droplets/486.mp3",0,0,0
+gisounddb[149][0] ftgen 0,0,0,1,"sounds/Water/Droplets/498.mp3",0,0,0
+gisounddb[150][0] ftgen 0,0,0,1,"sounds/Water/Droplets/432.mp3",0,0,0
+gisounddb[151][0] ftgen 0,0,0,1,"sounds/Water/Droplets/61.mp3",0,0,0
+gisounddb[152][0] ftgen 0,0,0,1,"sounds/Water/Droplets/427.mp3",0,0,0
+gisounddb[153][0] ftgen 0,0,0,1,"sounds/Water/Droplets/390.mp3",0,0,0
+gisounddb[154][0] ftgen 0,0,0,1,"sounds/Water/Droplets/320.mp3",0,0,0
+gisounddb[155][0] ftgen 0,0,0,1,"sounds/Water/Droplets/403.mp3",0,0,0
+gisounddb[156][0] ftgen 0,0,0,1,"sounds/Water/Droplets/67.mp3",0,0,0
+gisounddb[157][0] ftgen 0,0,0,1,"sounds/Water/Droplets/517.mp3",0,0,0
+gisounddb[158][0] ftgen 0,0,0,1,"sounds/Water/Droplets/472.mp3",0,0,0
+gisounddb[159][0] ftgen 0,0,0,1,"sounds/Water/Droplets/49.mp3",0,0,0
+gisounddb[160][0] ftgen 0,0,0,1,"sounds/Water/Droplets/408.mp3",0,0,0
+gisounddb[161][0] ftgen 0,0,0,1,"sounds/Water/Droplets/373.mp3",0,0,0
+gisounddb[162][0] ftgen 0,0,0,1,"sounds/Water/Droplets/132.mp3",0,0,0
+gisounddb[163][0] ftgen 0,0,0,1,"sounds/Water/Droplets/359.mp3",0,0,0
+gisounddb[164][0] ftgen 0,0,0,1,"sounds/Water/Droplets/55.mp3",0,0,0
+gisounddb[165][0] ftgen 0,0,0,1,"sounds/Water/Droplets/28.mp3",0,0,0
+gisounddb[166][0] ftgen 0,0,0,1,"sounds/Water/Droplets/318.mp3",0,0,0
+gisounddb[167][0] ftgen 0,0,0,1,"sounds/Water/Droplets/311.mp3",0,0,0
+gisounddb[168][0] ftgen 0,0,0,1,"sounds/Water/Droplets/525.mp3",0,0,0
+gisounddb[169][0] ftgen 0,0,0,1,"sounds/Water/Droplets/163.mp3",0,0,0
+gisounddb[170][0] ftgen 0,0,0,1,"sounds/Water/Droplets/288.mp3",0,0,0
+gisounddb[171][0] ftgen 0,0,0,1,"sounds/Water/Droplets/202.mp3",0,0,0
+gisounddb[172][0] ftgen 0,0,0,1,"sounds/Water/Droplets/23.mp3",0,0,0
+gisounddb[173][0] ftgen 0,0,0,1,"sounds/Water/Droplets/375.mp3",0,0,0
+gisounddb[174][0] ftgen 0,0,0,1,"sounds/Water/Droplets/72.mp3",0,0,0
+gisounddb[175][0] ftgen 0,0,0,1,"sounds/Water/Droplets/321.mp3",0,0,0
+gisounddb[176][0] ftgen 0,0,0,1,"sounds/Water/Droplets/128.mp3",0,0,0
+gisounddb[177][0] ftgen 0,0,0,1,"sounds/Water/Droplets/380.mp3",0,0,0
+gisounddb[178][0] ftgen 0,0,0,1,"sounds/Water/Droplets/366.mp3",0,0,0
+gisounddb[179][0] ftgen 0,0,0,1,"sounds/Water/Droplets/1.mp3",0,0,0
+gisounddb[180][0] ftgen 0,0,0,1,"sounds/Water/Droplets/235.mp3",0,0,0
+gisounddb[181][0] ftgen 0,0,0,1,"sounds/Water/Droplets/450.mp3",0,0,0
+gisounddb[182][0] ftgen 0,0,0,1,"sounds/Water/Droplets/27.mp3",0,0,0
+gisounddb[183][0] ftgen 0,0,0,1,"sounds/Water/Droplets/468.mp3",0,0,0
+gisounddb[184][0] ftgen 0,0,0,1,"sounds/Water/Droplets/58.mp3",0,0,0
+gisounddb[185][0] ftgen 0,0,0,1,"sounds/Water/Droplets/499.mp3",0,0,0
+gisounddb[186][0] ftgen 0,0,0,1,"sounds/Water/Droplets/223.mp3",0,0,0
+gisounddb[187][0] ftgen 0,0,0,1,"sounds/Water/Droplets/440.mp3",0,0,0
+gisounddb[188][0] ftgen 0,0,0,1,"sounds/Water/Droplets/546.mp3",0,0,0
+gisounddb[189][0] ftgen 0,0,0,1,"sounds/Water/Droplets/416.mp3",0,0,0
+gisounddb[190][0] ftgen 0,0,0,1,"sounds/Water/Droplets/26.mp3",0,0,0
+gisounddb[191][0] ftgen 0,0,0,1,"sounds/Water/Droplets/483.mp3",0,0,0
+gisounddb[192][0] ftgen 0,0,0,1,"sounds/Water/Droplets/199.mp3",0,0,0
+gisounddb[193][0] ftgen 0,0,0,1,"sounds/Water/Droplets/292.mp3",0,0,0
+gisounddb[194][0] ftgen 0,0,0,1,"sounds/Water/Droplets/503.mp3",0,0,0
+gisounddb[195][0] ftgen 0,0,0,1,"sounds/Water/Droplets/345.mp3",0,0,0
+gisounddb[196][0] ftgen 0,0,0,1,"sounds/Water/Droplets/363.mp3",0,0,0
+gisounddb[197][0] ftgen 0,0,0,1,"sounds/Water/Droplets/259.mp3",0,0,0
+gisounddb[198][0] ftgen 0,0,0,1,"sounds/Water/Droplets/470.mp3",0,0,0
+gisounddb[199][0] ftgen 0,0,0,1,"sounds/Water/Droplets/169.mp3",0,0,0
+gisounddb[200][0] ftgen 0,0,0,1,"sounds/Water/Droplets/36.mp3",0,0,0
+gisounddb[201][0] ftgen 0,0,0,1,"sounds/Water/Droplets/153.mp3",0,0,0
+gisounddb[202][0] ftgen 0,0,0,1,"sounds/Water/Droplets/18.mp3",0,0,0
+gisounddb[203][0] ftgen 0,0,0,1,"sounds/Water/Droplets/131.mp3",0,0,0
+gisounddb[204][0] ftgen 0,0,0,1,"sounds/Water/Droplets/519.mp3",0,0,0
+gisounddb[205][0] ftgen 0,0,0,1,"sounds/Water/Droplets/201.mp3",0,0,0
+gisounddb[206][0] ftgen 0,0,0,1,"sounds/Water/Droplets/465.mp3",0,0,0
+gisounddb[207][0] ftgen 0,0,0,1,"sounds/Water/Droplets/170.mp3",0,0,0
+gisounddb[208][0] ftgen 0,0,0,1,"sounds/Water/Droplets/134.mp3",0,0,0
+gisounddb[209][0] ftgen 0,0,0,1,"sounds/Water/Droplets/189.mp3",0,0,0
+gisounddb[210][0] ftgen 0,0,0,1,"sounds/Water/Droplets/90.mp3",0,0,0
+gisounddb[211][0] ftgen 0,0,0,1,"sounds/Water/Droplets/536.mp3",0,0,0
+gisounddb[212][0] ftgen 0,0,0,1,"sounds/Water/Droplets/492.mp3",0,0,0
+gisounddb[213][0] ftgen 0,0,0,1,"sounds/Water/Droplets/448.mp3",0,0,0
+gisounddb[214][0] ftgen 0,0,0,1,"sounds/Water/Droplets/451.mp3",0,0,0
+gisounddb[215][0] ftgen 0,0,0,1,"sounds/Water/Droplets/280.mp3",0,0,0
+gisounddb[216][0] ftgen 0,0,0,1,"sounds/Water/Droplets/337.mp3",0,0,0
+gisounddb[217][0] ftgen 0,0,0,1,"sounds/Water/Droplets/463.mp3",0,0,0
+gisounddb[218][0] ftgen 0,0,0,1,"sounds/Water/Droplets/32.mp3",0,0,0
+gisounddb[219][0] ftgen 0,0,0,1,"sounds/Water/Droplets/563.mp3",0,0,0
+gisounddb[220][0] ftgen 0,0,0,1,"sounds/Water/Droplets/497.mp3",0,0,0
+gisounddb[221][0] ftgen 0,0,0,1,"sounds/Water/Droplets/553.mp3",0,0,0
+gisounddb[222][0] ftgen 0,0,0,1,"sounds/Water/Droplets/368.mp3",0,0,0
+gisounddb[223][0] ftgen 0,0,0,1,"sounds/Water/Droplets/458.mp3",0,0,0
+gisounddb[224][0] ftgen 0,0,0,1,"sounds/Water/Droplets/490.mp3",0,0,0
+gisounddb[225][0] ftgen 0,0,0,1,"sounds/Water/Droplets/99.mp3",0,0,0
+gisounddb[226][0] ftgen 0,0,0,1,"sounds/Water/Droplets/71.mp3",0,0,0
+gisounddb[227][0] ftgen 0,0,0,1,"sounds/Water/Droplets/441.mp3",0,0,0
+gisounddb[228][0] ftgen 0,0,0,1,"sounds/Water/Droplets/480.mp3",0,0,0
+gisounddb[229][0] ftgen 0,0,0,1,"sounds/Water/Droplets/264.mp3",0,0,0
+gisounddb[230][0] ftgen 0,0,0,1,"sounds/Water/Droplets/190.mp3",0,0,0
+gisounddb[231][0] ftgen 0,0,0,1,"sounds/Water/Droplets/507.mp3",0,0,0
+gisounddb[232][0] ftgen 0,0,0,1,"sounds/Water/Droplets/225.mp3",0,0,0
+gisounddb[233][0] ftgen 0,0,0,1,"sounds/Water/Droplets/175.mp3",0,0,0
+gisounddb[234][0] ftgen 0,0,0,1,"sounds/Water/Droplets/437.mp3",0,0,0
+gisounddb[235][0] ftgen 0,0,0,1,"sounds/Water/Droplets/572.mp3",0,0,0
+gisounddb[236][0] ftgen 0,0,0,1,"sounds/Water/Droplets/515.mp3",0,0,0
+gisounddb[237][0] ftgen 0,0,0,1,"sounds/Water/Droplets/144.mp3",0,0,0
+gisounddb[238][0] ftgen 0,0,0,1,"sounds/Water/Droplets/538.mp3",0,0,0
+gisounddb[239][0] ftgen 0,0,0,1,"sounds/Water/Droplets/476.mp3",0,0,0
+gisounddb[240][0] ftgen 0,0,0,1,"sounds/Water/Droplets/268.mp3",0,0,0
+gisounddb[241][0] ftgen 0,0,0,1,"sounds/Water/Droplets/326.mp3",0,0,0
+gisounddb[242][0] ftgen 0,0,0,1,"sounds/Water/Droplets/539.mp3",0,0,0
+gisounddb[243][0] ftgen 0,0,0,1,"sounds/Water/Droplets/121.mp3",0,0,0
+gisounddb[244][0] ftgen 0,0,0,1,"sounds/Water/Droplets/129.mp3",0,0,0
+gisounddb[245][0] ftgen 0,0,0,1,"sounds/Water/Droplets/185.mp3",0,0,0
+gisounddb[246][0] ftgen 0,0,0,1,"sounds/Water/Droplets/113.mp3",0,0,0
+gisounddb[247][0] ftgen 0,0,0,1,"sounds/Water/Droplets/57.mp3",0,0,0
+gisounddb[248][0] ftgen 0,0,0,1,"sounds/Water/Droplets/230.mp3",0,0,0
+gisounddb[249][0] ftgen 0,0,0,1,"sounds/Water/Droplets/566.mp3",0,0,0
+gisounddb[250][0] ftgen 0,0,0,1,"sounds/Water/Droplets/429.mp3",0,0,0
+gisounddb[251][0] ftgen 0,0,0,1,"sounds/Water/Droplets/342.mp3",0,0,0
+gisounddb[252][0] ftgen 0,0,0,1,"sounds/Water/Droplets/325.mp3",0,0,0
+gisounddb[253][0] ftgen 0,0,0,1,"sounds/Water/Droplets/521.mp3",0,0,0
+gisounddb[254][0] ftgen 0,0,0,1,"sounds/Water/Droplets/426.mp3",0,0,0
+gisounddb[255][0] ftgen 0,0,0,1,"sounds/Water/Droplets/484.mp3",0,0,0
+gisounddb[256][0] ftgen 0,0,0,1,"sounds/Water/Droplets/322.mp3",0,0,0
+gisounddb[257][0] ftgen 0,0,0,1,"sounds/Water/Droplets/333.mp3",0,0,0
+gisounddb[258][0] ftgen 0,0,0,1,"sounds/Water/Droplets/388.mp3",0,0,0
+gisounddb[259][0] ftgen 0,0,0,1,"sounds/Water/Droplets/335.mp3",0,0,0
+gisounddb[260][0] ftgen 0,0,0,1,"sounds/Water/Droplets/247.mp3",0,0,0
+gisounddb[261][0] ftgen 0,0,0,1,"sounds/Water/Droplets/565.mp3",0,0,0
+gisounddb[262][0] ftgen 0,0,0,1,"sounds/Water/Droplets/547.mp3",0,0,0
+gisounddb[263][0] ftgen 0,0,0,1,"sounds/Water/Droplets/3.mp3",0,0,0
+gisounddb[264][0] ftgen 0,0,0,1,"sounds/Water/Droplets/419.mp3",0,0,0
+gisounddb[265][0] ftgen 0,0,0,1,"sounds/Water/Droplets/159.mp3",0,0,0
+gisounddb[266][0] ftgen 0,0,0,1,"sounds/Water/Droplets/53.mp3",0,0,0
+gisounddb[267][0] ftgen 0,0,0,1,"sounds/Water/Droplets/253.mp3",0,0,0
+gisounddb[268][0] ftgen 0,0,0,1,"sounds/Water/Droplets/535.mp3",0,0,0
+gisounddb[269][0] ftgen 0,0,0,1,"sounds/Water/Droplets/443.mp3",0,0,0
+gisounddb[270][0] ftgen 0,0,0,1,"sounds/Water/Droplets/286.mp3",0,0,0
+gisounddb[271][0] ftgen 0,0,0,1,"sounds/Water/Droplets/291.mp3",0,0,0
+gisounddb[272][0] ftgen 0,0,0,1,"sounds/Water/Droplets/518.mp3",0,0,0
+gisounddb[273][0] ftgen 0,0,0,1,"sounds/Water/Droplets/516.mp3",0,0,0
+gisounddb[274][0] ftgen 0,0,0,1,"sounds/Water/Droplets/421.mp3",0,0,0
+gisounddb[275][0] ftgen 0,0,0,1,"sounds/Water/Droplets/4.mp3",0,0,0
+gisounddb[276][0] ftgen 0,0,0,1,"sounds/Water/Droplets/349.mp3",0,0,0
+gisounddb[277][0] ftgen 0,0,0,1,"sounds/Water/Droplets/493.mp3",0,0,0
+gisounddb[278][0] ftgen 0,0,0,1,"sounds/Water/Droplets/369.mp3",0,0,0
+gisounddb[279][0] ftgen 0,0,0,1,"sounds/Water/Droplets/467.mp3",0,0,0
+gisounddb[280][0] ftgen 0,0,0,1,"sounds/Water/Droplets/96.mp3",0,0,0
+gisounddb[281][0] ftgen 0,0,0,1,"sounds/Water/Droplets/389.mp3",0,0,0
+gisounddb[282][0] ftgen 0,0,0,1,"sounds/Water/Droplets/571.mp3",0,0,0
+gisounddb[283][0] ftgen 0,0,0,1,"sounds/Water/Droplets/76.mp3",0,0,0
+gisounddb[284][0] ftgen 0,0,0,1,"sounds/Water/Droplets/433.mp3",0,0,0
+gisounddb[285][0] ftgen 0,0,0,1,"sounds/Water/Droplets/165.mp3",0,0,0
+gisounddb[286][0] ftgen 0,0,0,1,"sounds/Water/Droplets/391.mp3",0,0,0
+gisounddb[287][0] ftgen 0,0,0,1,"sounds/Water/Droplets/415.mp3",0,0,0
+gisounddb[288][0] ftgen 0,0,0,1,"sounds/Water/Droplets/69.mp3",0,0,0
+gisounddb[289][0] ftgen 0,0,0,1,"sounds/Water/Droplets/216.mp3",0,0,0
+gisounddb[290][0] ftgen 0,0,0,1,"sounds/Water/Droplets/54.mp3",0,0,0
+gisounddb[291][0] ftgen 0,0,0,1,"sounds/Water/Droplets/150.mp3",0,0,0
+gisounddb[292][0] ftgen 0,0,0,1,"sounds/Water/Droplets/254.mp3",0,0,0
+gisounddb[293][0] ftgen 0,0,0,1,"sounds/Water/Droplets/354.mp3",0,0,0
+gisounddb[294][0] ftgen 0,0,0,1,"sounds/Water/Droplets/122.mp3",0,0,0
+gisounddb[295][0] ftgen 0,0,0,1,"sounds/Water/Droplets/266.mp3",0,0,0
+gisounddb[296][0] ftgen 0,0,0,1,"sounds/Water/Droplets/11.mp3",0,0,0
+gisounddb[297][0] ftgen 0,0,0,1,"sounds/Water/Droplets/166.mp3",0,0,0
+gisounddb[298][0] ftgen 0,0,0,1,"sounds/Water/Droplets/142.mp3",0,0,0
+gisounddb[299][0] ftgen 0,0,0,1,"sounds/Water/Droplets/351.mp3",0,0,0
+gisounddb[300][0] ftgen 0,0,0,1,"sounds/Water/Droplets/151.mp3",0,0,0
+gisounddb[301][0] ftgen 0,0,0,1,"sounds/Water/Droplets/355.mp3",0,0,0
+gisounddb[302][0] ftgen 0,0,0,1,"sounds/Water/Droplets/79.mp3",0,0,0
+gisounddb[303][0] ftgen 0,0,0,1,"sounds/Water/Droplets/193.mp3",0,0,0
+gisounddb[304][0] ftgen 0,0,0,1,"sounds/Water/Droplets/385.mp3",0,0,0
+gisounddb[305][0] ftgen 0,0,0,1,"sounds/Water/Droplets/78.mp3",0,0,0
+gisounddb[306][0] ftgen 0,0,0,1,"sounds/Water/Droplets/200.mp3",0,0,0
+gisounddb[307][0] ftgen 0,0,0,1,"sounds/Water/Droplets/401.mp3",0,0,0
+gisounddb[308][0] ftgen 0,0,0,1,"sounds/Water/Droplets/487.mp3",0,0,0
+gisounddb[309][0] ftgen 0,0,0,1,"sounds/Water/Droplets/250.mp3",0,0,0
+gisounddb[310][0] ftgen 0,0,0,1,"sounds/Water/Droplets/196.mp3",0,0,0
+gisounddb[311][0] ftgen 0,0,0,1,"sounds/Water/Droplets/237.mp3",0,0,0
+gisounddb[312][0] ftgen 0,0,0,1,"sounds/Water/Droplets/568.mp3",0,0,0
+gisounddb[313][0] ftgen 0,0,0,1,"sounds/Water/Droplets/352.mp3",0,0,0
+gisounddb[314][0] ftgen 0,0,0,1,"sounds/Water/Droplets/452.mp3",0,0,0
+gisounddb[315][0] ftgen 0,0,0,1,"sounds/Water/Droplets/434.mp3",0,0,0
+gisounddb[316][0] ftgen 0,0,0,1,"sounds/Water/Droplets/25.mp3",0,0,0
+gisounddb[317][0] ftgen 0,0,0,1,"sounds/Water/Droplets/382.mp3",0,0,0
+gisounddb[318][0] ftgen 0,0,0,1,"sounds/Water/Droplets/425.mp3",0,0,0
+gisounddb[319][0] ftgen 0,0,0,1,"sounds/Water/Droplets/146.mp3",0,0,0
+gisounddb[320][0] ftgen 0,0,0,1,"sounds/Water/Droplets/181.mp3",0,0,0
+gisounddb[321][0] ftgen 0,0,0,1,"sounds/Water/Droplets/383.mp3",0,0,0
+gisounddb[322][0] ftgen 0,0,0,1,"sounds/Water/Droplets/66.mp3",0,0,0
+gisounddb[323][0] ftgen 0,0,0,1,"sounds/Water/Droplets/554.mp3",0,0,0
+gisounddb[324][0] ftgen 0,0,0,1,"sounds/Water/Droplets/176.mp3",0,0,0
+gisounddb[325][0] ftgen 0,0,0,1,"sounds/Water/Droplets/47.mp3",0,0,0
+gisounddb[326][0] ftgen 0,0,0,1,"sounds/Water/Droplets/48.mp3",0,0,0
+gisounddb[327][0] ftgen 0,0,0,1,"sounds/Water/Droplets/478.mp3",0,0,0
+gisounddb[328][0] ftgen 0,0,0,1,"sounds/Water/Droplets/68.mp3",0,0,0
+gisounddb[329][0] ftgen 0,0,0,1,"sounds/Water/Droplets/92.mp3",0,0,0
+gisounddb[330][0] ftgen 0,0,0,1,"sounds/Water/Droplets/402.mp3",0,0,0
+gisounddb[331][0] ftgen 0,0,0,1,"sounds/Water/Droplets/411.mp3",0,0,0
+gisounddb[332][0] ftgen 0,0,0,1,"sounds/Water/Droplets/308.mp3",0,0,0
+gisounddb[333][0] ftgen 0,0,0,1,"sounds/Water/Droplets/481.mp3",0,0,0
+gisounddb[334][0] ftgen 0,0,0,1,"sounds/Water/Droplets/119.mp3",0,0,0
+gisounddb[335][0] ftgen 0,0,0,1,"sounds/Water/Droplets/249.mp3",0,0,0
+gisounddb[336][0] ftgen 0,0,0,1,"sounds/Water/Droplets/152.mp3",0,0,0
+gisounddb[337][0] ftgen 0,0,0,1,"sounds/Water/Droplets/262.mp3",0,0,0
+gisounddb[338][0] ftgen 0,0,0,1,"sounds/Water/Droplets/278.mp3",0,0,0
+gisounddb[339][0] ftgen 0,0,0,1,"sounds/Water/Droplets/33.mp3",0,0,0
+gisounddb[340][0] ftgen 0,0,0,1,"sounds/Water/Droplets/106.mp3",0,0,0
+gisounddb[341][0] ftgen 0,0,0,1,"sounds/Water/Droplets/136.mp3",0,0,0
+gisounddb[342][0] ftgen 0,0,0,1,"sounds/Water/Droplets/41.mp3",0,0,0
+gisounddb[343][0] ftgen 0,0,0,1,"sounds/Water/Droplets/362.mp3",0,0,0
+gisounddb[344][0] ftgen 0,0,0,1,"sounds/Water/Droplets/444.mp3",0,0,0
+gisounddb[345][0] ftgen 0,0,0,1,"sounds/Water/Droplets/310.mp3",0,0,0
+gisounddb[346][0] ftgen 0,0,0,1,"sounds/Water/Droplets/35.mp3",0,0,0
+gisounddb[347][0] ftgen 0,0,0,1,"sounds/Water/Droplets/102.mp3",0,0,0
+gisounddb[348][0] ftgen 0,0,0,1,"sounds/Water/Droplets/16.mp3",0,0,0
+gisounddb[349][0] ftgen 0,0,0,1,"sounds/Water/Droplets/276.mp3",0,0,0
+gisounddb[350][0] ftgen 0,0,0,1,"sounds/Water/Droplets/10.mp3",0,0,0
+gisounddb[351][0] ftgen 0,0,0,1,"sounds/Water/Droplets/265.mp3",0,0,0
+gisounddb[352][0] ftgen 0,0,0,1,"sounds/Water/Droplets/293.mp3",0,0,0
+gisounddb[353][0] ftgen 0,0,0,1,"sounds/Water/Droplets/108.mp3",0,0,0
+gisounddb[354][0] ftgen 0,0,0,1,"sounds/Water/Droplets/418.mp3",0,0,0
+gisounddb[355][0] ftgen 0,0,0,1,"sounds/Water/Droplets/384.mp3",0,0,0
+gisounddb[356][0] ftgen 0,0,0,1,"sounds/Water/Droplets/398.mp3",0,0,0
+gisounddb[357][0] ftgen 0,0,0,1,"sounds/Water/Droplets/364.mp3",0,0,0
+gisounddb[358][0] ftgen 0,0,0,1,"sounds/Water/Droplets/80.mp3",0,0,0
+gisounddb[359][0] ftgen 0,0,0,1,"sounds/Water/Droplets/341.mp3",0,0,0
+gisounddb[360][0] ftgen 0,0,0,1,"sounds/Water/Droplets/117.mp3",0,0,0
+gisounddb[361][0] ftgen 0,0,0,1,"sounds/Water/Droplets/179.mp3",0,0,0
+gisounddb[362][0] ftgen 0,0,0,1,"sounds/Water/Droplets/221.mp3",0,0,0
+gisounddb[363][0] ftgen 0,0,0,1,"sounds/Water/Droplets/89.mp3",0,0,0
+gisounddb[364][0] ftgen 0,0,0,1,"sounds/Water/Droplets/257.mp3",0,0,0
+gisounddb[365][0] ftgen 0,0,0,1,"sounds/Water/Droplets/51.mp3",0,0,0
+gisounddb[366][0] ftgen 0,0,0,1,"sounds/Water/Droplets/65.mp3",0,0,0
+gisounddb[367][0] ftgen 0,0,0,1,"sounds/Water/Droplets/177.mp3",0,0,0
+gisounddb[368][0] ftgen 0,0,0,1,"sounds/Water/Droplets/357.mp3",0,0,0
+gisounddb[369][0] ftgen 0,0,0,1,"sounds/Water/Droplets/29.mp3",0,0,0
+gisounddb[370][0] ftgen 0,0,0,1,"sounds/Water/Droplets/557.mp3",0,0,0
+gisounddb[371][0] ftgen 0,0,0,1,"sounds/Water/Droplets/372.mp3",0,0,0
+gisounddb[372][0] ftgen 0,0,0,1,"sounds/Water/Droplets/246.mp3",0,0,0
+gisounddb[373][0] ftgen 0,0,0,1,"sounds/Water/Droplets/405.mp3",0,0,0
+gisounddb[374][0] ftgen 0,0,0,1,"sounds/Water/Droplets/336.mp3",0,0,0
+gisounddb[375][0] ftgen 0,0,0,1,"sounds/Water/Droplets/573.mp3",0,0,0
+gisounddb[376][0] ftgen 0,0,0,1,"sounds/Water/Droplets/2.mp3",0,0,0
+gisounddb[377][0] ftgen 0,0,0,1,"sounds/Water/Droplets/158.mp3",0,0,0
+gisounddb[378][0] ftgen 0,0,0,1,"sounds/Water/Droplets/312.mp3",0,0,0
+gisounddb[379][0] ftgen 0,0,0,1,"sounds/Water/Droplets/167.mp3",0,0,0
+gisounddb[380][0] ftgen 0,0,0,1,"sounds/Water/Droplets/508.mp3",0,0,0
+gisounddb[381][0] ftgen 0,0,0,1,"sounds/Water/Droplets/133.mp3",0,0,0
+gisounddb[382][0] ftgen 0,0,0,1,"sounds/Water/Droplets/252.mp3",0,0,0
+gisounddb[383][0] ftgen 0,0,0,1,"sounds/Water/Droplets/211.mp3",0,0,0
+gisounddb[384][0] ftgen 0,0,0,1,"sounds/Water/Droplets/294.mp3",0,0,0
+gisounddb[385][0] ftgen 0,0,0,1,"sounds/Water/Droplets/360.mp3",0,0,0
+gisounddb[386][0] ftgen 0,0,0,1,"sounds/Water/Droplets/116.mp3",0,0,0
+gisounddb[387][0] ftgen 0,0,0,1,"sounds/Water/Droplets/338.mp3",0,0,0
+gisounddb[388][0] ftgen 0,0,0,1,"sounds/Water/Droplets/232.mp3",0,0,0
+gisounddb[389][0] ftgen 0,0,0,1,"sounds/Water/Droplets/43.mp3",0,0,0
+gisounddb[390][0] ftgen 0,0,0,1,"sounds/Water/Droplets/567.mp3",0,0,0
+gisounddb[391][0] ftgen 0,0,0,1,"sounds/Water/Droplets/446.mp3",0,0,0
+gisounddb[392][0] ftgen 0,0,0,1,"sounds/Water/Droplets/86.mp3",0,0,0
+gisounddb[393][0] ftgen 0,0,0,1,"sounds/Water/Droplets/414.mp3",0,0,0
+gisounddb[394][0] ftgen 0,0,0,1,"sounds/Water/Droplets/307.mp3",0,0,0
+gisounddb[395][0] ftgen 0,0,0,1,"sounds/Water/Droplets/334.mp3",0,0,0
+gisounddb[396][0] ftgen 0,0,0,1,"sounds/Water/Droplets/350.mp3",0,0,0
+gisounddb[397][0] ftgen 0,0,0,1,"sounds/Water/Droplets/297.mp3",0,0,0
+gisounddb[398][0] ftgen 0,0,0,1,"sounds/Water/Droplets/155.mp3",0,0,0
+gisounddb[399][0] ftgen 0,0,0,1,"sounds/Water/Droplets/15.mp3",0,0,0
+gisounddb[400][0] ftgen 0,0,0,1,"sounds/Water/Droplets/575.mp3",0,0,0
+gisounddb[401][0] ftgen 0,0,0,1,"sounds/Water/Droplets/83.mp3",0,0,0
+gisounddb[402][0] ftgen 0,0,0,1,"sounds/Water/Droplets/140.mp3",0,0,0
+gisounddb[403][0] ftgen 0,0,0,1,"sounds/Water/Droplets/428.mp3",0,0,0
+gisounddb[404][0] ftgen 0,0,0,1,"sounds/Water/Droplets/172.mp3",0,0,0
+gisounddb[405][0] ftgen 0,0,0,1,"sounds/Water/Droplets/436.mp3",0,0,0
+gisounddb[406][0] ftgen 0,0,0,1,"sounds/Water/Droplets/577.mp3",0,0,0
+gisounddb[407][0] ftgen 0,0,0,1,"sounds/Water/Droplets/222.mp3",0,0,0
+gisounddb[408][0] ftgen 0,0,0,1,"sounds/Water/Droplets/212.mp3",0,0,0
+gisounddb[409][0] ftgen 0,0,0,1,"sounds/Water/Droplets/219.mp3",0,0,0
+gisounddb[410][0] ftgen 0,0,0,1,"sounds/Water/Droplets/379.mp3",0,0,0
+gisounddb[411][0] ftgen 0,0,0,1,"sounds/Water/Droplets/578.mp3",0,0,0
+gisounddb[412][0] ftgen 0,0,0,1,"sounds/Water/Droplets/275.mp3",0,0,0
+gisounddb[413][0] ftgen 0,0,0,1,"sounds/Water/Droplets/273.mp3",0,0,0
+gisounddb[414][0] ftgen 0,0,0,1,"sounds/Water/Droplets/570.mp3",0,0,0
+gisounddb[415][0] ftgen 0,0,0,1,"sounds/Water/Droplets/347.mp3",0,0,0
+gisounddb[416][0] ftgen 0,0,0,1,"sounds/Water/Droplets/395.mp3",0,0,0
+gisounddb[417][0] ftgen 0,0,0,1,"sounds/Water/Droplets/87.mp3",0,0,0
+gisounddb[418][0] ftgen 0,0,0,1,"sounds/Water/Droplets/13.mp3",0,0,0
+gisounddb[419][0] ftgen 0,0,0,1,"sounds/Water/Droplets/207.mp3",0,0,0
+gisounddb[420][0] ftgen 0,0,0,1,"sounds/Water/Droplets/206.mp3",0,0,0
+gisounddb[421][0] ftgen 0,0,0,1,"sounds/Water/Droplets/306.mp3",0,0,0
+gisounddb[422][0] ftgen 0,0,0,1,"sounds/Water/Droplets/522.mp3",0,0,0
+gisounddb[423][0] ftgen 0,0,0,1,"sounds/Water/Droplets/313.mp3",0,0,0
+gisounddb[424][0] ftgen 0,0,0,1,"sounds/Water/Droplets/19.mp3",0,0,0
+gisounddb[425][0] ftgen 0,0,0,1,"sounds/Water/Droplets/445.mp3",0,0,0
+gisounddb[426][0] ftgen 0,0,0,1,"sounds/Water/Droplets/6.mp3",0,0,0
+gisounddb[427][0] ftgen 0,0,0,1,"sounds/Water/Droplets/509.mp3",0,0,0
+gisounddb[428][0] ftgen 0,0,0,1,"sounds/Water/Droplets/227.mp3",0,0,0
+gisounddb[429][0] ftgen 0,0,0,1,"sounds/Water/Droplets/386.mp3",0,0,0
+gisounddb[430][0] ftgen 0,0,0,1,"sounds/Water/Droplets/213.mp3",0,0,0
+gisounddb[431][0] ftgen 0,0,0,1,"sounds/Water/Droplets/243.mp3",0,0,0
+gisounddb[432][0] ftgen 0,0,0,1,"sounds/Water/Droplets/82.mp3",0,0,0
+gisounddb[433][0] ftgen 0,0,0,1,"sounds/Water/Droplets/524.mp3",0,0,0
+gisounddb[434][0] ftgen 0,0,0,1,"sounds/Water/Droplets/209.mp3",0,0,0
+gisounddb[435][0] ftgen 0,0,0,1,"sounds/Water/Droplets/317.mp3",0,0,0
+gisounddb[436][0] ftgen 0,0,0,1,"sounds/Water/Droplets/489.mp3",0,0,0
+gisounddb[437][0] ftgen 0,0,0,1,"sounds/Water/Droplets/371.mp3",0,0,0
+gisounddb[438][0] ftgen 0,0,0,1,"sounds/Water/Droplets/523.mp3",0,0,0
+gisounddb[439][0] ftgen 0,0,0,1,"sounds/Water/Droplets/118.mp3",0,0,0
+gisounddb[440][0] ftgen 0,0,0,1,"sounds/Water/Droplets/455.mp3",0,0,0
+gisounddb[441][0] ftgen 0,0,0,1,"sounds/Water/Droplets/229.mp3",0,0,0
+gisounddb[442][0] ftgen 0,0,0,1,"sounds/Water/Droplets/459.mp3",0,0,0
+gisounddb[443][0] ftgen 0,0,0,1,"sounds/Water/Droplets/123.mp3",0,0,0
+gisounddb[444][0] ftgen 0,0,0,1,"sounds/Water/Droplets/387.mp3",0,0,0
+gisounddb[445][0] ftgen 0,0,0,1,"sounds/Water/Droplets/120.mp3",0,0,0
+gisounddb[446][0] ftgen 0,0,0,1,"sounds/Water/Droplets/14.mp3",0,0,0
+gisounddb[447][0] ftgen 0,0,0,1,"sounds/Water/Droplets/255.mp3",0,0,0
+gisounddb[448][0] ftgen 0,0,0,1,"sounds/Water/Droplets/101.mp3",0,0,0
+gisounddb[449][0] ftgen 0,0,0,1,"sounds/Water/Droplets/477.mp3",0,0,0
+gisounddb[450][0] ftgen 0,0,0,1,"sounds/Water/Droplets/412.mp3",0,0,0
+gisounddb[451][0] ftgen 0,0,0,1,"sounds/Water/Droplets/114.mp3",0,0,0
+gisounddb[452][0] ftgen 0,0,0,1,"sounds/Water/Droplets/282.mp3",0,0,0
+gisounddb[453][0] ftgen 0,0,0,1,"sounds/Water/Droplets/346.mp3",0,0,0
+gisounddb[454][0] ftgen 0,0,0,1,"sounds/Water/Droplets/188.mp3",0,0,0
+gisounddb[455][0] ftgen 0,0,0,1,"sounds/Water/Droplets/112.mp3",0,0,0
+gisounddb[456][0] ftgen 0,0,0,1,"sounds/Water/Droplets/283.mp3",0,0,0
+gisounddb[457][0] ftgen 0,0,0,1,"sounds/Water/Droplets/236.mp3",0,0,0
+gisounddb[458][0] ftgen 0,0,0,1,"sounds/Water/Droplets/22.mp3",0,0,0
+gisounddb[459][0] ftgen 0,0,0,1,"sounds/Water/Droplets/52.mp3",0,0,0
+gisounddb[460][0] ftgen 0,0,0,1,"sounds/Water/Droplets/91.mp3",0,0,0
+gisounddb[461][0] ftgen 0,0,0,1,"sounds/Water/Droplets/234.mp3",0,0,0
+gisounddb[462][0] ftgen 0,0,0,1,"sounds/Water/Droplets/244.mp3",0,0,0
+gisounddb[463][0] ftgen 0,0,0,1,"sounds/Water/Droplets/339.mp3",0,0,0
+gisounddb[464][0] ftgen 0,0,0,1,"sounds/Water/Droplets/439.mp3",0,0,0
+gisounddb[465][0] ftgen 0,0,0,1,"sounds/Water/Droplets/541.mp3",0,0,0
+gisounddb[466][0] ftgen 0,0,0,1,"sounds/Water/Droplets/284.mp3",0,0,0
+gisounddb[467][0] ftgen 0,0,0,1,"sounds/Water/Droplets/214.mp3",0,0,0
+gisounddb[468][0] ftgen 0,0,0,1,"sounds/Water/Droplets/241.mp3",0,0,0
+gisounddb[469][0] ftgen 0,0,0,1,"sounds/Water/Droplets/356.mp3",0,0,0
+gisounddb[470][0] ftgen 0,0,0,1,"sounds/Water/Droplets/168.mp3",0,0,0
+gisounddb[471][0] ftgen 0,0,0,1,"sounds/Water/Droplets/56.mp3",0,0,0
+gisounddb[472][0] ftgen 0,0,0,1,"sounds/Water/Droplets/220.mp3",0,0,0
+gisounddb[473][0] ftgen 0,0,0,1,"sounds/Water/Droplets/94.mp3",0,0,0
+gisounddb[474][0] ftgen 0,0,0,1,"sounds/Water/Droplets/374.mp3",0,0,0
+gisounddb[475][0] ftgen 0,0,0,1,"sounds/Water/Droplets/409.mp3",0,0,0
+gisounddb[476][0] ftgen 0,0,0,1,"sounds/Water/Droplets/183.mp3",0,0,0
+gisounddb[477][0] ftgen 0,0,0,1,"sounds/Water/Droplets/558.mp3",0,0,0
+gisounddb[478][0] ftgen 0,0,0,1,"sounds/Water/Droplets/471.mp3",0,0,0
+gisounddb[479][0] ftgen 0,0,0,1,"sounds/Water/Droplets/424.mp3",0,0,0
+gisounddb[480][0] ftgen 0,0,0,1,"sounds/Water/Droplets/191.mp3",0,0,0
+gisounddb[481][0] ftgen 0,0,0,1,"sounds/Water/Droplets/238.mp3",0,0,0
+gisounddb[482][0] ftgen 0,0,0,1,"sounds/Water/Droplets/496.mp3",0,0,0
+gisounddb[483][0] ftgen 0,0,0,1,"sounds/Water/Droplets/562.mp3",0,0,0
+gisounddb[484][0] ftgen 0,0,0,1,"sounds/Water/Droplets/248.mp3",0,0,0
+gisounddb[485][0] ftgen 0,0,0,1,"sounds/Water/Droplets/377.mp3",0,0,0
+gisounddb[486][0] ftgen 0,0,0,1,"sounds/Water/Droplets/438.mp3",0,0,0
+gisounddb[487][0] ftgen 0,0,0,1,"sounds/Water/Droplets/302.mp3",0,0,0
+gisounddb[488][0] ftgen 0,0,0,1,"sounds/Water/Droplets/231.mp3",0,0,0
+gisounddb[489][0] ftgen 0,0,0,1,"sounds/Water/Droplets/353.mp3",0,0,0
+gisounddb[490][0] ftgen 0,0,0,1,"sounds/Water/Droplets/542.mp3",0,0,0
+gisounddb[491][0] ftgen 0,0,0,1,"sounds/Water/Droplets/50.mp3",0,0,0
+gisounddb[492][0] ftgen 0,0,0,1,"sounds/Water/Droplets/501.mp3",0,0,0
+gisounddb[493][0] ftgen 0,0,0,1,"sounds/Water/Droplets/540.mp3",0,0,0
+gisounddb[494][0] ftgen 0,0,0,1,"sounds/Water/Droplets/267.mp3",0,0,0
+gisounddb[495][0] ftgen 0,0,0,1,"sounds/Water/Droplets/218.mp3",0,0,0
+gisounddb[496][0] ftgen 0,0,0,1,"sounds/Water/Droplets/296.mp3",0,0,0
+gisounddb[497][0] ftgen 0,0,0,1,"sounds/Water/Droplets/285.mp3",0,0,0
+gisounddb[498][0] ftgen 0,0,0,1,"sounds/Water/Droplets/64.mp3",0,0,0
+gisounddb[499][0] ftgen 0,0,0,1,"sounds/Water/Droplets/195.mp3",0,0,0
+gisounddb[500][0] ftgen 0,0,0,1,"sounds/Water/Droplets/270.mp3",0,0,0
+gisounddb[501][0] ftgen 0,0,0,1,"sounds/Water/Droplets/319.mp3",0,0,0
+gisounddb[502][0] ftgen 0,0,0,1,"sounds/Water/Droplets/500.mp3",0,0,0
+gisounddb[503][0] ftgen 0,0,0,1,"sounds/Water/Droplets/514.mp3",0,0,0
+gisounddb[504][0] ftgen 0,0,0,1,"sounds/Water/Droplets/457.mp3",0,0,0
+gisounddb[505][0] ftgen 0,0,0,1,"sounds/Water/Droplets/198.mp3",0,0,0
+gisounddb[506][0] ftgen 0,0,0,1,"sounds/Water/Droplets/564.mp3",0,0,0
+gisounddb[507][0] ftgen 0,0,0,1,"sounds/Water/Droplets/154.mp3",0,0,0
+gisounddb[508][0] ftgen 0,0,0,1,"sounds/Water/Droplets/31.mp3",0,0,0
+gisounddb[509][0] ftgen 0,0,0,1,"sounds/Water/Droplets/394.mp3",0,0,0
+gisounddb[510][0] ftgen 0,0,0,1,"sounds/Water/Droplets/485.mp3",0,0,0
+gisounddb[511][0] ftgen 0,0,0,1,"sounds/Water/Droplets/126.mp3",0,0,0
+gisounddb[512][0] ftgen 0,0,0,1,"sounds/Water/Droplets/261.mp3",0,0,0
+gisounddb[513][0] ftgen 0,0,0,1,"sounds/Water/Droplets/107.mp3",0,0,0
+gisounddb[514][0] ftgen 0,0,0,1,"sounds/Water/Droplets/115.mp3",0,0,0
+gisounddb[515][0] ftgen 0,0,0,1,"sounds/Water/Droplets/469.mp3",0,0,0
+gisounddb[516][0] ftgen 0,0,0,1,"sounds/Water/Droplets/240.mp3",0,0,0
+gisounddb[517][0] ftgen 0,0,0,1,"sounds/Water/Droplets/549.mp3",0,0,0
+gisounddb[518][0] ftgen 0,0,0,1,"sounds/Water/Droplets/186.mp3",0,0,0
+gisounddb[519][0] ftgen 0,0,0,1,"sounds/Water/Droplets/137.mp3",0,0,0
+gisounddb[520][0] ftgen 0,0,0,1,"sounds/Water/Droplets/161.mp3",0,0,0
+gisounddb[521][0] ftgen 0,0,0,1,"sounds/Water/Droplets/400.mp3",0,0,0
+gisounddb[522][0] ftgen 0,0,0,1,"sounds/Water/Droplets/279.mp3",0,0,0
+gisounddb[523][0] ftgen 0,0,0,1,"sounds/Water/Droplets/184.mp3",0,0,0
+gisounddb[524][0] ftgen 0,0,0,1,"sounds/Water/Droplets/215.mp3",0,0,0
+gisounddb[525][0] ftgen 0,0,0,1,"sounds/Water/Droplets/330.mp3",0,0,0
+gisounddb[526][0] ftgen 0,0,0,1,"sounds/Water/Droplets/529.mp3",0,0,0
+gisounddb[527][0] ftgen 0,0,0,1,"sounds/Water/Droplets/84.mp3",0,0,0
+gisounddb[528][0] ftgen 0,0,0,1,"sounds/Water/Droplets/376.mp3",0,0,0
+gisounddb[529][0] ftgen 0,0,0,1,"sounds/Water/Droplets/111.mp3",0,0,0
+gisounddb[530][0] ftgen 0,0,0,1,"sounds/Water/Droplets/97.mp3",0,0,0
+gisounddb[531][0] ftgen 0,0,0,1,"sounds/Water/Droplets/197.mp3",0,0,0
+gisounddb[532][0] ftgen 0,0,0,1,"sounds/Water/Droplets/73.mp3",0,0,0
+gisounddb[533][0] ftgen 0,0,0,1,"sounds/Water/Droplets/125.mp3",0,0,0
+gisounddb[534][0] ftgen 0,0,0,1,"sounds/Water/Droplets/422.mp3",0,0,0
+gisounddb[535][0] ftgen 0,0,0,1,"sounds/Water/Droplets/104.mp3",0,0,0
+gisounddb[536][0] ftgen 0,0,0,1,"sounds/Water/Droplets/156.mp3",0,0,0
+gisounddb[537][0] ftgen 0,0,0,1,"sounds/Water/Droplets/208.mp3",0,0,0
+gisounddb[538][0] ftgen 0,0,0,1,"sounds/Water/Droplets/464.mp3",0,0,0
+gisounddb[539][0] ftgen 0,0,0,1,"sounds/Water/Droplets/187.mp3",0,0,0
+gisounddb[540][0] ftgen 0,0,0,1,"sounds/Water/Droplets/110.mp3",0,0,0
+gisounddb[541][0] ftgen 0,0,0,1,"sounds/Water/Droplets/148.mp3",0,0,0
+gisounddb[542][0] ftgen 0,0,0,1,"sounds/Water/Droplets/20.mp3",0,0,0
+gisounddb[543][0] ftgen 0,0,0,1,"sounds/Water/Droplets/340.mp3",0,0,0
+gisounddb[544][0] ftgen 0,0,0,1,"sounds/Water/Droplets/277.mp3",0,0,0
+gisounddb[545][0] ftgen 0,0,0,1,"sounds/Water/Droplets/370.mp3",0,0,0
+gisounddb[546][0] ftgen 0,0,0,1,"sounds/Water/Droplets/269.mp3",0,0,0
+gisounddb[547][0] ftgen 0,0,0,1,"sounds/Water/Droplets/555.mp3",0,0,0
+gisounddb[548][0] ftgen 0,0,0,1,"sounds/Water/Droplets/495.mp3",0,0,0
+gisounddb[549][0] ftgen 0,0,0,1,"sounds/Water/Droplets/228.mp3",0,0,0
+gisounddb[550][0] ftgen 0,0,0,1,"sounds/Water/Droplets/574.mp3",0,0,0
+gisounddb[551][0] ftgen 0,0,0,1,"sounds/Water/Droplets/526.mp3",0,0,0
+gisounddb[552][0] ftgen 0,0,0,1,"sounds/Water/Droplets/143.mp3",0,0,0
+gisounddb[553][0] ftgen 0,0,0,1,"sounds/Water/Droplets/537.mp3",0,0,0
+gisounddb[554][0] ftgen 0,0,0,1,"sounds/Water/Droplets/304.mp3",0,0,0
+gisounddb[555][0] ftgen 0,0,0,1,"sounds/Water/Droplets/242.mp3",0,0,0
+gisounddb[556][0] ftgen 0,0,0,1,"sounds/Water/Droplets/324.mp3",0,0,0
+gisounddb[557][0] ftgen 0,0,0,1,"sounds/Water/Droplets/442.mp3",0,0,0
+gisounddb[558][0] ftgen 0,0,0,1,"sounds/Water/Droplets/528.mp3",0,0,0
+gisounddb[559][0] ftgen 0,0,0,1,"sounds/Water/Droplets/545.mp3",0,0,0
+gisounddb[560][0] ftgen 0,0,0,1,"sounds/Water/Droplets/513.mp3",0,0,0
+gisounddb[561][0] ftgen 0,0,0,1,"sounds/Water/Droplets/447.mp3",0,0,0
+gisounddb[562][0] ftgen 0,0,0,1,"sounds/Water/Droplets/7.mp3",0,0,0
+gisounddb[563][0] ftgen 0,0,0,1,"sounds/Water/Droplets/551.mp3",0,0,0
+gisounddb[564][0] ftgen 0,0,0,1,"sounds/Water/Droplets/63.mp3",0,0,0
+gisounddb[565][0] ftgen 0,0,0,1,"sounds/Water/Droplets/506.mp3",0,0,0
+gisounddb[566][0] ftgen 0,0,0,1,"sounds/Water/Droplets/127.mp3",0,0,0
+gisounddb[567][0] ftgen 0,0,0,1,"sounds/Water/Droplets/37.mp3",0,0,0
+gisounddb[568][0] ftgen 0,0,0,1,"sounds/Water/Droplets/327.mp3",0,0,0
+gisounddb[569][0] ftgen 0,0,0,1,"sounds/Water/Droplets/9.mp3",0,0,0
+gisounddb[570][0] ftgen 0,0,0,1,"sounds/Water/Droplets/24.mp3",0,0,0
+gisounddb[571][0] ftgen 0,0,0,1,"sounds/Water/Droplets/173.mp3",0,0,0
+gisounddb[572][0] ftgen 0,0,0,1,"sounds/Water/Droplets/204.mp3",0,0,0
+gisounddb[573][0] ftgen 0,0,0,1,"sounds/Water/Droplets/263.mp3",0,0,0
+gisounddb[574][0] ftgen 0,0,0,1,"sounds/Water/Droplets/194.mp3",0,0,0
+gisounddb[575][0] ftgen 0,0,0,1,"sounds/Water/Droplets/17.mp3",0,0,0
+gisounddb[576][0] ftgen 0,0,0,1,"sounds/Water/Droplets/303.mp3",0,0,0
+gisounddb[577][0] ftgen 0,0,0,1,"sounds/Water/Droplets/420.mp3",0,0,0
+gisounddb[578][0] ftgen 0,0,0,1,"sounds/Water/Paddling/45.mp3",0,0,0
+gisounddb[579][0] ftgen 0,0,0,1,"sounds/Water/Paddling/60.mp3",0,0,0
+gisounddb[580][0] ftgen 0,0,0,1,"sounds/Water/Paddling/59.mp3",0,0,0
+gisounddb[581][0] ftgen 0,0,0,1,"sounds/Water/Paddling/81.mp3",0,0,0
+gisounddb[582][0] ftgen 0,0,0,1,"sounds/Water/Paddling/38.mp3",0,0,0
+gisounddb[583][0] ftgen 0,0,0,1,"sounds/Water/Paddling/5.mp3",0,0,0
+gisounddb[584][0] ftgen 0,0,0,1,"sounds/Water/Paddling/85.mp3",0,0,0
+gisounddb[585][0] ftgen 0,0,0,1,"sounds/Water/Paddling/75.mp3",0,0,0
+gisounddb[586][0] ftgen 0,0,0,1,"sounds/Water/Paddling/88.mp3",0,0,0
+gisounddb[587][0] ftgen 0,0,0,1,"sounds/Water/Paddling/77.mp3",0,0,0
+gisounddb[588][0] ftgen 0,0,0,1,"sounds/Water/Paddling/70.mp3",0,0,0
+gisounddb[589][0] ftgen 0,0,0,1,"sounds/Water/Paddling/39.mp3",0,0,0
+gisounddb[590][0] ftgen 0,0,0,1,"sounds/Water/Paddling/62.mp3",0,0,0
+gisounddb[591][0] ftgen 0,0,0,1,"sounds/Water/Paddling/21.mp3",0,0,0
+gisounddb[592][0] ftgen 0,0,0,1,"sounds/Water/Paddling/40.mp3",0,0,0
+gisounddb[593][0] ftgen 0,0,0,1,"sounds/Water/Paddling/42.mp3",0,0,0
+gisounddb[594][0] ftgen 0,0,0,1,"sounds/Water/Paddling/98.mp3",0,0,0
+gisounddb[595][0] ftgen 0,0,0,1,"sounds/Water/Paddling/95.mp3",0,0,0
+gisounddb[596][0] ftgen 0,0,0,1,"sounds/Water/Paddling/74.mp3",0,0,0
+gisounddb[597][0] ftgen 0,0,0,1,"sounds/Water/Paddling/30.mp3",0,0,0
+gisounddb[598][0] ftgen 0,0,0,1,"sounds/Water/Paddling/100.mp3",0,0,0
+gisounddb[599][0] ftgen 0,0,0,1,"sounds/Water/Paddling/12.mp3",0,0,0
+gisounddb[600][0] ftgen 0,0,0,1,"sounds/Water/Paddling/44.mp3",0,0,0
+gisounddb[601][0] ftgen 0,0,0,1,"sounds/Water/Paddling/8.mp3",0,0,0
+gisounddb[602][0] ftgen 0,0,0,1,"sounds/Water/Paddling/46.mp3",0,0,0
+gisounddb[603][0] ftgen 0,0,0,1,"sounds/Water/Paddling/34.mp3",0,0,0
+gisounddb[604][0] ftgen 0,0,0,1,"sounds/Water/Paddling/93.mp3",0,0,0
+gisounddb[605][0] ftgen 0,0,0,1,"sounds/Water/Paddling/61.mp3",0,0,0
+gisounddb[606][0] ftgen 0,0,0,1,"sounds/Water/Paddling/67.mp3",0,0,0
+gisounddb[607][0] ftgen 0,0,0,1,"sounds/Water/Paddling/49.mp3",0,0,0
+gisounddb[608][0] ftgen 0,0,0,1,"sounds/Water/Paddling/55.mp3",0,0,0
+gisounddb[609][0] ftgen 0,0,0,1,"sounds/Water/Paddling/28.mp3",0,0,0
+gisounddb[610][0] ftgen 0,0,0,1,"sounds/Water/Paddling/23.mp3",0,0,0
+gisounddb[611][0] ftgen 0,0,0,1,"sounds/Water/Paddling/72.mp3",0,0,0
+gisounddb[612][0] ftgen 0,0,0,1,"sounds/Water/Paddling/1.mp3",0,0,0
+gisounddb[613][0] ftgen 0,0,0,1,"sounds/Water/Paddling/27.mp3",0,0,0
+gisounddb[614][0] ftgen 0,0,0,1,"sounds/Water/Paddling/58.mp3",0,0,0
+gisounddb[615][0] ftgen 0,0,0,1,"sounds/Water/Paddling/26.mp3",0,0,0
+gisounddb[616][0] ftgen 0,0,0,1,"sounds/Water/Paddling/36.mp3",0,0,0
+gisounddb[617][0] ftgen 0,0,0,1,"sounds/Water/Paddling/18.mp3",0,0,0
+gisounddb[618][0] ftgen 0,0,0,1,"sounds/Water/Paddling/90.mp3",0,0,0
+gisounddb[619][0] ftgen 0,0,0,1,"sounds/Water/Paddling/32.mp3",0,0,0
+gisounddb[620][0] ftgen 0,0,0,1,"sounds/Water/Paddling/99.mp3",0,0,0
+gisounddb[621][0] ftgen 0,0,0,1,"sounds/Water/Paddling/71.mp3",0,0,0
+gisounddb[622][0] ftgen 0,0,0,1,"sounds/Water/Paddling/57.mp3",0,0,0
+gisounddb[623][0] ftgen 0,0,0,1,"sounds/Water/Paddling/3.mp3",0,0,0
+gisounddb[624][0] ftgen 0,0,0,1,"sounds/Water/Paddling/53.mp3",0,0,0
+gisounddb[625][0] ftgen 0,0,0,1,"sounds/Water/Paddling/4.mp3",0,0,0
+gisounddb[626][0] ftgen 0,0,0,1,"sounds/Water/Paddling/96.mp3",0,0,0
+gisounddb[627][0] ftgen 0,0,0,1,"sounds/Water/Paddling/76.mp3",0,0,0
+gisounddb[628][0] ftgen 0,0,0,1,"sounds/Water/Paddling/69.mp3",0,0,0
+gisounddb[629][0] ftgen 0,0,0,1,"sounds/Water/Paddling/54.mp3",0,0,0
+gisounddb[630][0] ftgen 0,0,0,1,"sounds/Water/Paddling/11.mp3",0,0,0
+gisounddb[631][0] ftgen 0,0,0,1,"sounds/Water/Paddling/79.mp3",0,0,0
+gisounddb[632][0] ftgen 0,0,0,1,"sounds/Water/Paddling/78.mp3",0,0,0
+gisounddb[633][0] ftgen 0,0,0,1,"sounds/Water/Paddling/25.mp3",0,0,0
+gisounddb[634][0] ftgen 0,0,0,1,"sounds/Water/Paddling/66.mp3",0,0,0
+gisounddb[635][0] ftgen 0,0,0,1,"sounds/Water/Paddling/47.mp3",0,0,0
+gisounddb[636][0] ftgen 0,0,0,1,"sounds/Water/Paddling/48.mp3",0,0,0
+gisounddb[637][0] ftgen 0,0,0,1,"sounds/Water/Paddling/68.mp3",0,0,0
+gisounddb[638][0] ftgen 0,0,0,1,"sounds/Water/Paddling/92.mp3",0,0,0
+gisounddb[639][0] ftgen 0,0,0,1,"sounds/Water/Paddling/33.mp3",0,0,0
+gisounddb[640][0] ftgen 0,0,0,1,"sounds/Water/Paddling/41.mp3",0,0,0
+gisounddb[641][0] ftgen 0,0,0,1,"sounds/Water/Paddling/35.mp3",0,0,0
+gisounddb[642][0] ftgen 0,0,0,1,"sounds/Water/Paddling/16.mp3",0,0,0
+gisounddb[643][0] ftgen 0,0,0,1,"sounds/Water/Paddling/10.mp3",0,0,0
+gisounddb[644][0] ftgen 0,0,0,1,"sounds/Water/Paddling/80.mp3",0,0,0
+gisounddb[645][0] ftgen 0,0,0,1,"sounds/Water/Paddling/89.mp3",0,0,0
+gisounddb[646][0] ftgen 0,0,0,1,"sounds/Water/Paddling/51.mp3",0,0,0
+gisounddb[647][0] ftgen 0,0,0,1,"sounds/Water/Paddling/65.mp3",0,0,0
+gisounddb[648][0] ftgen 0,0,0,1,"sounds/Water/Paddling/29.mp3",0,0,0
+gisounddb[649][0] ftgen 0,0,0,1,"sounds/Water/Paddling/2.mp3",0,0,0
+gisounddb[650][0] ftgen 0,0,0,1,"sounds/Water/Paddling/43.mp3",0,0,0
+gisounddb[651][0] ftgen 0,0,0,1,"sounds/Water/Paddling/86.mp3",0,0,0
+gisounddb[652][0] ftgen 0,0,0,1,"sounds/Water/Paddling/15.mp3",0,0,0
+gisounddb[653][0] ftgen 0,0,0,1,"sounds/Water/Paddling/83.mp3",0,0,0
+gisounddb[654][0] ftgen 0,0,0,1,"sounds/Water/Paddling/87.mp3",0,0,0
+gisounddb[655][0] ftgen 0,0,0,1,"sounds/Water/Paddling/13.mp3",0,0,0
+gisounddb[656][0] ftgen 0,0,0,1,"sounds/Water/Paddling/19.mp3",0,0,0
+gisounddb[657][0] ftgen 0,0,0,1,"sounds/Water/Paddling/6.mp3",0,0,0
+gisounddb[658][0] ftgen 0,0,0,1,"sounds/Water/Paddling/82.mp3",0,0,0
+gisounddb[659][0] ftgen 0,0,0,1,"sounds/Water/Paddling/14.mp3",0,0,0
+gisounddb[660][0] ftgen 0,0,0,1,"sounds/Water/Paddling/22.mp3",0,0,0
+gisounddb[661][0] ftgen 0,0,0,1,"sounds/Water/Paddling/52.mp3",0,0,0
+gisounddb[662][0] ftgen 0,0,0,1,"sounds/Water/Paddling/91.mp3",0,0,0
+gisounddb[663][0] ftgen 0,0,0,1,"sounds/Water/Paddling/56.mp3",0,0,0
+gisounddb[664][0] ftgen 0,0,0,1,"sounds/Water/Paddling/94.mp3",0,0,0
+gisounddb[665][0] ftgen 0,0,0,1,"sounds/Water/Paddling/50.mp3",0,0,0
+gisounddb[666][0] ftgen 0,0,0,1,"sounds/Water/Paddling/64.mp3",0,0,0
+gisounddb[667][0] ftgen 0,0,0,1,"sounds/Water/Paddling/31.mp3",0,0,0
+gisounddb[668][0] ftgen 0,0,0,1,"sounds/Water/Paddling/84.mp3",0,0,0
+gisounddb[669][0] ftgen 0,0,0,1,"sounds/Water/Paddling/97.mp3",0,0,0
+gisounddb[670][0] ftgen 0,0,0,1,"sounds/Water/Paddling/73.mp3",0,0,0
+gisounddb[671][0] ftgen 0,0,0,1,"sounds/Water/Paddling/20.mp3",0,0,0
+gisounddb[672][0] ftgen 0,0,0,1,"sounds/Water/Paddling/7.mp3",0,0,0
+gisounddb[673][0] ftgen 0,0,0,1,"sounds/Water/Paddling/63.mp3",0,0,0
+gisounddb[674][0] ftgen 0,0,0,1,"sounds/Water/Paddling/37.mp3",0,0,0
+gisounddb[675][0] ftgen 0,0,0,1,"sounds/Water/Paddling/9.mp3",0,0,0
+gisounddb[676][0] ftgen 0,0,0,1,"sounds/Water/Paddling/24.mp3",0,0,0
+gisounddb[677][0] ftgen 0,0,0,1,"sounds/Water/Paddling/17.mp3",0,0,0
+gisounddb[678][0] ftgen 0,0,0,1,"sounds/MusicBox/89.3.mp3",0,0,0
+gisounddb[679][0] ftgen 0,0,0,1,"sounds/MusicBox/73.0.mp3",0,0,0
+gisounddb[680][0] ftgen 0,0,0,1,"sounds/MusicBox/77.0.mp3",0,0,0
+gisounddb[681][0] ftgen 0,0,0,1,"sounds/MusicBox/75.2.mp3",0,0,0
+gisounddb[682][0] ftgen 0,0,0,1,"sounds/MusicBox/92.1.mp3",0,0,0
+gisounddb[683][0] ftgen 0,0,0,1,"sounds/MusicBox/75.1.mp3",0,0,0
+gisounddb[684][0] ftgen 0,0,0,1,"sounds/MusicBox/68.2.mp3",0,0,0
+gisounddb[685][0] ftgen 0,0,0,1,"sounds/MusicBox/91.2.mp3",0,0,0
+gisounddb[686][0] ftgen 0,0,0,1,"sounds/MusicBox/85.3.mp3",0,0,0
+gisounddb[687][0] ftgen 0,0,0,1,"sounds/MusicBox/80.3.mp3",0,0,0
+gisounddb[688][0] ftgen 0,0,0,1,"sounds/MusicBox/92.0.mp3",0,0,0
+gisounddb[689][0] ftgen 0,0,0,1,"sounds/MusicBox/85.0.mp3",0,0,0
+gisounddb[690][0] ftgen 0,0,0,1,"sounds/MusicBox/68.3.mp3",0,0,0
+gisounddb[691][0] ftgen 0,0,0,1,"sounds/MusicBox/68.0.mp3",0,0,0
+gisounddb[692][0] ftgen 0,0,0,1,"sounds/MusicBox/77.3.mp3",0,0,0
+gisounddb[693][0] ftgen 0,0,0,1,"sounds/MusicBox/70.4.mp3",0,0,0
+gisounddb[694][0] ftgen 0,0,0,1,"sounds/MusicBox/73.1.mp3",0,0,0
+gisounddb[695][0] ftgen 0,0,0,1,"sounds/MusicBox/85.1.mp3",0,0,0
+gisounddb[696][0] ftgen 0,0,0,1,"sounds/MusicBox/79.1.mp3",0,0,0
+gisounddb[697][0] ftgen 0,0,0,1,"sounds/MusicBox/82.2.mp3",0,0,0
+gisounddb[698][0] ftgen 0,0,0,1,"sounds/MusicBox/70.1.mp3",0,0,0
+gisounddb[699][0] ftgen 0,0,0,1,"sounds/MusicBox/87.4.mp3",0,0,0
+gisounddb[700][0] ftgen 0,0,0,1,"sounds/MusicBox/80.1.mp3",0,0,0
+gisounddb[701][0] ftgen 0,0,0,1,"sounds/MusicBox/91.0.mp3",0,0,0
+gisounddb[702][0] ftgen 0,0,0,1,"sounds/MusicBox/82.3.mp3",0,0,0
+gisounddb[703][0] ftgen 0,0,0,1,"sounds/MusicBox/72.3.mp3",0,0,0
+gisounddb[704][0] ftgen 0,0,0,1,"sounds/MusicBox/79.0.mp3",0,0,0
+gisounddb[705][0] ftgen 0,0,0,1,"sounds/MusicBox/68.1.mp3",0,0,0
+gisounddb[706][0] ftgen 0,0,0,1,"sounds/MusicBox/92.2.mp3",0,0,0
+gisounddb[707][0] ftgen 0,0,0,1,"sounds/MusicBox/89.2.mp3",0,0,0
+gisounddb[708][0] ftgen 0,0,0,1,"sounds/MusicBox/82.1.mp3",0,0,0
+gisounddb[709][0] ftgen 0,0,0,1,"sounds/MusicBox/84.2.mp3",0,0,0
+gisounddb[710][0] ftgen 0,0,0,1,"sounds/MusicBox/72.0.mp3",0,0,0
+gisounddb[711][0] ftgen 0,0,0,1,"sounds/MusicBox/82.0.mp3",0,0,0
+gisounddb[712][0] ftgen 0,0,0,1,"sounds/MusicBox/72.2.mp3",0,0,0
+gisounddb[713][0] ftgen 0,0,0,1,"sounds/MusicBox/87.3.mp3",0,0,0
+gisounddb[714][0] ftgen 0,0,0,1,"sounds/MusicBox/70.3.mp3",0,0,0
+gisounddb[715][0] ftgen 0,0,0,1,"sounds/MusicBox/73.2.mp3",0,0,0
+gisounddb[716][0] ftgen 0,0,0,1,"sounds/MusicBox/87.1.mp3",0,0,0
+gisounddb[717][0] ftgen 0,0,0,1,"sounds/MusicBox/77.2.mp3",0,0,0
+gisounddb[718][0] ftgen 0,0,0,1,"sounds/MusicBox/77.1.mp3",0,0,0
+gisounddb[719][0] ftgen 0,0,0,1,"sounds/MusicBox/72.1.mp3",0,0,0
+gisounddb[720][0] ftgen 0,0,0,1,"sounds/MusicBox/87.2.mp3",0,0,0
+gisounddb[721][0] ftgen 0,0,0,1,"sounds/MusicBox/91.1.mp3",0,0,0
+gisounddb[722][0] ftgen 0,0,0,1,"sounds/MusicBox/87.0.mp3",0,0,0
+gisounddb[723][0] ftgen 0,0,0,1,"sounds/MusicBox/70.0.mp3",0,0,0
+gisounddb[724][0] ftgen 0,0,0,1,"sounds/MusicBox/70.2.mp3",0,0,0
+gisounddb[725][0] ftgen 0,0,0,1,"sounds/MusicBox/89.0.mp3",0,0,0
+gisounddb[726][0] ftgen 0,0,0,1,"sounds/MusicBox/85.2.mp3",0,0,0
+gisounddb[727][0] ftgen 0,0,0,1,"sounds/MusicBox/79.3.mp3",0,0,0
+gisounddb[728][0] ftgen 0,0,0,1,"sounds/MusicBox/89.1.mp3",0,0,0
+gisounddb[729][0] ftgen 0,0,0,1,"sounds/MusicBox/80.2.mp3",0,0,0
+gisounddb[730][0] ftgen 0,0,0,1,"sounds/MusicBox/84.1.mp3",0,0,0
+gisounddb[731][0] ftgen 0,0,0,1,"sounds/MusicBox/68.4.mp3",0,0,0
+gisounddb[732][0] ftgen 0,0,0,1,"sounds/MusicBox/80.0.mp3",0,0,0
+gisounddb[733][0] ftgen 0,0,0,1,"sounds/MusicBox/84.0.mp3",0,0,0
+gisounddb[734][0] ftgen 0,0,0,1,"sounds/MusicBox/75.0.mp3",0,0,0
+gisounddb[735][0] ftgen 0,0,0,1,"sounds/MusicBox/79.2.mp3",0,0,0
+gisounddb[736][0] ftgen 0,0,0,1,"sounds/MusicBox/68.5.mp3",0,0,0
+gisounddb[737][0] ftgen 0,0,0,1,"sounds/MusicBox/84.3.mp3",0,0,0
+gisounddb[738][0] ftgen 0,0,0,1,"sounds/Kalimba/65.1.mp3",0,0,0
+gisounddb[739][0] ftgen 0,0,0,1,"sounds/Kalimba/77.0.mp3",0,0,0
+gisounddb[740][0] ftgen 0,0,0,1,"sounds/Kalimba/76.3.mp3",0,0,0
+gisounddb[741][0] ftgen 0,0,0,1,"sounds/Kalimba/69.3.mp3",0,0,0
+gisounddb[742][0] ftgen 0,0,0,1,"sounds/Kalimba/64.0.mp3",0,0,0
+gisounddb[743][0] ftgen 0,0,0,1,"sounds/Kalimba/60.2.mp3",0,0,0
+gisounddb[744][0] ftgen 0,0,0,1,"sounds/Kalimba/69.0.mp3",0,0,0
+gisounddb[745][0] ftgen 0,0,0,1,"sounds/Kalimba/67.0.mp3",0,0,0
+gisounddb[746][0] ftgen 0,0,0,1,"sounds/Kalimba/62.3.mp3",0,0,0
+gisounddb[747][0] ftgen 0,0,0,1,"sounds/Kalimba/65.3.mp3",0,0,0
+gisounddb[748][0] ftgen 0,0,0,1,"sounds/Kalimba/62.2.mp3",0,0,0
+gisounddb[749][0] ftgen 0,0,0,1,"sounds/Kalimba/67.4.mp3",0,0,0
+gisounddb[750][0] ftgen 0,0,0,1,"sounds/Kalimba/69.2.mp3",0,0,0
+gisounddb[751][0] ftgen 0,0,0,1,"sounds/Kalimba/74.2.mp3",0,0,0
+gisounddb[752][0] ftgen 0,0,0,1,"sounds/Kalimba/77.3.mp3",0,0,0
+gisounddb[753][0] ftgen 0,0,0,1,"sounds/Kalimba/88.1.mp3",0,0,0
+gisounddb[754][0] ftgen 0,0,0,1,"sounds/Kalimba/65.0.mp3",0,0,0
+gisounddb[755][0] ftgen 0,0,0,1,"sounds/Kalimba/86.1.mp3",0,0,0
+gisounddb[756][0] ftgen 0,0,0,1,"sounds/Kalimba/69.1.mp3",0,0,0
+gisounddb[757][0] ftgen 0,0,0,1,"sounds/Kalimba/71.1.mp3",0,0,0
+gisounddb[758][0] ftgen 0,0,0,1,"sounds/Kalimba/79.1.mp3",0,0,0
+gisounddb[759][0] ftgen 0,0,0,1,"sounds/Kalimba/64.2.mp3",0,0,0
+gisounddb[760][0] ftgen 0,0,0,1,"sounds/Kalimba/83.4.mp3",0,0,0
+gisounddb[761][0] ftgen 0,0,0,1,"sounds/Kalimba/74.1.mp3",0,0,0
+gisounddb[762][0] ftgen 0,0,0,1,"sounds/Kalimba/83.3.mp3",0,0,0
+gisounddb[763][0] ftgen 0,0,0,1,"sounds/Kalimba/83.0.mp3",0,0,0
+gisounddb[764][0] ftgen 0,0,0,1,"sounds/Kalimba/86.3.mp3",0,0,0
+gisounddb[765][0] ftgen 0,0,0,1,"sounds/Kalimba/67.2.mp3",0,0,0
+gisounddb[766][0] ftgen 0,0,0,1,"sounds/Kalimba/71.2.mp3",0,0,0
+gisounddb[767][0] ftgen 0,0,0,1,"sounds/Kalimba/81.1.mp3",0,0,0
+gisounddb[768][0] ftgen 0,0,0,1,"sounds/Kalimba/72.3.mp3",0,0,0
+gisounddb[769][0] ftgen 0,0,0,1,"sounds/Kalimba/81.2.mp3",0,0,0
+gisounddb[770][0] ftgen 0,0,0,1,"sounds/Kalimba/79.0.mp3",0,0,0
+gisounddb[771][0] ftgen 0,0,0,1,"sounds/Kalimba/69.4.mp3",0,0,0
+gisounddb[772][0] ftgen 0,0,0,1,"sounds/Kalimba/60.1.mp3",0,0,0
+gisounddb[773][0] ftgen 0,0,0,1,"sounds/Kalimba/71.4.mp3",0,0,0
+gisounddb[774][0] ftgen 0,0,0,1,"sounds/Kalimba/62.0.mp3",0,0,0
+gisounddb[775][0] ftgen 0,0,0,1,"sounds/Kalimba/81.3.mp3",0,0,0
+gisounddb[776][0] ftgen 0,0,0,1,"sounds/Kalimba/81.4.mp3",0,0,0
+gisounddb[777][0] ftgen 0,0,0,1,"sounds/Kalimba/60.0.mp3",0,0,0
+gisounddb[778][0] ftgen 0,0,0,1,"sounds/Kalimba/65.2.mp3",0,0,0
+gisounddb[779][0] ftgen 0,0,0,1,"sounds/Kalimba/84.2.mp3",0,0,0
+gisounddb[780][0] ftgen 0,0,0,1,"sounds/Kalimba/72.0.mp3",0,0,0
+gisounddb[781][0] ftgen 0,0,0,1,"sounds/Kalimba/65.4.mp3",0,0,0
+gisounddb[782][0] ftgen 0,0,0,1,"sounds/Kalimba/71.3.mp3",0,0,0
+gisounddb[783][0] ftgen 0,0,0,1,"sounds/Kalimba/86.0.mp3",0,0,0
+gisounddb[784][0] ftgen 0,0,0,1,"sounds/Kalimba/72.2.mp3",0,0,0
+gisounddb[785][0] ftgen 0,0,0,1,"sounds/Kalimba/83.1.mp3",0,0,0
+gisounddb[786][0] ftgen 0,0,0,1,"sounds/Kalimba/60.3.mp3",0,0,0
+gisounddb[787][0] ftgen 0,0,0,1,"sounds/Kalimba/74.0.mp3",0,0,0
+gisounddb[788][0] ftgen 0,0,0,1,"sounds/Kalimba/77.2.mp3",0,0,0
+gisounddb[789][0] ftgen 0,0,0,1,"sounds/Kalimba/76.2.mp3",0,0,0
+gisounddb[790][0] ftgen 0,0,0,1,"sounds/Kalimba/77.1.mp3",0,0,0
+gisounddb[791][0] ftgen 0,0,0,1,"sounds/Kalimba/72.1.mp3",0,0,0
+gisounddb[792][0] ftgen 0,0,0,1,"sounds/Kalimba/88.0.mp3",0,0,0
+gisounddb[793][0] ftgen 0,0,0,1,"sounds/Kalimba/67.3.mp3",0,0,0
+gisounddb[794][0] ftgen 0,0,0,1,"sounds/Kalimba/81.0.mp3",0,0,0
+gisounddb[795][0] ftgen 0,0,0,1,"sounds/Kalimba/77.4.mp3",0,0,0
+gisounddb[796][0] ftgen 0,0,0,1,"sounds/Kalimba/88.2.mp3",0,0,0
+gisounddb[797][0] ftgen 0,0,0,1,"sounds/Kalimba/64.3.mp3",0,0,0
+gisounddb[798][0] ftgen 0,0,0,1,"sounds/Kalimba/76.1.mp3",0,0,0
+gisounddb[799][0] ftgen 0,0,0,1,"sounds/Kalimba/79.3.mp3",0,0,0
+gisounddb[800][0] ftgen 0,0,0,1,"sounds/Kalimba/83.2.mp3",0,0,0
+gisounddb[801][0] ftgen 0,0,0,1,"sounds/Kalimba/74.3.mp3",0,0,0
+gisounddb[802][0] ftgen 0,0,0,1,"sounds/Kalimba/76.0.mp3",0,0,0
+gisounddb[803][0] ftgen 0,0,0,1,"sounds/Kalimba/64.1.mp3",0,0,0
+gisounddb[804][0] ftgen 0,0,0,1,"sounds/Kalimba/84.1.mp3",0,0,0
+gisounddb[805][0] ftgen 0,0,0,1,"sounds/Kalimba/71.0.mp3",0,0,0
+gisounddb[806][0] ftgen 0,0,0,1,"sounds/Kalimba/62.1.mp3",0,0,0
+gisounddb[807][0] ftgen 0,0,0,1,"sounds/Kalimba/84.0.mp3",0,0,0
+gisounddb[808][0] ftgen 0,0,0,1,"sounds/Kalimba/67.1.mp3",0,0,0
+gisounddb[809][0] ftgen 0,0,0,1,"sounds/Kalimba/86.2.mp3",0,0,0
+gisounddb[810][0] ftgen 0,0,0,1,"sounds/Kalimba/79.2.mp3",0,0,0
+gisounddb[811][0] ftgen 0,0,0,1,"sounds/Kalimba/84.3.mp3",0,0,0
+index = 0 ; all sounds have the same number of channels
+while (index < 812) do
+ gisounddb[index][1] = 2
+ index += 1
+od
+index = 0
+while (index < 812) do
+ gisounddb[index][2] = ftlen(gisounddb[index][0]) / ftsr(gisounddb[index][0]) / ftchnls(gisounddb[index][0])
+ index += 1
+od
+gisounddb[0][3] = 0.00598323530261935
+gisounddb[1][3] = 0.002668039965544519
+gisounddb[2][3] = 0.002173936874994305
+gisounddb[3][3] = 0.004979451786363545
+gisounddb[4][3] = 0.0024711239889592027
+gisounddb[5][3] = 0.009364649467778248
+gisounddb[6][3] = 0.009321679101233231
+gisounddb[7][3] = 0.006833442669832136
+gisounddb[8][3] = 0.015333609384416738
+gisounddb[9][3] = 0.005833896088676241
+gisounddb[10][3] = 0.017964238393301628
+gisounddb[11][3] = 0.009157451122239924
+gisounddb[12][3] = 0.003487192404087312
+gisounddb[13][3] = 0.004809457393541127
+gisounddb[14][3] = 0.005094952285650194
+gisounddb[15][3] = 0.00508577733755102
+gisounddb[16][3] = 0.0076238339167297295
+gisounddb[17][3] = 0.01795838089707388
+gisounddb[18][3] = 0.011135254736008671
+gisounddb[19][3] = 0.013576740239896034
+gisounddb[20][3] = 0.012882775747587725
+gisounddb[21][3] = 0.0059420121787073146
+gisounddb[22][3] = 0.007522192374105889
+gisounddb[23][3] = 0.0057865114329241135
+gisounddb[24][3] = 0.004896228772449702
+gisounddb[25][3] = 0.009454675438874686
+gisounddb[26][3] = 0.009391380868927095
+gisounddb[27][3] = 0.0053192959305936455
+gisounddb[28][3] = 0.006795043100277803
+gisounddb[29][3] = 0.013220310439872141
+gisounddb[30][3] = 0.00953121223501827
+gisounddb[31][3] = 0.006500520467185666
+gisounddb[32][3] = 0.004149973682657126
+gisounddb[33][3] = 0.002678230289960877
+gisounddb[34][3] = 0.005247265788906494
+gisounddb[35][3] = 0.010188623179907971
+gisounddb[36][3] = 0.009178286541640475
+gisounddb[37][3] = 0.016318420501179293
+gisounddb[38][3] = 0.01256879675958142
+gisounddb[39][3] = 0.007123462497019896
+gisounddb[40][3] = 0.005673329365537944
+gisounddb[41][3] = 0.0020958309921066216
+gisounddb[42][3] = 0.022489096500953727
+gisounddb[43][3] = 0.0037841338521460307
+gisounddb[44][3] = 0.0024439839998671806
+gisounddb[45][3] = 0.0026509068532208995
+gisounddb[46][3] = 0.0056085710629587586
+gisounddb[47][3] = 0.0069071251232015775
+gisounddb[48][3] = 0.004785694508877388
+gisounddb[49][3] = 0.004233489507239822
+gisounddb[50][3] = 0.002683329621433783
+gisounddb[51][3] = 0.007827804609944575
+gisounddb[52][3] = 0.025816241592159405
+gisounddb[53][3] = 0.0029683546694794652
+gisounddb[54][3] = 0.008134088418116862
+gisounddb[55][3] = 0.010265294033948137
+gisounddb[56][3] = 0.005998868121066853
+gisounddb[57][3] = 0.0032324407079317823
+gisounddb[58][3] = 0.007746463537985637
+gisounddb[59][3] = 0.017130889608365868
+gisounddb[60][3] = 0.004040417913444802
+gisounddb[61][3] = 0.0034585825888229426
+gisounddb[62][3] = 0.0027885762951951657
+gisounddb[63][3] = 0.007412193059269223
+gisounddb[64][3] = 0.004817398559993996
+gisounddb[65][3] = 0.005078303449460165
+gisounddb[66][3] = 0.007898223491171356
+gisounddb[67][3] = 0.005787946301415294
+gisounddb[68][3] = 0.01643200923223261
+gisounddb[69][3] = 0.036636702264993354
+gisounddb[70][3] = 0.006636171664319744
+gisounddb[71][3] = 0.0025224906132375936
+gisounddb[72][3] = 0.0011023408292128146
+gisounddb[73][3] = 0.006070147153677933
+gisounddb[74][3] = 0.010358607309924907
+gisounddb[75][3] = 0.008521140505417229
+gisounddb[76][3] = 0.0021127328705942685
+gisounddb[77][3] = 0.003421763170599867
+gisounddb[78][3] = 0.007083046927614073
+gisounddb[79][3] = 0.002761877927451458
+gisounddb[80][3] = 0.002018563452141591
+gisounddb[81][3] = 0.0012938541603163892
+gisounddb[82][3] = 0.0037284122705047097
+gisounddb[83][3] = 0.010411801355004092
+gisounddb[84][3] = 0.01822565129163906
+gisounddb[85][3] = 0.0025984440330321695
+gisounddb[86][3] = 0.0005658286192922751
+gisounddb[87][3] = 0.0023197301292877176
+gisounddb[88][3] = 0.03358426681947521
+gisounddb[89][3] = 0.002844062794448459
+gisounddb[90][3] = 0.004159188078414864
+gisounddb[91][3] = 0.003189797468311443
+gisounddb[92][3] = 0.014815426224370916
+gisounddb[93][3] = 0.060412271756305744
+gisounddb[94][3] = 0.0018136686253645334
+gisounddb[95][3] = 0.007232254007936627
+gisounddb[96][3] = 0.0030909474087781794
+gisounddb[97][3] = 0.002861206811002901
+gisounddb[98][3] = 0.005708800828403748
+gisounddb[99][3] = 0.022035508721450096
+gisounddb[100][3] = 0.001829398138682419
+gisounddb[101][3] = 0.002445558057657685
+gisounddb[102][3] = 0.024251463943510375
+gisounddb[103][3] = 0.022715191237082214
+gisounddb[104][3] = 0.0068938200373220215
+gisounddb[105][3] = 0.010789944685722424
+gisounddb[106][3] = 0.006940406118522731
+gisounddb[107][3] = 0.006150041170064181
+gisounddb[108][3] = 0.002285473205307945
+gisounddb[109][3] = 0.003735154612992439
+gisounddb[110][3] = 0.0043190643071719555
+gisounddb[111][3] = 0.0020476086348571844
+gisounddb[112][3] = 0.004792845760020963
+gisounddb[113][3] = 0.02182145995325383
+gisounddb[114][3] = 0.009611357048713437
+gisounddb[115][3] = 0.008545568548161145
+gisounddb[116][3] = 0.001688605436359166
+gisounddb[117][3] = 0.01207249390081909
+gisounddb[118][3] = 0.06865753283265262
+gisounddb[119][3] = 0.0076430362672082666
+gisounddb[120][3] = 0.0050430122271156045
+gisounddb[121][3] = 0.019320634908080756
+gisounddb[122][3] = 0.006495820743701141
+gisounddb[123][3] = 0.0014797799550832454
+gisounddb[124][3] = 0.0028317942519223882
+gisounddb[125][3] = 0.003729956822729459
+gisounddb[126][3] = 0.0007509131045442697
+gisounddb[127][3] = 0.008503605860829202
+gisounddb[128][3] = 0.002183058745146387
+gisounddb[129][3] = 0.003327499302265506
+gisounddb[130][3] = 0.005691225132593801
+gisounddb[131][3] = 0.00487905172249012
+gisounddb[132][3] = 0.005345055572348599
+gisounddb[133][3] = 0.004411896193429177
+gisounddb[134][3] = 0.001849016293139234
+gisounddb[135][3] = 0.004640987027332499
+gisounddb[136][3] = 0.008200827442153698
+gisounddb[137][3] = 0.055251142800202185
+gisounddb[138][3] = 0.00990767182421253
+gisounddb[139][3] = 0.007142321684940194
+gisounddb[140][3] = 0.00594675295341376
+gisounddb[141][3] = 0.002062395894346932
+gisounddb[142][3] = 0.0020219500175936754
+gisounddb[143][3] = 0.0009920348328842647
+gisounddb[144][3] = 0.005059905767073799
+gisounddb[145][3] = 0.010656614165477526
+gisounddb[146][3] = 0.013639574266447707
+gisounddb[147][3] = 0.015841542567489347
+gisounddb[148][3] = 0.0062590866854165435
+gisounddb[149][3] = 0.0014979876152118943
+gisounddb[150][3] = 0.01669125154721101
+gisounddb[151][3] = 0.0047706700823672505
+gisounddb[152][3] = 0.004543058054591071
+gisounddb[153][3] = 0.004105231057890772
+gisounddb[154][3] = 0.012519922714184
+gisounddb[155][3] = 0.014255669722176052
+gisounddb[156][3] = 0.0027281806470830197
+gisounddb[157][3] = 0.00812709944758494
+gisounddb[158][3] = 0.004432300895712237
+gisounddb[159][3] = 0.009049263833995833
+gisounddb[160][3] = 0.0021287096533816894
+gisounddb[161][3] = 0.008486910842014512
+gisounddb[162][3] = 0.004335152216899965
+gisounddb[163][3] = 0.03757968731802192
+gisounddb[164][3] = 0.008640543757200343
+gisounddb[165][3] = 0.001468612258801247
+gisounddb[166][3] = 0.004621122084475156
+gisounddb[167][3] = 0.00904345829322083
+gisounddb[168][3] = 0.0021288069896774143
+gisounddb[169][3] = 0.010980844413307727
+gisounddb[170][3] = 0.0021535108453186063
+gisounddb[171][3] = 0.0022694593802069945
+gisounddb[172][3] = 0.0043021781436052
+gisounddb[173][3] = 0.007761898797427649
+gisounddb[174][3] = 0.03870314380541736
+gisounddb[175][3] = 0.0031233483685294172
+gisounddb[176][3] = 0.014566904692567125
+gisounddb[177][3] = 0.006603534660042465
+gisounddb[178][3] = 0.07015759066424301
+gisounddb[179][3] = 0.008233846094509768
+gisounddb[180][3] = 0.009177647681999341
+gisounddb[181][3] = 0.010457597200182838
+gisounddb[182][3] = 0.003428084417350242
+gisounddb[183][3] = 0.0067197243708596345
+gisounddb[184][3] = 0.005760114855804054
+gisounddb[185][3] = 0.014005636992265322
+gisounddb[186][3] = 0.001835219554734648
+gisounddb[187][3] = 0.004886499632854604
+gisounddb[188][3] = 0.02613489143950982
+gisounddb[189][3] = 0.0052344488277125826
+gisounddb[190][3] = 0.0029899306144379376
+gisounddb[191][3] = 0.004363238629084851
+gisounddb[192][3] = 0.001205490924064056
+gisounddb[193][3] = 0.008139938217240496
+gisounddb[194][3] = 0.0032541442965334125
+gisounddb[195][3] = 0.0023018805448565215
+gisounddb[196][3] = 0.009094167456523155
+gisounddb[197][3] = 0.005888462142563041
+gisounddb[198][3] = 0.003414062217937766
+gisounddb[199][3] = 0.003807303739080625
+gisounddb[200][3] = 0.002874875585051657
+gisounddb[201][3] = 0.019421626045407297
+gisounddb[202][3] = 0.015239848393550899
+gisounddb[203][3] = 0.03647973522087719
+gisounddb[204][3] = 0.002693713656303577
+gisounddb[205][3] = 0.0031989595879037677
+gisounddb[206][3] = 0.01860048486759007
+gisounddb[207][3] = 0.0033399371810819973
+gisounddb[208][3] = 0.016025688086218084
+gisounddb[209][3] = 0.015647778234324426
+gisounddb[210][3] = 0.00690289107451571
+gisounddb[211][3] = 0.007314035097680522
+gisounddb[212][3] = 0.0039641280660580825
+gisounddb[213][3] = 0.0036621402041172152
+gisounddb[214][3] = 0.0054182800480234924
+gisounddb[215][3] = 0.0004398412566356115
+gisounddb[216][3] = 0.010367436529764473
+gisounddb[217][3] = 0.010765564108453855
+gisounddb[218][3] = 0.020334198557246386
+gisounddb[219][3] = 0.002405251851272759
+gisounddb[220][3] = 0.0018626969335568267
+gisounddb[221][3] = 0.003523188873595955
+gisounddb[222][3] = 0.013492574972154052
+gisounddb[223][3] = 0.006908910851355109
+gisounddb[224][3] = 0.0035275826371921064
+gisounddb[225][3] = 0.003300785861026249
+gisounddb[226][3] = 0.011075041573406467
+gisounddb[227][3] = 0.009027768387917844
+gisounddb[228][3] = 0.003675884666356387
+gisounddb[229][3] = 0.002995311210923531
+gisounddb[230][3] = 0.004821918042957278
+gisounddb[231][3] = 0.0018752836230527792
+gisounddb[232][3] = 0.004263890823485804
+gisounddb[233][3] = 0.03104358103781758
+gisounddb[234][3] = 0.0032117672484302125
+gisounddb[235][3] = 0.008217639200380723
+gisounddb[236][3] = 0.010935634189466687
+gisounddb[237][3] = 0.006651324055185712
+gisounddb[238][3] = 0.007068938777205702
+gisounddb[239][3] = 0.0093076017392413
+gisounddb[240][3] = 0.02833390790112526
+gisounddb[241][3] = 0.0054978289775754734
+gisounddb[242][3] = 0.006768304002024846
+gisounddb[243][3] = 0.015032290849820773
+gisounddb[244][3] = 0.010219539239991313
+gisounddb[245][3] = 0.003549077762557423
+gisounddb[246][3] = 0.012373385246136947
+gisounddb[247][3] = 0.005959889985853581
+gisounddb[248][3] = 0.0029277652738058236
+gisounddb[249][3] = 0.007435241396101413
+gisounddb[250][3] = 0.007937041270049003
+gisounddb[251][3] = 0.013611373359839184
+gisounddb[252][3] = 0.018132109668240356
+gisounddb[253][3] = 0.012796578444360692
+gisounddb[254][3] = 0.024961780933500474
+gisounddb[255][3] = 0.020685343012448048
+gisounddb[256][3] = 0.0035283148242205744
+gisounddb[257][3] = 0.018899018333348883
+gisounddb[258][3] = 0.004592166861663849
+gisounddb[259][3] = 0.003577863328365638
+gisounddb[260][3] = 0.012466449649080825
+gisounddb[261][3] = 0.0028711123425671876
+gisounddb[262][3] = 0.0037543733198172097
+gisounddb[263][3] = 0.00427072456908484
+gisounddb[264][3] = 0.040643440072283196
+gisounddb[265][3] = 0.005583470806455899
+gisounddb[266][3] = 0.01176382463179803
+gisounddb[267][3] = 0.01412098836015984
+gisounddb[268][3] = 0.0038268139737235637
+gisounddb[269][3] = 0.018618655164692518
+gisounddb[270][3] = 0.0025800729697975176
+gisounddb[271][3] = 0.007753463412748381
+gisounddb[272][3] = 0.005236807990122312
+gisounddb[273][3] = 0.0033866813736296345
+gisounddb[274][3] = 0.017261859683350353
+gisounddb[275][3] = 0.004702330060675523
+gisounddb[276][3] = 0.004178873742888978
+gisounddb[277][3] = 0.005075176180202787
+gisounddb[278][3] = 0.013353241993554003
+gisounddb[279][3] = 0.005479373246195612
+gisounddb[280][3] = 0.012608063536198819
+gisounddb[281][3] = 0.0023066671814749562
+gisounddb[282][3] = 0.0021409127705228244
+gisounddb[283][3] = 0.007006677543484883
+gisounddb[284][3] = 0.010786446351904408
+gisounddb[285][3] = 0.007190692852869092
+gisounddb[286][3] = 0.02107453810181772
+gisounddb[287][3] = 0.020833516115118487
+gisounddb[288][3] = 0.009604049931211634
+gisounddb[289][3] = 0.0031194462574582952
+gisounddb[290][3] = 0.008116574940565136
+gisounddb[291][3] = 0.007568055568945597
+gisounddb[292][3] = 0.0005121098081047548
+gisounddb[293][3] = 0.002561685550216632
+gisounddb[294][3] = 0.00810219161868483
+gisounddb[295][3] = 0.005872674099182651
+gisounddb[296][3] = 0.0026863253984959466
+gisounddb[297][3] = 0.010497723486759192
+gisounddb[298][3] = 0.0036628258878083518
+gisounddb[299][3] = 0.006565065175125798
+gisounddb[300][3] = 0.0034246710723901085
+gisounddb[301][3] = 0.019133179634584697
+gisounddb[302][3] = 0.002532044323001517
+gisounddb[303][3] = 0.0019817469203325566
+gisounddb[304][3] = 0.006583980167050893
+gisounddb[305][3] = 0.0023637670258209818
+gisounddb[306][3] = 0.009728104799578585
+gisounddb[307][3] = 0.03234819400184569
+gisounddb[308][3] = 0.0016695929477820103
+gisounddb[309][3] = 0.003318203445489269
+gisounddb[310][3] = 0.005799540705906394
+gisounddb[311][3] = 0.017532512955171893
+gisounddb[312][3] = 0.013752066160165343
+gisounddb[313][3] = 0.028673388677898832
+gisounddb[314][3] = 0.0028470774935582268
+gisounddb[315][3] = 0.007050363740712134
+gisounddb[316][3] = 0.051732580992585146
+gisounddb[317][3] = 0.009643771478396868
+gisounddb[318][3] = 0.019006285176226483
+gisounddb[319][3] = 0.009240375873369502
+gisounddb[320][3] = 0.056446985420349864
+gisounddb[321][3] = 0.009618616059314553
+gisounddb[322][3] = 0.006633230087699021
+gisounddb[323][3] = 0.0028466583220969005
+gisounddb[324][3] = 0.0036788804434185513
+gisounddb[325][3] = 0.003001741820694803
+gisounddb[326][3] = 0.0030197588171403927
+gisounddb[327][3] = 0.013211343313583937
+gisounddb[328][3] = 0.00350223992190978
+gisounddb[329][3] = 0.006774591894657411
+gisounddb[330][3] = 0.013476248131485959
+gisounddb[331][3] = 0.025371418248535744
+gisounddb[332][3] = 0.006876738239025802
+gisounddb[333][3] = 0.0025183810010681717
+gisounddb[334][3] = 0.01802354971187227
+gisounddb[335][3] = 0.01318169919995478
+gisounddb[336][3] = 0.014386326781593396
+gisounddb[337][3] = 0.015376011448108295
+gisounddb[338][3] = 0.0129103134203921
+gisounddb[339][3] = 0.0038409763245733767
+gisounddb[340][3] = 0.00416009377099848
+gisounddb[341][3] = 0.020399226258469426
+gisounddb[342][3] = 0.005318694273622377
+gisounddb[343][3] = 0.0014209926810174278
+gisounddb[344][3] = 0.0008714511981146084
+gisounddb[345][3] = 0.003569236157508962
+gisounddb[346][3] = 0.002780360598695706
+gisounddb[347][3] = 0.00539387573801725
+gisounddb[348][3] = 0.0058988064090616
+gisounddb[349][3] = 0.023196768252831342
+gisounddb[350][3] = 0.007481174506303454
+gisounddb[351][3] = 0.0128427238663511
+gisounddb[352][3] = 0.014979669597572444
+gisounddb[353][3] = 0.0021213565136115613
+gisounddb[354][3] = 0.007271928731071858
+gisounddb[355][3] = 0.0067891477599548505
+gisounddb[356][3] = 0.012424727496252322
+gisounddb[357][3] = 0.004198288725868555
+gisounddb[358][3] = 0.005424932911675943
+gisounddb[359][3] = 0.010588874517906383
+gisounddb[360][3] = 0.006609011791042105
+gisounddb[361][3] = 0.00147036783996368
+gisounddb[362][3] = 0.0020706279471926258
+gisounddb[363][3] = 0.004604459778352934
+gisounddb[364][3] = 0.006390763611128467
+gisounddb[365][3] = 0.012571639556699397
+gisounddb[366][3] = 0.006449504061144282
+gisounddb[367][3] = 0.00548617941050492
+gisounddb[368][3] = 0.002598383418337303
+gisounddb[369][3] = 0.004099486452523307
+gisounddb[370][3] = 0.0024031462122296545
+gisounddb[371][3] = 0.002843508282239864
+gisounddb[372][3] = 0.011453272137971381
+gisounddb[373][3] = 0.003792922662189018
+gisounddb[374][3] = 0.004548737555286271
+gisounddb[375][3] = 0.009596472773640636
+gisounddb[376][3] = 0.007135573248911711
+gisounddb[377][3] = 0.0041255882946984864
+gisounddb[378][3] = 0.00571616118420898
+gisounddb[379][3] = 0.015886691214497508
+gisounddb[380][3] = 0.013020528254143845
+gisounddb[381][3] = 0.008017182235192115
+gisounddb[382][3] = 0.010032067930861694
+gisounddb[383][3] = 0.010501783067751898
+gisounddb[384][3] = 0.007988075635999976
+gisounddb[385][3] = 0.006065906049313298
+gisounddb[386][3] = 0.007838404805154792
+gisounddb[387][3] = 0.017819715000830034
+gisounddb[388][3] = 0.00442328149325862
+gisounddb[389][3] = 0.004886868131713872
+gisounddb[390][3] = 0.0023208152606108987
+gisounddb[391][3] = 0.005892675665637948
+gisounddb[392][3] = 0.003377402193912303
+gisounddb[393][3] = 0.006692232239254578
+gisounddb[394][3] = 0.0026917255584544865
+gisounddb[395][3] = 0.004844880749506244
+gisounddb[396][3] = 0.002552927528590085
+gisounddb[397][3] = 0.007992124954187203
+gisounddb[398][3] = 0.00508833662466761
+gisounddb[399][3] = 0.004024878101671962
+gisounddb[400][3] = 0.0385520547831399
+gisounddb[401][3] = 0.017086255384482395
+gisounddb[402][3] = 0.053611013068017174
+gisounddb[403][3] = 0.016325527493974236
+gisounddb[404][3] = 0.03348698568632971
+gisounddb[405][3] = 0.002409953819745983
+gisounddb[406][3] = 0.005164425705922126
+gisounddb[407][3] = 0.02461365117740858
+gisounddb[408][3] = 0.008361035608525535
+gisounddb[409][3] = 0.017713052380625077
+gisounddb[410][3] = 0.004144171028296165
+gisounddb[411][3] = 0.005111903874601885
+gisounddb[412][3] = 0.009511596165193818
+gisounddb[413][3] = 0.0025831992769168814
+gisounddb[414][3] = 0.002224326127407056
+gisounddb[415][3] = 0.002675210138735698
+gisounddb[416][3] = 0.0016762130987419922
+gisounddb[417][3] = 0.008457330229494263
+gisounddb[418][3] = 0.002201946155781755
+gisounddb[419][3] = 0.00187215458987571
+gisounddb[420][3] = 0.0019396775960374227
+gisounddb[421][3] = 0.005426155468378754
+gisounddb[422][3] = 0.004700934319130235
+gisounddb[423][3] = 0.0041384071801684255
+gisounddb[424][3] = 0.0033296339658053582
+gisounddb[425][3] = 0.0019851753387882393
+gisounddb[426][3] = 0.0016627317812495826
+gisounddb[427][3] = 0.0087069344872762
+gisounddb[428][3] = 0.016531749590141268
+gisounddb[429][3] = 0.005074914799375717
+gisounddb[430][3] = 0.002096750796047772
+gisounddb[431][3] = 0.010237075167430025
+gisounddb[432][3] = 0.002065928704777107
+gisounddb[433][3] = 0.006160447013395621
+gisounddb[434][3] = 0.0016557949265267394
+gisounddb[435][3] = 0.009734069413838527
+gisounddb[436][3] = 0.006500719309041842
+gisounddb[437][3] = 0.010488145723544924
+gisounddb[438][3] = 0.007698275817704695
+gisounddb[439][3] = 0.003143711378165215
+gisounddb[440][3] = 0.013929150868723797
+gisounddb[441][3] = 0.014859456225581748
+gisounddb[442][3] = 0.004306934633232537
+gisounddb[443][3] = 0.0054874603369139
+gisounddb[444][3] = 0.00843463660087648
+gisounddb[445][3] = 0.0026368872195097937
+gisounddb[446][3] = 0.008704988402787044
+gisounddb[447][3] = 0.0012804751501661088
+gisounddb[448][3] = 0.004627720106260821
+gisounddb[449][3] = 0.005485498216791181
+gisounddb[450][3] = 0.003980251574892601
+gisounddb[451][3] = 0.002028074346763902
+gisounddb[452][3] = 0.02010556505961227
+gisounddb[453][3] = 0.020058852617619086
+gisounddb[454][3] = 0.006169714326744116
+gisounddb[455][3] = 0.03047828005496211
+gisounddb[456][3] = 0.004411583498574707
+gisounddb[457][3] = 0.002958578705834365
+gisounddb[458][3] = 0.0025221060787447625
+gisounddb[459][3] = 0.007494995298158384
+gisounddb[460][3] = 0.014109860913318084
+gisounddb[461][3] = 0.013208432525379654
+gisounddb[462][3] = 0.011374579511251643
+gisounddb[463][3] = 0.011209191835239087
+gisounddb[464][3] = 0.020920871832514083
+gisounddb[465][3] = 0.02606082477236022
+gisounddb[466][3] = 0.0037007075063986137
+gisounddb[467][3] = 0.004220744385684271
+gisounddb[468][3] = 0.0053281950657955435
+gisounddb[469][3] = 0.04828994855131234
+gisounddb[470][3] = 0.010932876060493922
+gisounddb[471][3] = 0.005444123075072972
+gisounddb[472][3] = 0.006645652572307293
+gisounddb[473][3] = 0.020100237380717433
+gisounddb[474][3] = 0.006154774889091859
+gisounddb[475][3] = 0.00252522565089803
+gisounddb[476][3] = 0.002180516616157709
+gisounddb[477][3] = 0.000978159519875222
+gisounddb[478][3] = 0.005483244248137622
+gisounddb[479][3] = 0.006046928839129979
+gisounddb[480][3] = 0.007719600644641577
+gisounddb[481][3] = 0.0038352217771131037
+gisounddb[482][3] = 0.010838639132023944
+gisounddb[483][3] = 0.0014292543997852126
+gisounddb[484][3] = 0.0023834578216978355
+gisounddb[485][3] = 0.0029020306476392277
+gisounddb[486][3] = 0.007566214678212611
+gisounddb[487][3] = 0.011485267716906156
+gisounddb[488][3] = 0.005010156817509203
+gisounddb[489][3] = 0.007532703411193499
+gisounddb[490][3] = 0.029085078554030114
+gisounddb[491][3] = 0.005229043536351303
+gisounddb[492][3] = 0.0026878792513881622
+gisounddb[493][3] = 0.004470414710276486
+gisounddb[494][3] = 0.002728485324120709
+gisounddb[495][3] = 0.047558400382485364
+gisounddb[496][3] = 0.013127636023536504
+gisounddb[497][3] = 0.002175270558637706
+gisounddb[498][3] = 0.009358068443764158
+gisounddb[499][3] = 0.027935798282345468
+gisounddb[500][3] = 0.0014998084614029272
+gisounddb[501][3] = 0.01274512458623572
+gisounddb[502][3] = 0.0037240508988883553
+gisounddb[503][3] = 0.007706362908422983
+gisounddb[504][3] = 0.002495825599611696
+gisounddb[505][3] = 0.0012884050916754837
+gisounddb[506][3] = 0.0009039993649819509
+gisounddb[507][3] = 0.018027299484424546
+gisounddb[508][3] = 0.004585175004717885
+gisounddb[509][3] = 0.009187331921820464
+gisounddb[510][3] = 0.002850916424233112
+gisounddb[511][3] = 0.01873196295144582
+gisounddb[512][3] = 0.014346359568501983
+gisounddb[513][3] = 0.00724206909852762
+gisounddb[514][3] = 0.0031037855370083934
+gisounddb[515][3] = 0.0044048966393791045
+gisounddb[516][3] = 0.0027321093773058558
+gisounddb[517][3] = 0.008803712742953176
+gisounddb[518][3] = 0.01785301908746352
+gisounddb[519][3] = 0.005220788392193278
+gisounddb[520][3] = 0.023821939877156115
+gisounddb[521][3] = 0.002426225177121949
+gisounddb[522][3] = 0.005684174585228999
+gisounddb[523][3] = 0.017863805296023064
+gisounddb[524][3] = 0.017518845463973823
+gisounddb[525][3] = 0.0026327468189239313
+gisounddb[526][3] = 0.002973660539912657
+gisounddb[527][3] = 0.029133362488112432
+gisounddb[528][3] = 0.0228036258319039
+gisounddb[529][3] = 0.0025477521882140927
+gisounddb[530][3] = 0.003618172741877277
+gisounddb[531][3] = 0.008884971712468274
+gisounddb[532][3] = 0.00905334137489813
+gisounddb[533][3] = 0.02229323342406813
+gisounddb[534][3] = 0.003207865778784433
+gisounddb[535][3] = 0.0053737869377153726
+gisounddb[536][3] = 0.0043485233695898
+gisounddb[537][3] = 0.0020151857062879657
+gisounddb[538][3] = 0.014415693799474591
+gisounddb[539][3] = 0.013593607160702514
+gisounddb[540][3] = 0.00428564700896552
+gisounddb[541][3] = 0.07444193222836577
+gisounddb[542][3] = 0.005309893276497882
+gisounddb[543][3] = 0.013304580901370293
+gisounddb[544][3] = 0.0246420663200815
+gisounddb[545][3] = 0.012411839978270734
+gisounddb[546][3] = 0.016240216640570543
+gisounddb[547][3] = 0.0031354357083962303
+gisounddb[548][3] = 0.0030009243240957818
+gisounddb[549][3] = 0.04360495219265074
+gisounddb[550][3] = 0.006266343130316289
+gisounddb[551][3] = 0.008591878816464577
+gisounddb[552][3] = 0.023311503852397056
+gisounddb[553][3] = 0.0033413136798670106
+gisounddb[554][3] = 0.002130968913794323
+gisounddb[555][3] = 0.005047489696718953
+gisounddb[556][3] = 0.0013883127012422006
+gisounddb[557][3] = 0.005401203381130013
+gisounddb[558][3] = 0.006114792281792226
+gisounddb[559][3] = 0.0021929160094536506
+gisounddb[560][3] = 0.006439799295712199
+gisounddb[561][3] = 0.004764250376826801
+gisounddb[562][3] = 0.0023070408117369648
+gisounddb[563][3] = 0.0037407462384157156
+gisounddb[564][3] = 0.008090880082769775
+gisounddb[565][3] = 0.00717072848908366
+gisounddb[566][3] = 0.01432081031425937
+gisounddb[567][3] = 0.011269991260604338
+gisounddb[568][3] = 0.0021648406618559224
+gisounddb[569][3] = 0.013401472047907549
+gisounddb[570][3] = 0.002944642136705113
+gisounddb[571][3] = 0.005813598183712707
+gisounddb[572][3] = 0.004342415396765807
+gisounddb[573][3] = 0.008579782175930297
+gisounddb[574][3] = 0.007536321691550563
+gisounddb[575][3] = 0.004566067264477368
+gisounddb[576][3] = 0.006678065077714696
+gisounddb[577][3] = 0.0018568750364355909
+gisounddb[578][3] = 0.004602227297448349
+gisounddb[579][3] = 0.010559684533419718
+gisounddb[580][3] = 0.004875939526728292
+gisounddb[581][3] = 0.003938881885289803
+gisounddb[582][3] = 0.0055741913060258965
+gisounddb[583][3] = 0.003714851897338837
+gisounddb[584][3] = 0.0023386760699855885
+gisounddb[585][3] = 0.002165222470291048
+gisounddb[586][3] = 0.002165614220818982
+gisounddb[587][3] = 0.003510849774282209
+gisounddb[588][3] = 0.007282786779269763
+gisounddb[589][3] = 0.013205898895276765
+gisounddb[590][3] = 0.0023038150836895126
+gisounddb[591][3] = 0.010181684881978107
+gisounddb[592][3] = 0.004929173981604054
+gisounddb[593][3] = 0.004078854044243658
+gisounddb[594][3] = 0.007151159243309211
+gisounddb[595][3] = 0.011949581410987137
+gisounddb[596][3] = 0.006351169066161049
+gisounddb[597][3] = 0.01251749940924002
+gisounddb[598][3] = 0.00761383281278941
+gisounddb[599][3] = 0.004264509157515978
+gisounddb[600][3] = 0.003797649966963271
+gisounddb[601][3] = 0.004168134999804779
+gisounddb[602][3] = 0.008065006908729199
+gisounddb[603][3] = 0.009455214877587732
+gisounddb[604][3] = 0.007611660305154349
+gisounddb[605][3] = 0.002780002041929246
+gisounddb[606][3] = 0.002843419124117256
+gisounddb[607][3] = 0.0041063349509052206
+gisounddb[608][3] = 0.007193552968471317
+gisounddb[609][3] = 0.009638802997693834
+gisounddb[610][3] = 0.0032685471818866647
+gisounddb[611][3] = 0.00701454911528809
+gisounddb[612][3] = 0.012097610834380853
+gisounddb[613][3] = 0.005051856199738048
+gisounddb[614][3] = 0.003766886245398774
+gisounddb[615][3] = 0.009276869126805915
+gisounddb[616][3] = 0.0131746897038119
+gisounddb[617][3] = 0.006388593027769434
+gisounddb[618][3] = 0.0030674359628487017
+gisounddb[619][3] = 0.005317582042078476
+gisounddb[620][3] = 0.009128767863773838
+gisounddb[621][3] = 0.006982837687780044
+gisounddb[622][3] = 0.0023249394652068624
+gisounddb[623][3] = 0.009307089881817983
+gisounddb[624][3] = 0.005945561826552731
+gisounddb[625][3] = 0.0022069528012926684
+gisounddb[626][3] = 0.010962661287698428
+gisounddb[627][3] = 0.004033648310380017
+gisounddb[628][3] = 0.014471408004724472
+gisounddb[629][3] = 0.00437145143917027
+gisounddb[630][3] = 0.008150692354532914
+gisounddb[631][3] = 0.008165334812251592
+gisounddb[632][3] = 0.00310192219638842
+gisounddb[633][3] = 0.013869053162683245
+gisounddb[634][3] = 0.008022631143476684
+gisounddb[635][3] = 0.00908239217008547
+gisounddb[636][3] = 0.011174240568326053
+gisounddb[637][3] = 0.01015837612645686
+gisounddb[638][3] = 0.0030476508774465003
+gisounddb[639][3] = 0.004511649059132015
+gisounddb[640][3] = 0.002087461513881296
+gisounddb[641][3] = 0.014235924084432415
+gisounddb[642][3] = 0.007902871900628482
+gisounddb[643][3] = 0.004844632517898694
+gisounddb[644][3] = 0.0018956746950473113
+gisounddb[645][3] = 0.0023211162494528683
+gisounddb[646][3] = 0.011661410813061815
+gisounddb[647][3] = 0.003870209284557988
+gisounddb[648][3] = 0.008465566772317355
+gisounddb[649][3] = 0.025338046170815955
+gisounddb[650][3] = 0.0023577810841684007
+gisounddb[651][3] = 0.0044425832646652445
+gisounddb[652][3] = 0.016214927805016988
+gisounddb[653][3] = 0.003844343807621522
+gisounddb[654][3] = 0.006827215071181767
+gisounddb[655][3] = 0.0065291171332305135
+gisounddb[656][3] = 0.005104111839541149
+gisounddb[657][3] = 0.0037569127227481823
+gisounddb[658][3] = 0.0014267133932908836
+gisounddb[659][3] = 0.007252019529865882
+gisounddb[660][3] = 0.003037663243438373
+gisounddb[661][3] = 0.003547579392957334
+gisounddb[662][3] = 0.002723086767725526
+gisounddb[663][3] = 0.00861216389292126
+gisounddb[664][3] = 0.0029494502610725214
+gisounddb[665][3] = 0.003828394445767493
+gisounddb[666][3] = 0.00361507882673771
+gisounddb[667][3] = 0.005897955237632097
+gisounddb[668][3] = 0.0035965288058324996
+gisounddb[669][3] = 0.010994972447901716
+gisounddb[670][3] = 0.005013068567851499
+gisounddb[671][3] = 0.009174168590941601
+gisounddb[672][3] = 0.0031386207059344333
+gisounddb[673][3] = 0.0062389754352276785
+gisounddb[674][3] = 0.010260251789330715
+gisounddb[675][3] = 0.006200820890154181
+gisounddb[676][3] = 0.014439685672985604
+gisounddb[677][3] = 0.014813641779068071
+gisounddb[678][3] = 0.018251903548057054
+gisounddb[679][3] = 0.011181666990941563
+gisounddb[680][3] = 0.011554512148330814
+gisounddb[681][3] = 0.0069372208002718575
+gisounddb[682][3] = 0.011953292698018864
+gisounddb[683][3] = 0.006892391583084265
+gisounddb[684][3] = 0.010053442147549947
+gisounddb[685][3] = 0.02013942333774168
+gisounddb[686][3] = 0.015919164013887106
+gisounddb[687][3] = 0.010751038390147512
+gisounddb[688][3] = 0.011063249609909877
+gisounddb[689][3] = 0.014892026521623407
+gisounddb[690][3] = 0.0206630226933796
+gisounddb[691][3] = 0.005069539013580193
+gisounddb[692][3] = 0.01217868828052402
+gisounddb[693][3] = 0.010671139883783867
+gisounddb[694][3] = 0.010858461740808683
+gisounddb[695][3] = 0.017240489956639495
+gisounddb[696][3] = 0.012214672242238486
+gisounddb[697][3] = 0.015738950432507916
+gisounddb[698][3] = 0.011008893943535419
+gisounddb[699][3] = 0.027901099737017383
+gisounddb[700][3] = 0.009659576840261504
+gisounddb[701][3] = 0.017432214557215258
+gisounddb[702][3] = 0.01338733631620945
+gisounddb[703][3] = 0.00499279471633831
+gisounddb[704][3] = 0.01362640708701679
+gisounddb[705][3] = 0.006238732976448212
+gisounddb[706][3] = 0.010218546313561117
+gisounddb[707][3] = 0.019950509463016766
+gisounddb[708][3] = 0.012045865769150385
+gisounddb[709][3] = 0.017874345197251087
+gisounddb[710][3] = 0.0038784685979807386
+gisounddb[711][3] = 0.012714215581831147
+gisounddb[712][3] = 0.004629362796562973
+gisounddb[713][3] = 0.025374640769456485
+gisounddb[714][3] = 0.01117951436749212
+gisounddb[715][3] = 0.010498584279568832
+gisounddb[716][3] = 0.02788710640174532
+gisounddb[717][3] = 0.010561154680304738
+gisounddb[718][3] = 0.01261177097467849
+gisounddb[719][3] = 0.0045605234252421075
+gisounddb[720][3] = 0.02350015730843291
+gisounddb[721][3] = 0.013830368800276839
+gisounddb[722][3] = 0.02639824785663504
+gisounddb[723][3] = 0.0104386559098187
+gisounddb[724][3] = 0.01079184458758692
+gisounddb[725][3] = 0.01717611137786307
+gisounddb[726][3] = 0.015294976336037732
+gisounddb[727][3] = 0.014279692384103506
+gisounddb[728][3] = 0.017302733871876065
+gisounddb[729][3] = 0.01476157600116635
+gisounddb[730][3] = 0.01855250240341873
+gisounddb[731][3] = 0.016643324245619123
+gisounddb[732][3] = 0.01092348431062898
+gisounddb[733][3] = 0.01700530109200499
+gisounddb[734][3] = 0.005491478866684686
+gisounddb[735][3] = 0.01595248092902744
+gisounddb[736][3] = 0.016292034828290055
+gisounddb[737][3] = 0.01927014831937228
+gisounddb[738][3] = 0.022030921247400508
+gisounddb[739][3] = 0.02668552943903565
+gisounddb[740][3] = 0.0350933610512908
+gisounddb[741][3] = 0.032306160116300726
+gisounddb[742][3] = 0.008604982494786587
+gisounddb[743][3] = 0.01336480817533003
+gisounddb[744][3] = 0.04126349312237479
+gisounddb[745][3] = 0.01688365990720188
+gisounddb[746][3] = 0.013269527006402458
+gisounddb[747][3] = 0.033652114226503896
+gisounddb[748][3] = 0.027834791750810706
+gisounddb[749][3] = 0.029605985206080206
+gisounddb[750][3] = 0.06239406054572747
+gisounddb[751][3] = 0.08125712267509352
+gisounddb[752][3] = 0.04506454378223325
+gisounddb[753][3] = 0.005536491531520234
+gisounddb[754][3] = 0.012594556401336374
+gisounddb[755][3] = 0.04331427362163623
+gisounddb[756][3] = 0.03815882769406725
+gisounddb[757][3] = 0.04311968569833153
+gisounddb[758][3] = 0.01290443924710545
+gisounddb[759][3] = 0.02543259226630102
+gisounddb[760][3] = 0.013807331367675472
+gisounddb[761][3] = 0.051727377750206756
+gisounddb[762][3] = 0.018105933100012774
+gisounddb[763][3] = 0.01503090408823028
+gisounddb[764][3] = 0.04066653651601607
+gisounddb[765][3] = 0.019785030704605577
+gisounddb[766][3] = 0.020513528254503605
+gisounddb[767][3] = 0.021811989949497103
+gisounddb[768][3] = 0.04197170110583874
+gisounddb[769][3] = 0.007787717450314113
+gisounddb[770][3] = 0.022039077612055785
+gisounddb[771][3] = 0.050690316125043836
+gisounddb[772][3] = 0.007433778304895162
+gisounddb[773][3] = 0.018971265918227145
+gisounddb[774][3] = 0.022136217631625935
+gisounddb[775][3] = 0.013278755834230403
+gisounddb[776][3] = 0.013759093616217815
+gisounddb[777][3] = 0.017635557936445133
+gisounddb[778][3] = 0.024434598575899323
+gisounddb[779][3] = 0.015879053121518973
+gisounddb[780][3] = 0.046574736134235205
+gisounddb[781][3] = 0.03014772791895619
+gisounddb[782][3] = 0.04200720014999427
+gisounddb[783][3] = 0.029187231954077273
+gisounddb[784][3] = 0.059910205049415674
+gisounddb[785][3] = 0.015469580011371383
+gisounddb[786][3] = 0.024100469852183604
+gisounddb[787][3] = 0.02826988852054064
+gisounddb[788][3] = 0.05809491488469972
+gisounddb[789][3] = 0.10019443620210781
+gisounddb[790][3] = 0.043839447035064656
+gisounddb[791][3] = 0.06318106891536869
+gisounddb[792][3] = 0.007334783924659835
+gisounddb[793][3] = 0.032038716536893073
+gisounddb[794][3] = 0.014547262965728974
+gisounddb[795][3] = 0.06422454479395664
+gisounddb[796][3] = 0.006876915272420333
+gisounddb[797][3] = 0.009956895446421615
+gisounddb[798][3] = 0.04286474221599859
+gisounddb[799][3] = 0.02140306846514407
+gisounddb[800][3] = 0.009356558528507905
+gisounddb[801][3] = 0.05259149570882242
+gisounddb[802][3] = 0.0767571493050292
+gisounddb[803][3] = 0.01958853005092953
+gisounddb[804][3] = 0.0243970110508286
+gisounddb[805][3] = 0.026324404405504633
+gisounddb[806][3] = 0.011989866771048432
+gisounddb[807][3] = 0.018903519856402574
+gisounddb[808][3] = 0.007644364659092591
+gisounddb[809][3] = 0.02157119117881706
+gisounddb[810][3] = 0.017231388131029365
+gisounddb[811][3] = 0.024060375636874375
+gixdb_pitchreference ftgen 0,0,-512,-2,0
+gixdb_pitchnotes ftgen 0,0,-1191,-2,0
+gixdb_pitchadjust ftgen 0,0,-1191,-2,0
+gixdb_pitchrefoffset ftgen 0,0,-4,-2,-1,-1,0,128
+tabw_i 0,0,gixdb_pitchreference
+tabw_i 6,2,gixdb_pitchreference
+tabw_i 12,4,gixdb_pitchreference
+tabw_i 18,6,gixdb_pitchreference
+tabw_i 24,8,gixdb_pitchreference
+tabw_i 30,10,gixdb_pitchreference
+tabw_i 36,12,gixdb_pitchreference
+tabw_i 42,14,gixdb_pitchreference
+tabw_i 48,16,gixdb_pitchreference
+tabw_i 54,18,gixdb_pitchreference
+tabw_i 60,20,gixdb_pitchreference
+tabw_i 66,22,gixdb_pitchreference
+tabw_i 72,24,gixdb_pitchreference
+tabw_i 78,26,gixdb_pitchreference
+tabw_i 84,28,gixdb_pitchreference
+tabw_i 90,30,gixdb_pitchreference
+tabw_i 96,32,gixdb_pitchreference
+tabw_i 102,34,gixdb_pitchreference
+tabw_i 108,36,gixdb_pitchreference
+tabw_i 114,38,gixdb_pitchreference
+tabw_i 120,40,gixdb_pitchreference
+tabw_i 126,42,gixdb_pitchreference
+tabw_i 132,44,gixdb_pitchreference
+tabw_i 138,46,gixdb_pitchreference
+tabw_i 144,48,gixdb_pitchreference
+tabw_i 150,50,gixdb_pitchreference
+tabw_i 156,52,gixdb_pitchreference
+tabw_i 162,54,gixdb_pitchreference
+tabw_i 168,56,gixdb_pitchreference
+tabw_i 174,58,gixdb_pitchreference
+tabw_i 180,60,gixdb_pitchreference
+tabw_i 186,62,gixdb_pitchreference
+tabw_i 192,64,gixdb_pitchreference
+tabw_i 198,66,gixdb_pitchreference
+tabw_i 204,68,gixdb_pitchreference
+tabw_i 210,70,gixdb_pitchreference
+tabw_i 216,72,gixdb_pitchreference
+tabw_i 222,74,gixdb_pitchreference
+tabw_i 228,76,gixdb_pitchreference
+tabw_i 234,78,gixdb_pitchreference
+tabw_i 240,80,gixdb_pitchreference
+tabw_i 246,82,gixdb_pitchreference
+tabw_i 252,84,gixdb_pitchreference
+tabw_i 258,86,gixdb_pitchreference
+tabw_i 264,88,gixdb_pitchreference
+tabw_i 270,90,gixdb_pitchreference
+tabw_i 276,92,gixdb_pitchreference
+tabw_i 282,94,gixdb_pitchreference
+tabw_i 288,96,gixdb_pitchreference
+tabw_i 294,98,gixdb_pitchreference
+tabw_i 300,100,gixdb_pitchreference
+tabw_i 306,102,gixdb_pitchreference
+tabw_i 312,104,gixdb_pitchreference
+tabw_i 318,106,gixdb_pitchreference
+tabw_i 324,108,gixdb_pitchreference
+tabw_i 330,110,gixdb_pitchreference
+tabw_i 336,112,gixdb_pitchreference
+tabw_i 342,114,gixdb_pitchreference
+tabw_i 348,116,gixdb_pitchreference
+tabw_i 354,118,gixdb_pitchreference
+tabw_i 360,120,gixdb_pitchreference
+tabw_i 366,122,gixdb_pitchreference
+tabw_i 372,124,gixdb_pitchreference
+tabw_i 378,126,gixdb_pitchreference
+tabw_i 384,128,gixdb_pitchreference
+tabw_i 390,130,gixdb_pitchreference
+tabw_i 396,132,gixdb_pitchreference
+tabw_i 402,134,gixdb_pitchreference
+tabw_i 408,136,gixdb_pitchreference
+tabw_i 414,138,gixdb_pitchreference
+tabw_i 425,140,gixdb_pitchreference
+tabw_i 430,142,gixdb_pitchreference
+tabw_i 439,144,gixdb_pitchreference
+tabw_i 443,146,gixdb_pitchreference
+tabw_i 446,148,gixdb_pitchreference
+tabw_i 452,150,gixdb_pitchreference
+tabw_i 455,152,gixdb_pitchreference
+tabw_i 462,154,gixdb_pitchreference
+tabw_i 466,156,gixdb_pitchreference
+tabw_i 474,158,gixdb_pitchreference
+tabw_i 478,160,gixdb_pitchreference
+tabw_i 482,162,gixdb_pitchreference
+tabw_i 490,164,gixdb_pitchreference
+tabw_i 494,166,gixdb_pitchreference
+tabw_i 502,168,gixdb_pitchreference
+tabw_i 506,170,gixdb_pitchreference
+tabw_i 510,172,gixdb_pitchreference
+tabw_i 519,174,gixdb_pitchreference
+tabw_i 524,176,gixdb_pitchreference
+tabw_i 533,178,gixdb_pitchreference
+tabw_i 537,180,gixdb_pitchreference
+tabw_i 544,182,gixdb_pitchreference
+tabw_i 547,184,gixdb_pitchreference
+tabw_i 550,186,gixdb_pitchreference
+tabw_i 553,188,gixdb_pitchreference
+tabw_i 556,190,gixdb_pitchreference
+tabw_i 559,192,gixdb_pitchreference
+tabw_i 562,194,gixdb_pitchreference
+tabw_i 565,196,gixdb_pitchreference
+tabw_i 568,198,gixdb_pitchreference
+tabw_i 571,200,gixdb_pitchreference
+tabw_i 574,202,gixdb_pitchreference
+tabw_i 577,204,gixdb_pitchreference
+tabw_i 580,206,gixdb_pitchreference
+tabw_i 583,208,gixdb_pitchreference
+tabw_i 586,210,gixdb_pitchreference
+tabw_i 589,212,gixdb_pitchreference
+tabw_i 592,214,gixdb_pitchreference
+tabw_i 595,216,gixdb_pitchreference
+tabw_i 598,218,gixdb_pitchreference
+tabw_i 601,220,gixdb_pitchreference
+tabw_i 604,222,gixdb_pitchreference
+tabw_i 607,224,gixdb_pitchreference
+tabw_i 610,226,gixdb_pitchreference
+tabw_i 613,228,gixdb_pitchreference
+tabw_i 616,230,gixdb_pitchreference
+tabw_i 619,232,gixdb_pitchreference
+tabw_i 622,234,gixdb_pitchreference
+tabw_i 625,236,gixdb_pitchreference
+tabw_i 628,238,gixdb_pitchreference
+tabw_i 631,240,gixdb_pitchreference
+tabw_i 634,242,gixdb_pitchreference
+tabw_i 637,244,gixdb_pitchreference
+tabw_i 640,246,gixdb_pitchreference
+tabw_i 643,248,gixdb_pitchreference
+tabw_i 646,250,gixdb_pitchreference
+tabw_i 649,252,gixdb_pitchreference
+tabw_i 652,254,gixdb_pitchreference
+tabw_i 655,256,gixdb_pitchreference
+tabw_i 659,258,gixdb_pitchreference
+tabw_i 663,260,gixdb_pitchreference
+tabw_i 667,262,gixdb_pitchreference
+tabw_i 671,264,gixdb_pitchreference
+tabw_i 675,266,gixdb_pitchreference
+tabw_i 679,268,gixdb_pitchreference
+tabw_i 683,270,gixdb_pitchreference
+tabw_i 687,272,gixdb_pitchreference
+tabw_i 691,274,gixdb_pitchreference
+tabw_i 695,276,gixdb_pitchreference
+tabw_i 699,278,gixdb_pitchreference
+tabw_i 703,280,gixdb_pitchreference
+tabw_i 707,282,gixdb_pitchreference
+tabw_i 711,284,gixdb_pitchreference
+tabw_i 715,286,gixdb_pitchreference
+tabw_i 719,288,gixdb_pitchreference
+tabw_i 723,290,gixdb_pitchreference
+tabw_i 727,292,gixdb_pitchreference
+tabw_i 731,294,gixdb_pitchreference
+tabw_i 735,296,gixdb_pitchreference
+tabw_i 739,298,gixdb_pitchreference
+tabw_i 743,300,gixdb_pitchreference
+tabw_i 747,302,gixdb_pitchreference
+tabw_i 751,304,gixdb_pitchreference
+tabw_i 755,306,gixdb_pitchreference
+tabw_i 759,308,gixdb_pitchreference
+tabw_i 763,310,gixdb_pitchreference
+tabw_i 767,312,gixdb_pitchreference
+tabw_i 771,314,gixdb_pitchreference
+tabw_i 775,316,gixdb_pitchreference
+tabw_i 779,318,gixdb_pitchreference
+tabw_i 783,320,gixdb_pitchreference
+tabw_i 787,322,gixdb_pitchreference
+tabw_i 791,324,gixdb_pitchreference
+tabw_i 795,326,gixdb_pitchreference
+tabw_i 799,328,gixdb_pitchreference
+tabw_i 803,330,gixdb_pitchreference
+tabw_i 807,332,gixdb_pitchreference
+tabw_i 811,334,gixdb_pitchreference
+tabw_i 815,336,gixdb_pitchreference
+tabw_i 819,338,gixdb_pitchreference
+tabw_i 823,340,gixdb_pitchreference
+tabw_i 827,342,gixdb_pitchreference
+tabw_i 831,344,gixdb_pitchreference
+tabw_i 835,346,gixdb_pitchreference
+tabw_i 839,348,gixdb_pitchreference
+tabw_i 843,350,gixdb_pitchreference
+tabw_i 847,352,gixdb_pitchreference
+tabw_i 851,354,gixdb_pitchreference
+tabw_i 855,356,gixdb_pitchreference
+tabw_i 859,358,gixdb_pitchreference
+tabw_i 863,360,gixdb_pitchreference
+tabw_i 867,362,gixdb_pitchreference
+tabw_i 871,364,gixdb_pitchreference
+tabw_i 875,366,gixdb_pitchreference
+tabw_i 879,368,gixdb_pitchreference
+tabw_i 883,370,gixdb_pitchreference
+tabw_i 887,372,gixdb_pitchreference
+tabw_i 891,374,gixdb_pitchreference
+tabw_i 895,376,gixdb_pitchreference
+tabw_i 899,378,gixdb_pitchreference
+tabw_i 907,380,gixdb_pitchreference
+tabw_i 911,382,gixdb_pitchreference
+tabw_i 919,384,gixdb_pitchreference
+tabw_i 923,386,gixdb_pitchreference
+tabw_i 928,388,gixdb_pitchreference
+tabw_i 938,390,gixdb_pitchreference
+tabw_i 943,392,gixdb_pitchreference
+tabw_i 953,394,gixdb_pitchreference
+tabw_i 958,396,gixdb_pitchreference
+tabw_i 968,398,gixdb_pitchreference
+tabw_i 973,400,gixdb_pitchreference
+tabw_i 977,402,gixdb_pitchreference
+tabw_i 985,404,gixdb_pitchreference
+tabw_i 989,406,gixdb_pitchreference
+tabw_i 997,408,gixdb_pitchreference
+tabw_i 1001,410,gixdb_pitchreference
+tabw_i 1006,412,gixdb_pitchreference
+tabw_i 1015,414,gixdb_pitchreference
+tabw_i 1019,416,gixdb_pitchreference
+tabw_i 1028,418,gixdb_pitchreference
+tabw_i 1033,420,gixdb_pitchreference
+tabw_i 1043,422,gixdb_pitchreference
+tabw_i 1048,424,gixdb_pitchreference
+tabw_i 1052,426,gixdb_pitchreference
+tabw_i 1060,428,gixdb_pitchreference
+tabw_i 1064,430,gixdb_pitchreference
+tabw_i 1071,432,gixdb_pitchreference
+tabw_i 1074,434,gixdb_pitchreference
+tabw_i 1077,436,gixdb_pitchreference
+tabw_i 1080,438,gixdb_pitchreference
+tabw_i 1083,440,gixdb_pitchreference
+tabw_i 1086,442,gixdb_pitchreference
+tabw_i 1089,444,gixdb_pitchreference
+tabw_i 1092,446,gixdb_pitchreference
+tabw_i 1095,448,gixdb_pitchreference
+tabw_i 1098,450,gixdb_pitchreference
+tabw_i 1101,452,gixdb_pitchreference
+tabw_i 1104,454,gixdb_pitchreference
+tabw_i 1107,456,gixdb_pitchreference
+tabw_i 1110,458,gixdb_pitchreference
+tabw_i 1113,460,gixdb_pitchreference
+tabw_i 1116,462,gixdb_pitchreference
+tabw_i 1119,464,gixdb_pitchreference
+tabw_i 1122,466,gixdb_pitchreference
+tabw_i 1125,468,gixdb_pitchreference
+tabw_i 1128,470,gixdb_pitchreference
+tabw_i 1131,472,gixdb_pitchreference
+tabw_i 1134,474,gixdb_pitchreference
+tabw_i 1137,476,gixdb_pitchreference
+tabw_i 1140,478,gixdb_pitchreference
+tabw_i 1143,480,gixdb_pitchreference
+tabw_i 1146,482,gixdb_pitchreference
+tabw_i 1149,484,gixdb_pitchreference
+tabw_i 1152,486,gixdb_pitchreference
+tabw_i 1155,488,gixdb_pitchreference
+tabw_i 1158,490,gixdb_pitchreference
+tabw_i 1161,492,gixdb_pitchreference
+tabw_i 1164,494,gixdb_pitchreference
+tabw_i 1167,496,gixdb_pitchreference
+tabw_i 1170,498,gixdb_pitchreference
+tabw_i 1173,500,gixdb_pitchreference
+tabw_i 1176,502,gixdb_pitchreference
+tabw_i 1179,504,gixdb_pitchreference
+tabw_i 1182,506,gixdb_pitchreference
+tabw_i 1185,508,gixdb_pitchreference
+tabw_i 1188,510,gixdb_pitchreference
+tabw_i 5,1,gixdb_pitchreference
+tabw_i 11,3,gixdb_pitchreference
+tabw_i 17,5,gixdb_pitchreference
+tabw_i 23,7,gixdb_pitchreference
+tabw_i 29,9,gixdb_pitchreference
+tabw_i 35,11,gixdb_pitchreference
+tabw_i 41,13,gixdb_pitchreference
+tabw_i 47,15,gixdb_pitchreference
+tabw_i 53,17,gixdb_pitchreference
+tabw_i 59,19,gixdb_pitchreference
+tabw_i 65,21,gixdb_pitchreference
+tabw_i 71,23,gixdb_pitchreference
+tabw_i 77,25,gixdb_pitchreference
+tabw_i 83,27,gixdb_pitchreference
+tabw_i 89,29,gixdb_pitchreference
+tabw_i 95,31,gixdb_pitchreference
+tabw_i 101,33,gixdb_pitchreference
+tabw_i 107,35,gixdb_pitchreference
+tabw_i 113,37,gixdb_pitchreference
+tabw_i 119,39,gixdb_pitchreference
+tabw_i 125,41,gixdb_pitchreference
+tabw_i 131,43,gixdb_pitchreference
+tabw_i 137,45,gixdb_pitchreference
+tabw_i 143,47,gixdb_pitchreference
+tabw_i 149,49,gixdb_pitchreference
+tabw_i 155,51,gixdb_pitchreference
+tabw_i 161,53,gixdb_pitchreference
+tabw_i 167,55,gixdb_pitchreference
+tabw_i 173,57,gixdb_pitchreference
+tabw_i 179,59,gixdb_pitchreference
+tabw_i 185,61,gixdb_pitchreference
+tabw_i 191,63,gixdb_pitchreference
+tabw_i 197,65,gixdb_pitchreference
+tabw_i 203,67,gixdb_pitchreference
+tabw_i 209,69,gixdb_pitchreference
+tabw_i 215,71,gixdb_pitchreference
+tabw_i 221,73,gixdb_pitchreference
+tabw_i 227,75,gixdb_pitchreference
+tabw_i 233,77,gixdb_pitchreference
+tabw_i 239,79,gixdb_pitchreference
+tabw_i 245,81,gixdb_pitchreference
+tabw_i 251,83,gixdb_pitchreference
+tabw_i 257,85,gixdb_pitchreference
+tabw_i 263,87,gixdb_pitchreference
+tabw_i 269,89,gixdb_pitchreference
+tabw_i 275,91,gixdb_pitchreference
+tabw_i 281,93,gixdb_pitchreference
+tabw_i 287,95,gixdb_pitchreference
+tabw_i 293,97,gixdb_pitchreference
+tabw_i 299,99,gixdb_pitchreference
+tabw_i 305,101,gixdb_pitchreference
+tabw_i 311,103,gixdb_pitchreference
+tabw_i 317,105,gixdb_pitchreference
+tabw_i 323,107,gixdb_pitchreference
+tabw_i 329,109,gixdb_pitchreference
+tabw_i 335,111,gixdb_pitchreference
+tabw_i 341,113,gixdb_pitchreference
+tabw_i 347,115,gixdb_pitchreference
+tabw_i 353,117,gixdb_pitchreference
+tabw_i 359,119,gixdb_pitchreference
+tabw_i 365,121,gixdb_pitchreference
+tabw_i 371,123,gixdb_pitchreference
+tabw_i 377,125,gixdb_pitchreference
+tabw_i 383,127,gixdb_pitchreference
+tabw_i 389,129,gixdb_pitchreference
+tabw_i 395,131,gixdb_pitchreference
+tabw_i 401,133,gixdb_pitchreference
+tabw_i 407,135,gixdb_pitchreference
+tabw_i 413,137,gixdb_pitchreference
+tabw_i 424,139,gixdb_pitchreference
+tabw_i 429,141,gixdb_pitchreference
+tabw_i 438,143,gixdb_pitchreference
+tabw_i 442,145,gixdb_pitchreference
+tabw_i 445,147,gixdb_pitchreference
+tabw_i 451,149,gixdb_pitchreference
+tabw_i 454,151,gixdb_pitchreference
+tabw_i 461,153,gixdb_pitchreference
+tabw_i 465,155,gixdb_pitchreference
+tabw_i 473,157,gixdb_pitchreference
+tabw_i 477,159,gixdb_pitchreference
+tabw_i 481,161,gixdb_pitchreference
+tabw_i 489,163,gixdb_pitchreference
+tabw_i 493,165,gixdb_pitchreference
+tabw_i 501,167,gixdb_pitchreference
+tabw_i 505,169,gixdb_pitchreference
+tabw_i 509,171,gixdb_pitchreference
+tabw_i 518,173,gixdb_pitchreference
+tabw_i 523,175,gixdb_pitchreference
+tabw_i 532,177,gixdb_pitchreference
+tabw_i 536,179,gixdb_pitchreference
+tabw_i 543,181,gixdb_pitchreference
+tabw_i 546,183,gixdb_pitchreference
+tabw_i 549,185,gixdb_pitchreference
+tabw_i 552,187,gixdb_pitchreference
+tabw_i 555,189,gixdb_pitchreference
+tabw_i 558,191,gixdb_pitchreference
+tabw_i 561,193,gixdb_pitchreference
+tabw_i 564,195,gixdb_pitchreference
+tabw_i 567,197,gixdb_pitchreference
+tabw_i 570,199,gixdb_pitchreference
+tabw_i 573,201,gixdb_pitchreference
+tabw_i 576,203,gixdb_pitchreference
+tabw_i 579,205,gixdb_pitchreference
+tabw_i 582,207,gixdb_pitchreference
+tabw_i 585,209,gixdb_pitchreference
+tabw_i 588,211,gixdb_pitchreference
+tabw_i 591,213,gixdb_pitchreference
+tabw_i 594,215,gixdb_pitchreference
+tabw_i 597,217,gixdb_pitchreference
+tabw_i 600,219,gixdb_pitchreference
+tabw_i 603,221,gixdb_pitchreference
+tabw_i 606,223,gixdb_pitchreference
+tabw_i 609,225,gixdb_pitchreference
+tabw_i 612,227,gixdb_pitchreference
+tabw_i 615,229,gixdb_pitchreference
+tabw_i 618,231,gixdb_pitchreference
+tabw_i 621,233,gixdb_pitchreference
+tabw_i 624,235,gixdb_pitchreference
+tabw_i 627,237,gixdb_pitchreference
+tabw_i 630,239,gixdb_pitchreference
+tabw_i 633,241,gixdb_pitchreference
+tabw_i 636,243,gixdb_pitchreference
+tabw_i 639,245,gixdb_pitchreference
+tabw_i 642,247,gixdb_pitchreference
+tabw_i 645,249,gixdb_pitchreference
+tabw_i 648,251,gixdb_pitchreference
+tabw_i 651,253,gixdb_pitchreference
+tabw_i 654,255,gixdb_pitchreference
+tabw_i 658,257,gixdb_pitchreference
+tabw_i 662,259,gixdb_pitchreference
+tabw_i 666,261,gixdb_pitchreference
+tabw_i 670,263,gixdb_pitchreference
+tabw_i 674,265,gixdb_pitchreference
+tabw_i 678,267,gixdb_pitchreference
+tabw_i 682,269,gixdb_pitchreference
+tabw_i 686,271,gixdb_pitchreference
+tabw_i 690,273,gixdb_pitchreference
+tabw_i 694,275,gixdb_pitchreference
+tabw_i 698,277,gixdb_pitchreference
+tabw_i 702,279,gixdb_pitchreference
+tabw_i 706,281,gixdb_pitchreference
+tabw_i 710,283,gixdb_pitchreference
+tabw_i 714,285,gixdb_pitchreference
+tabw_i 718,287,gixdb_pitchreference
+tabw_i 722,289,gixdb_pitchreference
+tabw_i 726,291,gixdb_pitchreference
+tabw_i 730,293,gixdb_pitchreference
+tabw_i 734,295,gixdb_pitchreference
+tabw_i 738,297,gixdb_pitchreference
+tabw_i 742,299,gixdb_pitchreference
+tabw_i 746,301,gixdb_pitchreference
+tabw_i 750,303,gixdb_pitchreference
+tabw_i 754,305,gixdb_pitchreference
+tabw_i 758,307,gixdb_pitchreference
+tabw_i 762,309,gixdb_pitchreference
+tabw_i 766,311,gixdb_pitchreference
+tabw_i 770,313,gixdb_pitchreference
+tabw_i 774,315,gixdb_pitchreference
+tabw_i 778,317,gixdb_pitchreference
+tabw_i 782,319,gixdb_pitchreference
+tabw_i 786,321,gixdb_pitchreference
+tabw_i 790,323,gixdb_pitchreference
+tabw_i 794,325,gixdb_pitchreference
+tabw_i 798,327,gixdb_pitchreference
+tabw_i 802,329,gixdb_pitchreference
+tabw_i 806,331,gixdb_pitchreference
+tabw_i 810,333,gixdb_pitchreference
+tabw_i 814,335,gixdb_pitchreference
+tabw_i 818,337,gixdb_pitchreference
+tabw_i 822,339,gixdb_pitchreference
+tabw_i 826,341,gixdb_pitchreference
+tabw_i 830,343,gixdb_pitchreference
+tabw_i 834,345,gixdb_pitchreference
+tabw_i 838,347,gixdb_pitchreference
+tabw_i 842,349,gixdb_pitchreference
+tabw_i 846,351,gixdb_pitchreference
+tabw_i 850,353,gixdb_pitchreference
+tabw_i 854,355,gixdb_pitchreference
+tabw_i 858,357,gixdb_pitchreference
+tabw_i 862,359,gixdb_pitchreference
+tabw_i 866,361,gixdb_pitchreference
+tabw_i 870,363,gixdb_pitchreference
+tabw_i 874,365,gixdb_pitchreference
+tabw_i 878,367,gixdb_pitchreference
+tabw_i 882,369,gixdb_pitchreference
+tabw_i 886,371,gixdb_pitchreference
+tabw_i 890,373,gixdb_pitchreference
+tabw_i 894,375,gixdb_pitchreference
+tabw_i 898,377,gixdb_pitchreference
+tabw_i 906,379,gixdb_pitchreference
+tabw_i 910,381,gixdb_pitchreference
+tabw_i 918,383,gixdb_pitchreference
+tabw_i 922,385,gixdb_pitchreference
+tabw_i 927,387,gixdb_pitchreference
+tabw_i 937,389,gixdb_pitchreference
+tabw_i 942,391,gixdb_pitchreference
+tabw_i 952,393,gixdb_pitchreference
+tabw_i 957,395,gixdb_pitchreference
+tabw_i 967,397,gixdb_pitchreference
+tabw_i 972,399,gixdb_pitchreference
+tabw_i 976,401,gixdb_pitchreference
+tabw_i 984,403,gixdb_pitchreference
+tabw_i 988,405,gixdb_pitchreference
+tabw_i 996,407,gixdb_pitchreference
+tabw_i 1000,409,gixdb_pitchreference
+tabw_i 1005,411,gixdb_pitchreference
+tabw_i 1014,413,gixdb_pitchreference
+tabw_i 1018,415,gixdb_pitchreference
+tabw_i 1027,417,gixdb_pitchreference
+tabw_i 1032,419,gixdb_pitchreference
+tabw_i 1042,421,gixdb_pitchreference
+tabw_i 1047,423,gixdb_pitchreference
+tabw_i 1051,425,gixdb_pitchreference
+tabw_i 1059,427,gixdb_pitchreference
+tabw_i 1063,429,gixdb_pitchreference
+tabw_i 1070,431,gixdb_pitchreference
+tabw_i 1073,433,gixdb_pitchreference
+tabw_i 1076,435,gixdb_pitchreference
+tabw_i 1079,437,gixdb_pitchreference
+tabw_i 1082,439,gixdb_pitchreference
+tabw_i 1085,441,gixdb_pitchreference
+tabw_i 1088,443,gixdb_pitchreference
+tabw_i 1091,445,gixdb_pitchreference
+tabw_i 1094,447,gixdb_pitchreference
+tabw_i 1097,449,gixdb_pitchreference
+tabw_i 1100,451,gixdb_pitchreference
+tabw_i 1103,453,gixdb_pitchreference
+tabw_i 1106,455,gixdb_pitchreference
+tabw_i 1109,457,gixdb_pitchreference
+tabw_i 1112,459,gixdb_pitchreference
+tabw_i 1115,461,gixdb_pitchreference
+tabw_i 1118,463,gixdb_pitchreference
+tabw_i 1121,465,gixdb_pitchreference
+tabw_i 1124,467,gixdb_pitchreference
+tabw_i 1127,469,gixdb_pitchreference
+tabw_i 1130,471,gixdb_pitchreference
+tabw_i 1133,473,gixdb_pitchreference
+tabw_i 1136,475,gixdb_pitchreference
+tabw_i 1139,477,gixdb_pitchreference
+tabw_i 1142,479,gixdb_pitchreference
+tabw_i 1145,481,gixdb_pitchreference
+tabw_i 1148,483,gixdb_pitchreference
+tabw_i 1151,485,gixdb_pitchreference
+tabw_i 1154,487,gixdb_pitchreference
+tabw_i 1157,489,gixdb_pitchreference
+tabw_i 1160,491,gixdb_pitchreference
+tabw_i 1163,493,gixdb_pitchreference
+tabw_i 1166,495,gixdb_pitchreference
+tabw_i 1169,497,gixdb_pitchreference
+tabw_i 1172,499,gixdb_pitchreference
+tabw_i 1175,501,gixdb_pitchreference
+tabw_i 1178,503,gixdb_pitchreference
+tabw_i 1181,505,gixdb_pitchreference
+tabw_i 1184,507,gixdb_pitchreference
+tabw_i 1187,509,gixdb_pitchreference
+tabw_i 1190,511,gixdb_pitchreference
+tabw_i 684,0,gixdb_pitchnotes
+tabw_i 690,1,gixdb_pitchnotes
+tabw_i 691,2,gixdb_pitchnotes
+tabw_i 705,3,gixdb_pitchnotes
+tabw_i 731,4,gixdb_pitchnotes
+tabw_i 736,5,gixdb_pitchnotes
+tabw_i 684,6,gixdb_pitchnotes
+tabw_i 690,7,gixdb_pitchnotes
+tabw_i 691,8,gixdb_pitchnotes
+tabw_i 705,9,gixdb_pitchnotes
+tabw_i 731,10,gixdb_pitchnotes
+tabw_i 736,11,gixdb_pitchnotes
+tabw_i 684,12,gixdb_pitchnotes
+tabw_i 690,13,gixdb_pitchnotes
+tabw_i 691,14,gixdb_pitchnotes
+tabw_i 705,15,gixdb_pitchnotes
+tabw_i 731,16,gixdb_pitchnotes
+tabw_i 736,17,gixdb_pitchnotes
+tabw_i 684,18,gixdb_pitchnotes
+tabw_i 690,19,gixdb_pitchnotes
+tabw_i 691,20,gixdb_pitchnotes
+tabw_i 705,21,gixdb_pitchnotes
+tabw_i 731,22,gixdb_pitchnotes
+tabw_i 736,23,gixdb_pitchnotes
+tabw_i 684,24,gixdb_pitchnotes
+tabw_i 690,25,gixdb_pitchnotes
+tabw_i 691,26,gixdb_pitchnotes
+tabw_i 705,27,gixdb_pitchnotes
+tabw_i 731,28,gixdb_pitchnotes
+tabw_i 736,29,gixdb_pitchnotes
+tabw_i 684,30,gixdb_pitchnotes
+tabw_i 690,31,gixdb_pitchnotes
+tabw_i 691,32,gixdb_pitchnotes
+tabw_i 705,33,gixdb_pitchnotes
+tabw_i 731,34,gixdb_pitchnotes
+tabw_i 736,35,gixdb_pitchnotes
+tabw_i 684,36,gixdb_pitchnotes
+tabw_i 690,37,gixdb_pitchnotes
+tabw_i 691,38,gixdb_pitchnotes
+tabw_i 705,39,gixdb_pitchnotes
+tabw_i 731,40,gixdb_pitchnotes
+tabw_i 736,41,gixdb_pitchnotes
+tabw_i 684,42,gixdb_pitchnotes
+tabw_i 690,43,gixdb_pitchnotes
+tabw_i 691,44,gixdb_pitchnotes
+tabw_i 705,45,gixdb_pitchnotes
+tabw_i 731,46,gixdb_pitchnotes
+tabw_i 736,47,gixdb_pitchnotes
+tabw_i 684,48,gixdb_pitchnotes
+tabw_i 690,49,gixdb_pitchnotes
+tabw_i 691,50,gixdb_pitchnotes
+tabw_i 705,51,gixdb_pitchnotes
+tabw_i 731,52,gixdb_pitchnotes
+tabw_i 736,53,gixdb_pitchnotes
+tabw_i 684,54,gixdb_pitchnotes
+tabw_i 690,55,gixdb_pitchnotes
+tabw_i 691,56,gixdb_pitchnotes
+tabw_i 705,57,gixdb_pitchnotes
+tabw_i 731,58,gixdb_pitchnotes
+tabw_i 736,59,gixdb_pitchnotes
+tabw_i 684,60,gixdb_pitchnotes
+tabw_i 690,61,gixdb_pitchnotes
+tabw_i 691,62,gixdb_pitchnotes
+tabw_i 705,63,gixdb_pitchnotes
+tabw_i 731,64,gixdb_pitchnotes
+tabw_i 736,65,gixdb_pitchnotes
+tabw_i 684,66,gixdb_pitchnotes
+tabw_i 690,67,gixdb_pitchnotes
+tabw_i 691,68,gixdb_pitchnotes
+tabw_i 705,69,gixdb_pitchnotes
+tabw_i 731,70,gixdb_pitchnotes
+tabw_i 736,71,gixdb_pitchnotes
+tabw_i 684,72,gixdb_pitchnotes
+tabw_i 690,73,gixdb_pitchnotes
+tabw_i 691,74,gixdb_pitchnotes
+tabw_i 705,75,gixdb_pitchnotes
+tabw_i 731,76,gixdb_pitchnotes
+tabw_i 736,77,gixdb_pitchnotes
+tabw_i 684,78,gixdb_pitchnotes
+tabw_i 690,79,gixdb_pitchnotes
+tabw_i 691,80,gixdb_pitchnotes
+tabw_i 705,81,gixdb_pitchnotes
+tabw_i 731,82,gixdb_pitchnotes
+tabw_i 736,83,gixdb_pitchnotes
+tabw_i 684,84,gixdb_pitchnotes
+tabw_i 690,85,gixdb_pitchnotes
+tabw_i 691,86,gixdb_pitchnotes
+tabw_i 705,87,gixdb_pitchnotes
+tabw_i 731,88,gixdb_pitchnotes
+tabw_i 736,89,gixdb_pitchnotes
+tabw_i 684,90,gixdb_pitchnotes
+tabw_i 690,91,gixdb_pitchnotes
+tabw_i 691,92,gixdb_pitchnotes
+tabw_i 705,93,gixdb_pitchnotes
+tabw_i 731,94,gixdb_pitchnotes
+tabw_i 736,95,gixdb_pitchnotes
+tabw_i 684,96,gixdb_pitchnotes
+tabw_i 690,97,gixdb_pitchnotes
+tabw_i 691,98,gixdb_pitchnotes
+tabw_i 705,99,gixdb_pitchnotes
+tabw_i 731,100,gixdb_pitchnotes
+tabw_i 736,101,gixdb_pitchnotes
+tabw_i 684,102,gixdb_pitchnotes
+tabw_i 690,103,gixdb_pitchnotes
+tabw_i 691,104,gixdb_pitchnotes
+tabw_i 705,105,gixdb_pitchnotes
+tabw_i 731,106,gixdb_pitchnotes
+tabw_i 736,107,gixdb_pitchnotes
+tabw_i 684,108,gixdb_pitchnotes
+tabw_i 690,109,gixdb_pitchnotes
+tabw_i 691,110,gixdb_pitchnotes
+tabw_i 705,111,gixdb_pitchnotes
+tabw_i 731,112,gixdb_pitchnotes
+tabw_i 736,113,gixdb_pitchnotes
+tabw_i 684,114,gixdb_pitchnotes
+tabw_i 690,115,gixdb_pitchnotes
+tabw_i 691,116,gixdb_pitchnotes
+tabw_i 705,117,gixdb_pitchnotes
+tabw_i 731,118,gixdb_pitchnotes
+tabw_i 736,119,gixdb_pitchnotes
+tabw_i 684,120,gixdb_pitchnotes
+tabw_i 690,121,gixdb_pitchnotes
+tabw_i 691,122,gixdb_pitchnotes
+tabw_i 705,123,gixdb_pitchnotes
+tabw_i 731,124,gixdb_pitchnotes
+tabw_i 736,125,gixdb_pitchnotes
+tabw_i 684,126,gixdb_pitchnotes
+tabw_i 690,127,gixdb_pitchnotes
+tabw_i 691,128,gixdb_pitchnotes
+tabw_i 705,129,gixdb_pitchnotes
+tabw_i 731,130,gixdb_pitchnotes
+tabw_i 736,131,gixdb_pitchnotes
+tabw_i 684,132,gixdb_pitchnotes
+tabw_i 690,133,gixdb_pitchnotes
+tabw_i 691,134,gixdb_pitchnotes
+tabw_i 705,135,gixdb_pitchnotes
+tabw_i 731,136,gixdb_pitchnotes
+tabw_i 736,137,gixdb_pitchnotes
+tabw_i 684,138,gixdb_pitchnotes
+tabw_i 690,139,gixdb_pitchnotes
+tabw_i 691,140,gixdb_pitchnotes
+tabw_i 705,141,gixdb_pitchnotes
+tabw_i 731,142,gixdb_pitchnotes
+tabw_i 736,143,gixdb_pitchnotes
+tabw_i 684,144,gixdb_pitchnotes
+tabw_i 690,145,gixdb_pitchnotes
+tabw_i 691,146,gixdb_pitchnotes
+tabw_i 705,147,gixdb_pitchnotes
+tabw_i 731,148,gixdb_pitchnotes
+tabw_i 736,149,gixdb_pitchnotes
+tabw_i 684,150,gixdb_pitchnotes
+tabw_i 690,151,gixdb_pitchnotes
+tabw_i 691,152,gixdb_pitchnotes
+tabw_i 705,153,gixdb_pitchnotes
+tabw_i 731,154,gixdb_pitchnotes
+tabw_i 736,155,gixdb_pitchnotes
+tabw_i 684,156,gixdb_pitchnotes
+tabw_i 690,157,gixdb_pitchnotes
+tabw_i 691,158,gixdb_pitchnotes
+tabw_i 705,159,gixdb_pitchnotes
+tabw_i 731,160,gixdb_pitchnotes
+tabw_i 736,161,gixdb_pitchnotes
+tabw_i 684,162,gixdb_pitchnotes
+tabw_i 690,163,gixdb_pitchnotes
+tabw_i 691,164,gixdb_pitchnotes
+tabw_i 705,165,gixdb_pitchnotes
+tabw_i 731,166,gixdb_pitchnotes
+tabw_i 736,167,gixdb_pitchnotes
+tabw_i 684,168,gixdb_pitchnotes
+tabw_i 690,169,gixdb_pitchnotes
+tabw_i 691,170,gixdb_pitchnotes
+tabw_i 705,171,gixdb_pitchnotes
+tabw_i 731,172,gixdb_pitchnotes
+tabw_i 736,173,gixdb_pitchnotes
+tabw_i 684,174,gixdb_pitchnotes
+tabw_i 690,175,gixdb_pitchnotes
+tabw_i 691,176,gixdb_pitchnotes
+tabw_i 705,177,gixdb_pitchnotes
+tabw_i 731,178,gixdb_pitchnotes
+tabw_i 736,179,gixdb_pitchnotes
+tabw_i 684,180,gixdb_pitchnotes
+tabw_i 690,181,gixdb_pitchnotes
+tabw_i 691,182,gixdb_pitchnotes
+tabw_i 705,183,gixdb_pitchnotes
+tabw_i 731,184,gixdb_pitchnotes
+tabw_i 736,185,gixdb_pitchnotes
+tabw_i 684,186,gixdb_pitchnotes
+tabw_i 690,187,gixdb_pitchnotes
+tabw_i 691,188,gixdb_pitchnotes
+tabw_i 705,189,gixdb_pitchnotes
+tabw_i 731,190,gixdb_pitchnotes
+tabw_i 736,191,gixdb_pitchnotes
+tabw_i 684,192,gixdb_pitchnotes
+tabw_i 690,193,gixdb_pitchnotes
+tabw_i 691,194,gixdb_pitchnotes
+tabw_i 705,195,gixdb_pitchnotes
+tabw_i 731,196,gixdb_pitchnotes
+tabw_i 736,197,gixdb_pitchnotes
+tabw_i 684,198,gixdb_pitchnotes
+tabw_i 690,199,gixdb_pitchnotes
+tabw_i 691,200,gixdb_pitchnotes
+tabw_i 705,201,gixdb_pitchnotes
+tabw_i 731,202,gixdb_pitchnotes
+tabw_i 736,203,gixdb_pitchnotes
+tabw_i 684,204,gixdb_pitchnotes
+tabw_i 690,205,gixdb_pitchnotes
+tabw_i 691,206,gixdb_pitchnotes
+tabw_i 705,207,gixdb_pitchnotes
+tabw_i 731,208,gixdb_pitchnotes
+tabw_i 736,209,gixdb_pitchnotes
+tabw_i 684,210,gixdb_pitchnotes
+tabw_i 690,211,gixdb_pitchnotes
+tabw_i 691,212,gixdb_pitchnotes
+tabw_i 705,213,gixdb_pitchnotes
+tabw_i 731,214,gixdb_pitchnotes
+tabw_i 736,215,gixdb_pitchnotes
+tabw_i 684,216,gixdb_pitchnotes
+tabw_i 690,217,gixdb_pitchnotes
+tabw_i 691,218,gixdb_pitchnotes
+tabw_i 705,219,gixdb_pitchnotes
+tabw_i 731,220,gixdb_pitchnotes
+tabw_i 736,221,gixdb_pitchnotes
+tabw_i 684,222,gixdb_pitchnotes
+tabw_i 690,223,gixdb_pitchnotes
+tabw_i 691,224,gixdb_pitchnotes
+tabw_i 705,225,gixdb_pitchnotes
+tabw_i 731,226,gixdb_pitchnotes
+tabw_i 736,227,gixdb_pitchnotes
+tabw_i 684,228,gixdb_pitchnotes
+tabw_i 690,229,gixdb_pitchnotes
+tabw_i 691,230,gixdb_pitchnotes
+tabw_i 705,231,gixdb_pitchnotes
+tabw_i 731,232,gixdb_pitchnotes
+tabw_i 736,233,gixdb_pitchnotes
+tabw_i 684,234,gixdb_pitchnotes
+tabw_i 690,235,gixdb_pitchnotes
+tabw_i 691,236,gixdb_pitchnotes
+tabw_i 705,237,gixdb_pitchnotes
+tabw_i 731,238,gixdb_pitchnotes
+tabw_i 736,239,gixdb_pitchnotes
+tabw_i 684,240,gixdb_pitchnotes
+tabw_i 690,241,gixdb_pitchnotes
+tabw_i 691,242,gixdb_pitchnotes
+tabw_i 705,243,gixdb_pitchnotes
+tabw_i 731,244,gixdb_pitchnotes
+tabw_i 736,245,gixdb_pitchnotes
+tabw_i 684,246,gixdb_pitchnotes
+tabw_i 690,247,gixdb_pitchnotes
+tabw_i 691,248,gixdb_pitchnotes
+tabw_i 705,249,gixdb_pitchnotes
+tabw_i 731,250,gixdb_pitchnotes
+tabw_i 736,251,gixdb_pitchnotes
+tabw_i 684,252,gixdb_pitchnotes
+tabw_i 690,253,gixdb_pitchnotes
+tabw_i 691,254,gixdb_pitchnotes
+tabw_i 705,255,gixdb_pitchnotes
+tabw_i 731,256,gixdb_pitchnotes
+tabw_i 736,257,gixdb_pitchnotes
+tabw_i 684,258,gixdb_pitchnotes
+tabw_i 690,259,gixdb_pitchnotes
+tabw_i 691,260,gixdb_pitchnotes
+tabw_i 705,261,gixdb_pitchnotes
+tabw_i 731,262,gixdb_pitchnotes
+tabw_i 736,263,gixdb_pitchnotes
+tabw_i 684,264,gixdb_pitchnotes
+tabw_i 690,265,gixdb_pitchnotes
+tabw_i 691,266,gixdb_pitchnotes
+tabw_i 705,267,gixdb_pitchnotes
+tabw_i 731,268,gixdb_pitchnotes
+tabw_i 736,269,gixdb_pitchnotes
+tabw_i 684,270,gixdb_pitchnotes
+tabw_i 690,271,gixdb_pitchnotes
+tabw_i 691,272,gixdb_pitchnotes
+tabw_i 705,273,gixdb_pitchnotes
+tabw_i 731,274,gixdb_pitchnotes
+tabw_i 736,275,gixdb_pitchnotes
+tabw_i 684,276,gixdb_pitchnotes
+tabw_i 690,277,gixdb_pitchnotes
+tabw_i 691,278,gixdb_pitchnotes
+tabw_i 705,279,gixdb_pitchnotes
+tabw_i 731,280,gixdb_pitchnotes
+tabw_i 736,281,gixdb_pitchnotes
+tabw_i 684,282,gixdb_pitchnotes
+tabw_i 690,283,gixdb_pitchnotes
+tabw_i 691,284,gixdb_pitchnotes
+tabw_i 705,285,gixdb_pitchnotes
+tabw_i 731,286,gixdb_pitchnotes
+tabw_i 736,287,gixdb_pitchnotes
+tabw_i 684,288,gixdb_pitchnotes
+tabw_i 690,289,gixdb_pitchnotes
+tabw_i 691,290,gixdb_pitchnotes
+tabw_i 705,291,gixdb_pitchnotes
+tabw_i 731,292,gixdb_pitchnotes
+tabw_i 736,293,gixdb_pitchnotes
+tabw_i 684,294,gixdb_pitchnotes
+tabw_i 690,295,gixdb_pitchnotes
+tabw_i 691,296,gixdb_pitchnotes
+tabw_i 705,297,gixdb_pitchnotes
+tabw_i 731,298,gixdb_pitchnotes
+tabw_i 736,299,gixdb_pitchnotes
+tabw_i 684,300,gixdb_pitchnotes
+tabw_i 690,301,gixdb_pitchnotes
+tabw_i 691,302,gixdb_pitchnotes
+tabw_i 705,303,gixdb_pitchnotes
+tabw_i 731,304,gixdb_pitchnotes
+tabw_i 736,305,gixdb_pitchnotes
+tabw_i 684,306,gixdb_pitchnotes
+tabw_i 690,307,gixdb_pitchnotes
+tabw_i 691,308,gixdb_pitchnotes
+tabw_i 705,309,gixdb_pitchnotes
+tabw_i 731,310,gixdb_pitchnotes
+tabw_i 736,311,gixdb_pitchnotes
+tabw_i 684,312,gixdb_pitchnotes
+tabw_i 690,313,gixdb_pitchnotes
+tabw_i 691,314,gixdb_pitchnotes
+tabw_i 705,315,gixdb_pitchnotes
+tabw_i 731,316,gixdb_pitchnotes
+tabw_i 736,317,gixdb_pitchnotes
+tabw_i 684,318,gixdb_pitchnotes
+tabw_i 690,319,gixdb_pitchnotes
+tabw_i 691,320,gixdb_pitchnotes
+tabw_i 705,321,gixdb_pitchnotes
+tabw_i 731,322,gixdb_pitchnotes
+tabw_i 736,323,gixdb_pitchnotes
+tabw_i 684,324,gixdb_pitchnotes
+tabw_i 690,325,gixdb_pitchnotes
+tabw_i 691,326,gixdb_pitchnotes
+tabw_i 705,327,gixdb_pitchnotes
+tabw_i 731,328,gixdb_pitchnotes
+tabw_i 736,329,gixdb_pitchnotes
+tabw_i 684,330,gixdb_pitchnotes
+tabw_i 690,331,gixdb_pitchnotes
+tabw_i 691,332,gixdb_pitchnotes
+tabw_i 705,333,gixdb_pitchnotes
+tabw_i 731,334,gixdb_pitchnotes
+tabw_i 736,335,gixdb_pitchnotes
+tabw_i 684,336,gixdb_pitchnotes
+tabw_i 690,337,gixdb_pitchnotes
+tabw_i 691,338,gixdb_pitchnotes
+tabw_i 705,339,gixdb_pitchnotes
+tabw_i 731,340,gixdb_pitchnotes
+tabw_i 736,341,gixdb_pitchnotes
+tabw_i 684,342,gixdb_pitchnotes
+tabw_i 690,343,gixdb_pitchnotes
+tabw_i 691,344,gixdb_pitchnotes
+tabw_i 705,345,gixdb_pitchnotes
+tabw_i 731,346,gixdb_pitchnotes
+tabw_i 736,347,gixdb_pitchnotes
+tabw_i 684,348,gixdb_pitchnotes
+tabw_i 690,349,gixdb_pitchnotes
+tabw_i 691,350,gixdb_pitchnotes
+tabw_i 705,351,gixdb_pitchnotes
+tabw_i 731,352,gixdb_pitchnotes
+tabw_i 736,353,gixdb_pitchnotes
+tabw_i 684,354,gixdb_pitchnotes
+tabw_i 690,355,gixdb_pitchnotes
+tabw_i 691,356,gixdb_pitchnotes
+tabw_i 705,357,gixdb_pitchnotes
+tabw_i 731,358,gixdb_pitchnotes
+tabw_i 736,359,gixdb_pitchnotes
+tabw_i 684,360,gixdb_pitchnotes
+tabw_i 690,361,gixdb_pitchnotes
+tabw_i 691,362,gixdb_pitchnotes
+tabw_i 705,363,gixdb_pitchnotes
+tabw_i 731,364,gixdb_pitchnotes
+tabw_i 736,365,gixdb_pitchnotes
+tabw_i 684,366,gixdb_pitchnotes
+tabw_i 690,367,gixdb_pitchnotes
+tabw_i 691,368,gixdb_pitchnotes
+tabw_i 705,369,gixdb_pitchnotes
+tabw_i 731,370,gixdb_pitchnotes
+tabw_i 736,371,gixdb_pitchnotes
+tabw_i 684,372,gixdb_pitchnotes
+tabw_i 690,373,gixdb_pitchnotes
+tabw_i 691,374,gixdb_pitchnotes
+tabw_i 705,375,gixdb_pitchnotes
+tabw_i 731,376,gixdb_pitchnotes
+tabw_i 736,377,gixdb_pitchnotes
+tabw_i 684,378,gixdb_pitchnotes
+tabw_i 690,379,gixdb_pitchnotes
+tabw_i 691,380,gixdb_pitchnotes
+tabw_i 705,381,gixdb_pitchnotes
+tabw_i 731,382,gixdb_pitchnotes
+tabw_i 736,383,gixdb_pitchnotes
+tabw_i 684,384,gixdb_pitchnotes
+tabw_i 690,385,gixdb_pitchnotes
+tabw_i 691,386,gixdb_pitchnotes
+tabw_i 705,387,gixdb_pitchnotes
+tabw_i 731,388,gixdb_pitchnotes
+tabw_i 736,389,gixdb_pitchnotes
+tabw_i 684,390,gixdb_pitchnotes
+tabw_i 690,391,gixdb_pitchnotes
+tabw_i 691,392,gixdb_pitchnotes
+tabw_i 705,393,gixdb_pitchnotes
+tabw_i 731,394,gixdb_pitchnotes
+tabw_i 736,395,gixdb_pitchnotes
+tabw_i 684,396,gixdb_pitchnotes
+tabw_i 690,397,gixdb_pitchnotes
+tabw_i 691,398,gixdb_pitchnotes
+tabw_i 705,399,gixdb_pitchnotes
+tabw_i 731,400,gixdb_pitchnotes
+tabw_i 736,401,gixdb_pitchnotes
+tabw_i 684,402,gixdb_pitchnotes
+tabw_i 690,403,gixdb_pitchnotes
+tabw_i 691,404,gixdb_pitchnotes
+tabw_i 705,405,gixdb_pitchnotes
+tabw_i 731,406,gixdb_pitchnotes
+tabw_i 736,407,gixdb_pitchnotes
+tabw_i 684,408,gixdb_pitchnotes
+tabw_i 690,409,gixdb_pitchnotes
+tabw_i 691,410,gixdb_pitchnotes
+tabw_i 705,411,gixdb_pitchnotes
+tabw_i 731,412,gixdb_pitchnotes
+tabw_i 736,413,gixdb_pitchnotes
+tabw_i 684,414,gixdb_pitchnotes
+tabw_i 690,415,gixdb_pitchnotes
+tabw_i 691,416,gixdb_pitchnotes
+tabw_i 693,417,gixdb_pitchnotes
+tabw_i 698,418,gixdb_pitchnotes
+tabw_i 705,419,gixdb_pitchnotes
+tabw_i 714,420,gixdb_pitchnotes
+tabw_i 723,421,gixdb_pitchnotes
+tabw_i 724,422,gixdb_pitchnotes
+tabw_i 731,423,gixdb_pitchnotes
+tabw_i 736,424,gixdb_pitchnotes
+tabw_i 693,425,gixdb_pitchnotes
+tabw_i 698,426,gixdb_pitchnotes
+tabw_i 714,427,gixdb_pitchnotes
+tabw_i 723,428,gixdb_pitchnotes
+tabw_i 724,429,gixdb_pitchnotes
+tabw_i 693,430,gixdb_pitchnotes
+tabw_i 698,431,gixdb_pitchnotes
+tabw_i 703,432,gixdb_pitchnotes
+tabw_i 710,433,gixdb_pitchnotes
+tabw_i 712,434,gixdb_pitchnotes
+tabw_i 714,435,gixdb_pitchnotes
+tabw_i 719,436,gixdb_pitchnotes
+tabw_i 723,437,gixdb_pitchnotes
+tabw_i 724,438,gixdb_pitchnotes
+tabw_i 703,439,gixdb_pitchnotes
+tabw_i 710,440,gixdb_pitchnotes
+tabw_i 712,441,gixdb_pitchnotes
+tabw_i 719,442,gixdb_pitchnotes
+tabw_i 679,443,gixdb_pitchnotes
+tabw_i 694,444,gixdb_pitchnotes
+tabw_i 715,445,gixdb_pitchnotes
+tabw_i 679,446,gixdb_pitchnotes
+tabw_i 681,447,gixdb_pitchnotes
+tabw_i 683,448,gixdb_pitchnotes
+tabw_i 694,449,gixdb_pitchnotes
+tabw_i 715,450,gixdb_pitchnotes
+tabw_i 734,451,gixdb_pitchnotes
+tabw_i 681,452,gixdb_pitchnotes
+tabw_i 683,453,gixdb_pitchnotes
+tabw_i 734,454,gixdb_pitchnotes
+tabw_i 680,455,gixdb_pitchnotes
+tabw_i 681,456,gixdb_pitchnotes
+tabw_i 683,457,gixdb_pitchnotes
+tabw_i 692,458,gixdb_pitchnotes
+tabw_i 717,459,gixdb_pitchnotes
+tabw_i 718,460,gixdb_pitchnotes
+tabw_i 734,461,gixdb_pitchnotes
+tabw_i 680,462,gixdb_pitchnotes
+tabw_i 692,463,gixdb_pitchnotes
+tabw_i 717,464,gixdb_pitchnotes
+tabw_i 718,465,gixdb_pitchnotes
+tabw_i 680,466,gixdb_pitchnotes
+tabw_i 692,467,gixdb_pitchnotes
+tabw_i 696,468,gixdb_pitchnotes
+tabw_i 704,469,gixdb_pitchnotes
+tabw_i 717,470,gixdb_pitchnotes
+tabw_i 718,471,gixdb_pitchnotes
+tabw_i 727,472,gixdb_pitchnotes
+tabw_i 735,473,gixdb_pitchnotes
+tabw_i 696,474,gixdb_pitchnotes
+tabw_i 704,475,gixdb_pitchnotes
+tabw_i 727,476,gixdb_pitchnotes
+tabw_i 735,477,gixdb_pitchnotes
+tabw_i 687,478,gixdb_pitchnotes
+tabw_i 700,479,gixdb_pitchnotes
+tabw_i 729,480,gixdb_pitchnotes
+tabw_i 732,481,gixdb_pitchnotes
+tabw_i 687,482,gixdb_pitchnotes
+tabw_i 697,483,gixdb_pitchnotes
+tabw_i 700,484,gixdb_pitchnotes
+tabw_i 702,485,gixdb_pitchnotes
+tabw_i 708,486,gixdb_pitchnotes
+tabw_i 711,487,gixdb_pitchnotes
+tabw_i 729,488,gixdb_pitchnotes
+tabw_i 732,489,gixdb_pitchnotes
+tabw_i 697,490,gixdb_pitchnotes
+tabw_i 702,491,gixdb_pitchnotes
+tabw_i 708,492,gixdb_pitchnotes
+tabw_i 711,493,gixdb_pitchnotes
+tabw_i 697,494,gixdb_pitchnotes
+tabw_i 702,495,gixdb_pitchnotes
+tabw_i 708,496,gixdb_pitchnotes
+tabw_i 709,497,gixdb_pitchnotes
+tabw_i 711,498,gixdb_pitchnotes
+tabw_i 730,499,gixdb_pitchnotes
+tabw_i 733,500,gixdb_pitchnotes
+tabw_i 737,501,gixdb_pitchnotes
+tabw_i 709,502,gixdb_pitchnotes
+tabw_i 730,503,gixdb_pitchnotes
+tabw_i 733,504,gixdb_pitchnotes
+tabw_i 737,505,gixdb_pitchnotes
+tabw_i 686,506,gixdb_pitchnotes
+tabw_i 689,507,gixdb_pitchnotes
+tabw_i 695,508,gixdb_pitchnotes
+tabw_i 726,509,gixdb_pitchnotes
+tabw_i 686,510,gixdb_pitchnotes
+tabw_i 689,511,gixdb_pitchnotes
+tabw_i 695,512,gixdb_pitchnotes
+tabw_i 699,513,gixdb_pitchnotes
+tabw_i 713,514,gixdb_pitchnotes
+tabw_i 716,515,gixdb_pitchnotes
+tabw_i 720,516,gixdb_pitchnotes
+tabw_i 722,517,gixdb_pitchnotes
+tabw_i 726,518,gixdb_pitchnotes
+tabw_i 699,519,gixdb_pitchnotes
+tabw_i 713,520,gixdb_pitchnotes
+tabw_i 716,521,gixdb_pitchnotes
+tabw_i 720,522,gixdb_pitchnotes
+tabw_i 722,523,gixdb_pitchnotes
+tabw_i 678,524,gixdb_pitchnotes
+tabw_i 699,525,gixdb_pitchnotes
+tabw_i 707,526,gixdb_pitchnotes
+tabw_i 713,527,gixdb_pitchnotes
+tabw_i 716,528,gixdb_pitchnotes
+tabw_i 720,529,gixdb_pitchnotes
+tabw_i 722,530,gixdb_pitchnotes
+tabw_i 725,531,gixdb_pitchnotes
+tabw_i 728,532,gixdb_pitchnotes
+tabw_i 678,533,gixdb_pitchnotes
+tabw_i 707,534,gixdb_pitchnotes
+tabw_i 725,535,gixdb_pitchnotes
+tabw_i 728,536,gixdb_pitchnotes
+tabw_i 678,537,gixdb_pitchnotes
+tabw_i 685,538,gixdb_pitchnotes
+tabw_i 701,539,gixdb_pitchnotes
+tabw_i 707,540,gixdb_pitchnotes
+tabw_i 721,541,gixdb_pitchnotes
+tabw_i 725,542,gixdb_pitchnotes
+tabw_i 728,543,gixdb_pitchnotes
+tabw_i 685,544,gixdb_pitchnotes
+tabw_i 701,545,gixdb_pitchnotes
+tabw_i 721,546,gixdb_pitchnotes
+tabw_i 682,547,gixdb_pitchnotes
+tabw_i 688,548,gixdb_pitchnotes
+tabw_i 706,549,gixdb_pitchnotes
+tabw_i 682,550,gixdb_pitchnotes
+tabw_i 688,551,gixdb_pitchnotes
+tabw_i 706,552,gixdb_pitchnotes
+tabw_i 682,553,gixdb_pitchnotes
+tabw_i 688,554,gixdb_pitchnotes
+tabw_i 706,555,gixdb_pitchnotes
+tabw_i 682,556,gixdb_pitchnotes
+tabw_i 688,557,gixdb_pitchnotes
+tabw_i 706,558,gixdb_pitchnotes
+tabw_i 682,559,gixdb_pitchnotes
+tabw_i 688,560,gixdb_pitchnotes
+tabw_i 706,561,gixdb_pitchnotes
+tabw_i 682,562,gixdb_pitchnotes
+tabw_i 688,563,gixdb_pitchnotes
+tabw_i 706,564,gixdb_pitchnotes
+tabw_i 682,565,gixdb_pitchnotes
+tabw_i 688,566,gixdb_pitchnotes
+tabw_i 706,567,gixdb_pitchnotes
+tabw_i 682,568,gixdb_pitchnotes
+tabw_i 688,569,gixdb_pitchnotes
+tabw_i 706,570,gixdb_pitchnotes
+tabw_i 682,571,gixdb_pitchnotes
+tabw_i 688,572,gixdb_pitchnotes
+tabw_i 706,573,gixdb_pitchnotes
+tabw_i 682,574,gixdb_pitchnotes
+tabw_i 688,575,gixdb_pitchnotes
+tabw_i 706,576,gixdb_pitchnotes
+tabw_i 682,577,gixdb_pitchnotes
+tabw_i 688,578,gixdb_pitchnotes
+tabw_i 706,579,gixdb_pitchnotes
+tabw_i 682,580,gixdb_pitchnotes
+tabw_i 688,581,gixdb_pitchnotes
+tabw_i 706,582,gixdb_pitchnotes
+tabw_i 682,583,gixdb_pitchnotes
+tabw_i 688,584,gixdb_pitchnotes
+tabw_i 706,585,gixdb_pitchnotes
+tabw_i 682,586,gixdb_pitchnotes
+tabw_i 688,587,gixdb_pitchnotes
+tabw_i 706,588,gixdb_pitchnotes
+tabw_i 682,589,gixdb_pitchnotes
+tabw_i 688,590,gixdb_pitchnotes
+tabw_i 706,591,gixdb_pitchnotes
+tabw_i 682,592,gixdb_pitchnotes
+tabw_i 688,593,gixdb_pitchnotes
+tabw_i 706,594,gixdb_pitchnotes
+tabw_i 682,595,gixdb_pitchnotes
+tabw_i 688,596,gixdb_pitchnotes
+tabw_i 706,597,gixdb_pitchnotes
+tabw_i 682,598,gixdb_pitchnotes
+tabw_i 688,599,gixdb_pitchnotes
+tabw_i 706,600,gixdb_pitchnotes
+tabw_i 682,601,gixdb_pitchnotes
+tabw_i 688,602,gixdb_pitchnotes
+tabw_i 706,603,gixdb_pitchnotes
+tabw_i 682,604,gixdb_pitchnotes
+tabw_i 688,605,gixdb_pitchnotes
+tabw_i 706,606,gixdb_pitchnotes
+tabw_i 682,607,gixdb_pitchnotes
+tabw_i 688,608,gixdb_pitchnotes
+tabw_i 706,609,gixdb_pitchnotes
+tabw_i 682,610,gixdb_pitchnotes
+tabw_i 688,611,gixdb_pitchnotes
+tabw_i 706,612,gixdb_pitchnotes
+tabw_i 682,613,gixdb_pitchnotes
+tabw_i 688,614,gixdb_pitchnotes
+tabw_i 706,615,gixdb_pitchnotes
+tabw_i 682,616,gixdb_pitchnotes
+tabw_i 688,617,gixdb_pitchnotes
+tabw_i 706,618,gixdb_pitchnotes
+tabw_i 682,619,gixdb_pitchnotes
+tabw_i 688,620,gixdb_pitchnotes
+tabw_i 706,621,gixdb_pitchnotes
+tabw_i 682,622,gixdb_pitchnotes
+tabw_i 688,623,gixdb_pitchnotes
+tabw_i 706,624,gixdb_pitchnotes
+tabw_i 682,625,gixdb_pitchnotes
+tabw_i 688,626,gixdb_pitchnotes
+tabw_i 706,627,gixdb_pitchnotes
+tabw_i 682,628,gixdb_pitchnotes
+tabw_i 688,629,gixdb_pitchnotes
+tabw_i 706,630,gixdb_pitchnotes
+tabw_i 682,631,gixdb_pitchnotes
+tabw_i 688,632,gixdb_pitchnotes
+tabw_i 706,633,gixdb_pitchnotes
+tabw_i 682,634,gixdb_pitchnotes
+tabw_i 688,635,gixdb_pitchnotes
+tabw_i 706,636,gixdb_pitchnotes
+tabw_i 682,637,gixdb_pitchnotes
+tabw_i 688,638,gixdb_pitchnotes
+tabw_i 706,639,gixdb_pitchnotes
+tabw_i 682,640,gixdb_pitchnotes
+tabw_i 688,641,gixdb_pitchnotes
+tabw_i 706,642,gixdb_pitchnotes
+tabw_i 682,643,gixdb_pitchnotes
+tabw_i 688,644,gixdb_pitchnotes
+tabw_i 706,645,gixdb_pitchnotes
+tabw_i 682,646,gixdb_pitchnotes
+tabw_i 688,647,gixdb_pitchnotes
+tabw_i 706,648,gixdb_pitchnotes
+tabw_i 682,649,gixdb_pitchnotes
+tabw_i 688,650,gixdb_pitchnotes
+tabw_i 706,651,gixdb_pitchnotes
+tabw_i 682,652,gixdb_pitchnotes
+tabw_i 688,653,gixdb_pitchnotes
+tabw_i 706,654,gixdb_pitchnotes
+tabw_i 743,655,gixdb_pitchnotes
+tabw_i 772,656,gixdb_pitchnotes
+tabw_i 777,657,gixdb_pitchnotes
+tabw_i 786,658,gixdb_pitchnotes
+tabw_i 743,659,gixdb_pitchnotes
+tabw_i 772,660,gixdb_pitchnotes
+tabw_i 777,661,gixdb_pitchnotes
+tabw_i 786,662,gixdb_pitchnotes
+tabw_i 743,663,gixdb_pitchnotes
+tabw_i 772,664,gixdb_pitchnotes
+tabw_i 777,665,gixdb_pitchnotes
+tabw_i 786,666,gixdb_pitchnotes
+tabw_i 743,667,gixdb_pitchnotes
+tabw_i 772,668,gixdb_pitchnotes
+tabw_i 777,669,gixdb_pitchnotes
+tabw_i 786,670,gixdb_pitchnotes
+tabw_i 743,671,gixdb_pitchnotes
+tabw_i 772,672,gixdb_pitchnotes
+tabw_i 777,673,gixdb_pitchnotes
+tabw_i 786,674,gixdb_pitchnotes
+tabw_i 743,675,gixdb_pitchnotes
+tabw_i 772,676,gixdb_pitchnotes
+tabw_i 777,677,gixdb_pitchnotes
+tabw_i 786,678,gixdb_pitchnotes
+tabw_i 743,679,gixdb_pitchnotes
+tabw_i 772,680,gixdb_pitchnotes
+tabw_i 777,681,gixdb_pitchnotes
+tabw_i 786,682,gixdb_pitchnotes
+tabw_i 743,683,gixdb_pitchnotes
+tabw_i 772,684,gixdb_pitchnotes
+tabw_i 777,685,gixdb_pitchnotes
+tabw_i 786,686,gixdb_pitchnotes
+tabw_i 743,687,gixdb_pitchnotes
+tabw_i 772,688,gixdb_pitchnotes
+tabw_i 777,689,gixdb_pitchnotes
+tabw_i 786,690,gixdb_pitchnotes
+tabw_i 743,691,gixdb_pitchnotes
+tabw_i 772,692,gixdb_pitchnotes
+tabw_i 777,693,gixdb_pitchnotes
+tabw_i 786,694,gixdb_pitchnotes
+tabw_i 743,695,gixdb_pitchnotes
+tabw_i 772,696,gixdb_pitchnotes
+tabw_i 777,697,gixdb_pitchnotes
+tabw_i 786,698,gixdb_pitchnotes
+tabw_i 743,699,gixdb_pitchnotes
+tabw_i 772,700,gixdb_pitchnotes
+tabw_i 777,701,gixdb_pitchnotes
+tabw_i 786,702,gixdb_pitchnotes
+tabw_i 743,703,gixdb_pitchnotes
+tabw_i 772,704,gixdb_pitchnotes
+tabw_i 777,705,gixdb_pitchnotes
+tabw_i 786,706,gixdb_pitchnotes
+tabw_i 743,707,gixdb_pitchnotes
+tabw_i 772,708,gixdb_pitchnotes
+tabw_i 777,709,gixdb_pitchnotes
+tabw_i 786,710,gixdb_pitchnotes
+tabw_i 743,711,gixdb_pitchnotes
+tabw_i 772,712,gixdb_pitchnotes
+tabw_i 777,713,gixdb_pitchnotes
+tabw_i 786,714,gixdb_pitchnotes
+tabw_i 743,715,gixdb_pitchnotes
+tabw_i 772,716,gixdb_pitchnotes
+tabw_i 777,717,gixdb_pitchnotes
+tabw_i 786,718,gixdb_pitchnotes
+tabw_i 743,719,gixdb_pitchnotes
+tabw_i 772,720,gixdb_pitchnotes
+tabw_i 777,721,gixdb_pitchnotes
+tabw_i 786,722,gixdb_pitchnotes
+tabw_i 743,723,gixdb_pitchnotes
+tabw_i 772,724,gixdb_pitchnotes
+tabw_i 777,725,gixdb_pitchnotes
+tabw_i 786,726,gixdb_pitchnotes
+tabw_i 743,727,gixdb_pitchnotes
+tabw_i 772,728,gixdb_pitchnotes
+tabw_i 777,729,gixdb_pitchnotes
+tabw_i 786,730,gixdb_pitchnotes
+tabw_i 743,731,gixdb_pitchnotes
+tabw_i 772,732,gixdb_pitchnotes
+tabw_i 777,733,gixdb_pitchnotes
+tabw_i 786,734,gixdb_pitchnotes
+tabw_i 743,735,gixdb_pitchnotes
+tabw_i 772,736,gixdb_pitchnotes
+tabw_i 777,737,gixdb_pitchnotes
+tabw_i 786,738,gixdb_pitchnotes
+tabw_i 743,739,gixdb_pitchnotes
+tabw_i 772,740,gixdb_pitchnotes
+tabw_i 777,741,gixdb_pitchnotes
+tabw_i 786,742,gixdb_pitchnotes
+tabw_i 743,743,gixdb_pitchnotes
+tabw_i 772,744,gixdb_pitchnotes
+tabw_i 777,745,gixdb_pitchnotes
+tabw_i 786,746,gixdb_pitchnotes
+tabw_i 743,747,gixdb_pitchnotes
+tabw_i 772,748,gixdb_pitchnotes
+tabw_i 777,749,gixdb_pitchnotes
+tabw_i 786,750,gixdb_pitchnotes
+tabw_i 743,751,gixdb_pitchnotes
+tabw_i 772,752,gixdb_pitchnotes
+tabw_i 777,753,gixdb_pitchnotes
+tabw_i 786,754,gixdb_pitchnotes
+tabw_i 743,755,gixdb_pitchnotes
+tabw_i 772,756,gixdb_pitchnotes
+tabw_i 777,757,gixdb_pitchnotes
+tabw_i 786,758,gixdb_pitchnotes
+tabw_i 743,759,gixdb_pitchnotes
+tabw_i 772,760,gixdb_pitchnotes
+tabw_i 777,761,gixdb_pitchnotes
+tabw_i 786,762,gixdb_pitchnotes
+tabw_i 743,763,gixdb_pitchnotes
+tabw_i 772,764,gixdb_pitchnotes
+tabw_i 777,765,gixdb_pitchnotes
+tabw_i 786,766,gixdb_pitchnotes
+tabw_i 743,767,gixdb_pitchnotes
+tabw_i 772,768,gixdb_pitchnotes
+tabw_i 777,769,gixdb_pitchnotes
+tabw_i 786,770,gixdb_pitchnotes
+tabw_i 743,771,gixdb_pitchnotes
+tabw_i 772,772,gixdb_pitchnotes
+tabw_i 777,773,gixdb_pitchnotes
+tabw_i 786,774,gixdb_pitchnotes
+tabw_i 743,775,gixdb_pitchnotes
+tabw_i 772,776,gixdb_pitchnotes
+tabw_i 777,777,gixdb_pitchnotes
+tabw_i 786,778,gixdb_pitchnotes
+tabw_i 743,779,gixdb_pitchnotes
+tabw_i 772,780,gixdb_pitchnotes
+tabw_i 777,781,gixdb_pitchnotes
+tabw_i 786,782,gixdb_pitchnotes
+tabw_i 743,783,gixdb_pitchnotes
+tabw_i 772,784,gixdb_pitchnotes
+tabw_i 777,785,gixdb_pitchnotes
+tabw_i 786,786,gixdb_pitchnotes
+tabw_i 743,787,gixdb_pitchnotes
+tabw_i 772,788,gixdb_pitchnotes
+tabw_i 777,789,gixdb_pitchnotes
+tabw_i 786,790,gixdb_pitchnotes
+tabw_i 743,791,gixdb_pitchnotes
+tabw_i 772,792,gixdb_pitchnotes
+tabw_i 777,793,gixdb_pitchnotes
+tabw_i 786,794,gixdb_pitchnotes
+tabw_i 743,795,gixdb_pitchnotes
+tabw_i 772,796,gixdb_pitchnotes
+tabw_i 777,797,gixdb_pitchnotes
+tabw_i 786,798,gixdb_pitchnotes
+tabw_i 743,799,gixdb_pitchnotes
+tabw_i 772,800,gixdb_pitchnotes
+tabw_i 777,801,gixdb_pitchnotes
+tabw_i 786,802,gixdb_pitchnotes
+tabw_i 743,803,gixdb_pitchnotes
+tabw_i 772,804,gixdb_pitchnotes
+tabw_i 777,805,gixdb_pitchnotes
+tabw_i 786,806,gixdb_pitchnotes
+tabw_i 743,807,gixdb_pitchnotes
+tabw_i 772,808,gixdb_pitchnotes
+tabw_i 777,809,gixdb_pitchnotes
+tabw_i 786,810,gixdb_pitchnotes
+tabw_i 743,811,gixdb_pitchnotes
+tabw_i 772,812,gixdb_pitchnotes
+tabw_i 777,813,gixdb_pitchnotes
+tabw_i 786,814,gixdb_pitchnotes
+tabw_i 743,815,gixdb_pitchnotes
+tabw_i 772,816,gixdb_pitchnotes
+tabw_i 777,817,gixdb_pitchnotes
+tabw_i 786,818,gixdb_pitchnotes
+tabw_i 743,819,gixdb_pitchnotes
+tabw_i 772,820,gixdb_pitchnotes
+tabw_i 777,821,gixdb_pitchnotes
+tabw_i 786,822,gixdb_pitchnotes
+tabw_i 743,823,gixdb_pitchnotes
+tabw_i 772,824,gixdb_pitchnotes
+tabw_i 777,825,gixdb_pitchnotes
+tabw_i 786,826,gixdb_pitchnotes
+tabw_i 743,827,gixdb_pitchnotes
+tabw_i 772,828,gixdb_pitchnotes
+tabw_i 777,829,gixdb_pitchnotes
+tabw_i 786,830,gixdb_pitchnotes
+tabw_i 743,831,gixdb_pitchnotes
+tabw_i 772,832,gixdb_pitchnotes
+tabw_i 777,833,gixdb_pitchnotes
+tabw_i 786,834,gixdb_pitchnotes
+tabw_i 743,835,gixdb_pitchnotes
+tabw_i 772,836,gixdb_pitchnotes
+tabw_i 777,837,gixdb_pitchnotes
+tabw_i 786,838,gixdb_pitchnotes
+tabw_i 743,839,gixdb_pitchnotes
+tabw_i 772,840,gixdb_pitchnotes
+tabw_i 777,841,gixdb_pitchnotes
+tabw_i 786,842,gixdb_pitchnotes
+tabw_i 743,843,gixdb_pitchnotes
+tabw_i 772,844,gixdb_pitchnotes
+tabw_i 777,845,gixdb_pitchnotes
+tabw_i 786,846,gixdb_pitchnotes
+tabw_i 743,847,gixdb_pitchnotes
+tabw_i 772,848,gixdb_pitchnotes
+tabw_i 777,849,gixdb_pitchnotes
+tabw_i 786,850,gixdb_pitchnotes
+tabw_i 743,851,gixdb_pitchnotes
+tabw_i 772,852,gixdb_pitchnotes
+tabw_i 777,853,gixdb_pitchnotes
+tabw_i 786,854,gixdb_pitchnotes
+tabw_i 743,855,gixdb_pitchnotes
+tabw_i 772,856,gixdb_pitchnotes
+tabw_i 777,857,gixdb_pitchnotes
+tabw_i 786,858,gixdb_pitchnotes
+tabw_i 743,859,gixdb_pitchnotes
+tabw_i 772,860,gixdb_pitchnotes
+tabw_i 777,861,gixdb_pitchnotes
+tabw_i 786,862,gixdb_pitchnotes
+tabw_i 743,863,gixdb_pitchnotes
+tabw_i 772,864,gixdb_pitchnotes
+tabw_i 777,865,gixdb_pitchnotes
+tabw_i 786,866,gixdb_pitchnotes
+tabw_i 743,867,gixdb_pitchnotes
+tabw_i 772,868,gixdb_pitchnotes
+tabw_i 777,869,gixdb_pitchnotes
+tabw_i 786,870,gixdb_pitchnotes
+tabw_i 743,871,gixdb_pitchnotes
+tabw_i 772,872,gixdb_pitchnotes
+tabw_i 777,873,gixdb_pitchnotes
+tabw_i 786,874,gixdb_pitchnotes
+tabw_i 743,875,gixdb_pitchnotes
+tabw_i 772,876,gixdb_pitchnotes
+tabw_i 777,877,gixdb_pitchnotes
+tabw_i 786,878,gixdb_pitchnotes
+tabw_i 743,879,gixdb_pitchnotes
+tabw_i 772,880,gixdb_pitchnotes
+tabw_i 777,881,gixdb_pitchnotes
+tabw_i 786,882,gixdb_pitchnotes
+tabw_i 743,883,gixdb_pitchnotes
+tabw_i 772,884,gixdb_pitchnotes
+tabw_i 777,885,gixdb_pitchnotes
+tabw_i 786,886,gixdb_pitchnotes
+tabw_i 743,887,gixdb_pitchnotes
+tabw_i 772,888,gixdb_pitchnotes
+tabw_i 777,889,gixdb_pitchnotes
+tabw_i 786,890,gixdb_pitchnotes
+tabw_i 743,891,gixdb_pitchnotes
+tabw_i 772,892,gixdb_pitchnotes
+tabw_i 777,893,gixdb_pitchnotes
+tabw_i 786,894,gixdb_pitchnotes
+tabw_i 743,895,gixdb_pitchnotes
+tabw_i 772,896,gixdb_pitchnotes
+tabw_i 777,897,gixdb_pitchnotes
+tabw_i 786,898,gixdb_pitchnotes
+tabw_i 743,899,gixdb_pitchnotes
+tabw_i 746,900,gixdb_pitchnotes
+tabw_i 748,901,gixdb_pitchnotes
+tabw_i 772,902,gixdb_pitchnotes
+tabw_i 774,903,gixdb_pitchnotes
+tabw_i 777,904,gixdb_pitchnotes
+tabw_i 786,905,gixdb_pitchnotes
+tabw_i 806,906,gixdb_pitchnotes
+tabw_i 746,907,gixdb_pitchnotes
+tabw_i 748,908,gixdb_pitchnotes
+tabw_i 774,909,gixdb_pitchnotes
+tabw_i 806,910,gixdb_pitchnotes
+tabw_i 742,911,gixdb_pitchnotes
+tabw_i 746,912,gixdb_pitchnotes
+tabw_i 748,913,gixdb_pitchnotes
+tabw_i 759,914,gixdb_pitchnotes
+tabw_i 774,915,gixdb_pitchnotes
+tabw_i 797,916,gixdb_pitchnotes
+tabw_i 803,917,gixdb_pitchnotes
+tabw_i 806,918,gixdb_pitchnotes
+tabw_i 742,919,gixdb_pitchnotes
+tabw_i 759,920,gixdb_pitchnotes
+tabw_i 797,921,gixdb_pitchnotes
+tabw_i 803,922,gixdb_pitchnotes
+tabw_i 738,923,gixdb_pitchnotes
+tabw_i 747,924,gixdb_pitchnotes
+tabw_i 754,925,gixdb_pitchnotes
+tabw_i 778,926,gixdb_pitchnotes
+tabw_i 781,927,gixdb_pitchnotes
+tabw_i 738,928,gixdb_pitchnotes
+tabw_i 745,929,gixdb_pitchnotes
+tabw_i 747,930,gixdb_pitchnotes
+tabw_i 749,931,gixdb_pitchnotes
+tabw_i 754,932,gixdb_pitchnotes
+tabw_i 765,933,gixdb_pitchnotes
+tabw_i 778,934,gixdb_pitchnotes
+tabw_i 781,935,gixdb_pitchnotes
+tabw_i 793,936,gixdb_pitchnotes
+tabw_i 808,937,gixdb_pitchnotes
+tabw_i 745,938,gixdb_pitchnotes
+tabw_i 749,939,gixdb_pitchnotes
+tabw_i 765,940,gixdb_pitchnotes
+tabw_i 793,941,gixdb_pitchnotes
+tabw_i 808,942,gixdb_pitchnotes
+tabw_i 741,943,gixdb_pitchnotes
+tabw_i 744,944,gixdb_pitchnotes
+tabw_i 745,945,gixdb_pitchnotes
+tabw_i 749,946,gixdb_pitchnotes
+tabw_i 750,947,gixdb_pitchnotes
+tabw_i 756,948,gixdb_pitchnotes
+tabw_i 765,949,gixdb_pitchnotes
+tabw_i 771,950,gixdb_pitchnotes
+tabw_i 793,951,gixdb_pitchnotes
+tabw_i 808,952,gixdb_pitchnotes
+tabw_i 741,953,gixdb_pitchnotes
+tabw_i 744,954,gixdb_pitchnotes
+tabw_i 750,955,gixdb_pitchnotes
+tabw_i 756,956,gixdb_pitchnotes
+tabw_i 771,957,gixdb_pitchnotes
+tabw_i 741,958,gixdb_pitchnotes
+tabw_i 744,959,gixdb_pitchnotes
+tabw_i 750,960,gixdb_pitchnotes
+tabw_i 756,961,gixdb_pitchnotes
+tabw_i 757,962,gixdb_pitchnotes
+tabw_i 766,963,gixdb_pitchnotes
+tabw_i 771,964,gixdb_pitchnotes
+tabw_i 773,965,gixdb_pitchnotes
+tabw_i 782,966,gixdb_pitchnotes
+tabw_i 805,967,gixdb_pitchnotes
+tabw_i 757,968,gixdb_pitchnotes
+tabw_i 766,969,gixdb_pitchnotes
+tabw_i 773,970,gixdb_pitchnotes
+tabw_i 782,971,gixdb_pitchnotes
+tabw_i 805,972,gixdb_pitchnotes
+tabw_i 768,973,gixdb_pitchnotes
+tabw_i 780,974,gixdb_pitchnotes
+tabw_i 784,975,gixdb_pitchnotes
+tabw_i 791,976,gixdb_pitchnotes
+tabw_i 751,977,gixdb_pitchnotes
+tabw_i 761,978,gixdb_pitchnotes
+tabw_i 768,979,gixdb_pitchnotes
+tabw_i 780,980,gixdb_pitchnotes
+tabw_i 784,981,gixdb_pitchnotes
+tabw_i 787,982,gixdb_pitchnotes
+tabw_i 791,983,gixdb_pitchnotes
+tabw_i 801,984,gixdb_pitchnotes
+tabw_i 751,985,gixdb_pitchnotes
+tabw_i 761,986,gixdb_pitchnotes
+tabw_i 787,987,gixdb_pitchnotes
+tabw_i 801,988,gixdb_pitchnotes
+tabw_i 740,989,gixdb_pitchnotes
+tabw_i 751,990,gixdb_pitchnotes
+tabw_i 761,991,gixdb_pitchnotes
+tabw_i 787,992,gixdb_pitchnotes
+tabw_i 789,993,gixdb_pitchnotes
+tabw_i 798,994,gixdb_pitchnotes
+tabw_i 801,995,gixdb_pitchnotes
+tabw_i 802,996,gixdb_pitchnotes
+tabw_i 740,997,gixdb_pitchnotes
+tabw_i 789,998,gixdb_pitchnotes
+tabw_i 798,999,gixdb_pitchnotes
+tabw_i 802,1000,gixdb_pitchnotes
+tabw_i 739,1001,gixdb_pitchnotes
+tabw_i 752,1002,gixdb_pitchnotes
+tabw_i 788,1003,gixdb_pitchnotes
+tabw_i 790,1004,gixdb_pitchnotes
+tabw_i 795,1005,gixdb_pitchnotes
+tabw_i 739,1006,gixdb_pitchnotes
+tabw_i 752,1007,gixdb_pitchnotes
+tabw_i 758,1008,gixdb_pitchnotes
+tabw_i 770,1009,gixdb_pitchnotes
+tabw_i 788,1010,gixdb_pitchnotes
+tabw_i 790,1011,gixdb_pitchnotes
+tabw_i 795,1012,gixdb_pitchnotes
+tabw_i 799,1013,gixdb_pitchnotes
+tabw_i 810,1014,gixdb_pitchnotes
+tabw_i 758,1015,gixdb_pitchnotes
+tabw_i 770,1016,gixdb_pitchnotes
+tabw_i 799,1017,gixdb_pitchnotes
+tabw_i 810,1018,gixdb_pitchnotes
+tabw_i 758,1019,gixdb_pitchnotes
+tabw_i 767,1020,gixdb_pitchnotes
+tabw_i 769,1021,gixdb_pitchnotes
+tabw_i 770,1022,gixdb_pitchnotes
+tabw_i 775,1023,gixdb_pitchnotes
+tabw_i 776,1024,gixdb_pitchnotes
+tabw_i 794,1025,gixdb_pitchnotes
+tabw_i 799,1026,gixdb_pitchnotes
+tabw_i 810,1027,gixdb_pitchnotes
+tabw_i 767,1028,gixdb_pitchnotes
+tabw_i 769,1029,gixdb_pitchnotes
+tabw_i 775,1030,gixdb_pitchnotes
+tabw_i 776,1031,gixdb_pitchnotes
+tabw_i 794,1032,gixdb_pitchnotes
+tabw_i 760,1033,gixdb_pitchnotes
+tabw_i 762,1034,gixdb_pitchnotes
+tabw_i 763,1035,gixdb_pitchnotes
+tabw_i 767,1036,gixdb_pitchnotes
+tabw_i 769,1037,gixdb_pitchnotes
+tabw_i 775,1038,gixdb_pitchnotes
+tabw_i 776,1039,gixdb_pitchnotes
+tabw_i 785,1040,gixdb_pitchnotes
+tabw_i 794,1041,gixdb_pitchnotes
+tabw_i 800,1042,gixdb_pitchnotes
+tabw_i 760,1043,gixdb_pitchnotes
+tabw_i 762,1044,gixdb_pitchnotes
+tabw_i 763,1045,gixdb_pitchnotes
+tabw_i 785,1046,gixdb_pitchnotes
+tabw_i 800,1047,gixdb_pitchnotes
+tabw_i 779,1048,gixdb_pitchnotes
+tabw_i 804,1049,gixdb_pitchnotes
+tabw_i 807,1050,gixdb_pitchnotes
+tabw_i 811,1051,gixdb_pitchnotes
+tabw_i 755,1052,gixdb_pitchnotes
+tabw_i 764,1053,gixdb_pitchnotes
+tabw_i 779,1054,gixdb_pitchnotes
+tabw_i 783,1055,gixdb_pitchnotes
+tabw_i 804,1056,gixdb_pitchnotes
+tabw_i 807,1057,gixdb_pitchnotes
+tabw_i 809,1058,gixdb_pitchnotes
+tabw_i 811,1059,gixdb_pitchnotes
+tabw_i 755,1060,gixdb_pitchnotes
+tabw_i 764,1061,gixdb_pitchnotes
+tabw_i 783,1062,gixdb_pitchnotes
+tabw_i 809,1063,gixdb_pitchnotes
+tabw_i 753,1064,gixdb_pitchnotes
+tabw_i 755,1065,gixdb_pitchnotes
+tabw_i 764,1066,gixdb_pitchnotes
+tabw_i 783,1067,gixdb_pitchnotes
+tabw_i 792,1068,gixdb_pitchnotes
+tabw_i 796,1069,gixdb_pitchnotes
+tabw_i 809,1070,gixdb_pitchnotes
+tabw_i 753,1071,gixdb_pitchnotes
+tabw_i 792,1072,gixdb_pitchnotes
+tabw_i 796,1073,gixdb_pitchnotes
+tabw_i 753,1074,gixdb_pitchnotes
+tabw_i 792,1075,gixdb_pitchnotes
+tabw_i 796,1076,gixdb_pitchnotes
+tabw_i 753,1077,gixdb_pitchnotes
+tabw_i 792,1078,gixdb_pitchnotes
+tabw_i 796,1079,gixdb_pitchnotes
+tabw_i 753,1080,gixdb_pitchnotes
+tabw_i 792,1081,gixdb_pitchnotes
+tabw_i 796,1082,gixdb_pitchnotes
+tabw_i 753,1083,gixdb_pitchnotes
+tabw_i 792,1084,gixdb_pitchnotes
+tabw_i 796,1085,gixdb_pitchnotes
+tabw_i 753,1086,gixdb_pitchnotes
+tabw_i 792,1087,gixdb_pitchnotes
+tabw_i 796,1088,gixdb_pitchnotes
+tabw_i 753,1089,gixdb_pitchnotes
+tabw_i 792,1090,gixdb_pitchnotes
+tabw_i 796,1091,gixdb_pitchnotes
+tabw_i 753,1092,gixdb_pitchnotes
+tabw_i 792,1093,gixdb_pitchnotes
+tabw_i 796,1094,gixdb_pitchnotes
+tabw_i 753,1095,gixdb_pitchnotes
+tabw_i 792,1096,gixdb_pitchnotes
+tabw_i 796,1097,gixdb_pitchnotes
+tabw_i 753,1098,gixdb_pitchnotes
+tabw_i 792,1099,gixdb_pitchnotes
+tabw_i 796,1100,gixdb_pitchnotes
+tabw_i 753,1101,gixdb_pitchnotes
+tabw_i 792,1102,gixdb_pitchnotes
+tabw_i 796,1103,gixdb_pitchnotes
+tabw_i 753,1104,gixdb_pitchnotes
+tabw_i 792,1105,gixdb_pitchnotes
+tabw_i 796,1106,gixdb_pitchnotes
+tabw_i 753,1107,gixdb_pitchnotes
+tabw_i 792,1108,gixdb_pitchnotes
+tabw_i 796,1109,gixdb_pitchnotes
+tabw_i 753,1110,gixdb_pitchnotes
+tabw_i 792,1111,gixdb_pitchnotes
+tabw_i 796,1112,gixdb_pitchnotes
+tabw_i 753,1113,gixdb_pitchnotes
+tabw_i 792,1114,gixdb_pitchnotes
+tabw_i 796,1115,gixdb_pitchnotes
+tabw_i 753,1116,gixdb_pitchnotes
+tabw_i 792,1117,gixdb_pitchnotes
+tabw_i 796,1118,gixdb_pitchnotes
+tabw_i 753,1119,gixdb_pitchnotes
+tabw_i 792,1120,gixdb_pitchnotes
+tabw_i 796,1121,gixdb_pitchnotes
+tabw_i 753,1122,gixdb_pitchnotes
+tabw_i 792,1123,gixdb_pitchnotes
+tabw_i 796,1124,gixdb_pitchnotes
+tabw_i 753,1125,gixdb_pitchnotes
+tabw_i 792,1126,gixdb_pitchnotes
+tabw_i 796,1127,gixdb_pitchnotes
+tabw_i 753,1128,gixdb_pitchnotes
+tabw_i 792,1129,gixdb_pitchnotes
+tabw_i 796,1130,gixdb_pitchnotes
+tabw_i 753,1131,gixdb_pitchnotes
+tabw_i 792,1132,gixdb_pitchnotes
+tabw_i 796,1133,gixdb_pitchnotes
+tabw_i 753,1134,gixdb_pitchnotes
+tabw_i 792,1135,gixdb_pitchnotes
+tabw_i 796,1136,gixdb_pitchnotes
+tabw_i 753,1137,gixdb_pitchnotes
+tabw_i 792,1138,gixdb_pitchnotes
+tabw_i 796,1139,gixdb_pitchnotes
+tabw_i 753,1140,gixdb_pitchnotes
+tabw_i 792,1141,gixdb_pitchnotes
+tabw_i 796,1142,gixdb_pitchnotes
+tabw_i 753,1143,gixdb_pitchnotes
+tabw_i 792,1144,gixdb_pitchnotes
+tabw_i 796,1145,gixdb_pitchnotes
+tabw_i 753,1146,gixdb_pitchnotes
+tabw_i 792,1147,gixdb_pitchnotes
+tabw_i 796,1148,gixdb_pitchnotes
+tabw_i 753,1149,gixdb_pitchnotes
+tabw_i 792,1150,gixdb_pitchnotes
+tabw_i 796,1151,gixdb_pitchnotes
+tabw_i 753,1152,gixdb_pitchnotes
+tabw_i 792,1153,gixdb_pitchnotes
+tabw_i 796,1154,gixdb_pitchnotes
+tabw_i 753,1155,gixdb_pitchnotes
+tabw_i 792,1156,gixdb_pitchnotes
+tabw_i 796,1157,gixdb_pitchnotes
+tabw_i 753,1158,gixdb_pitchnotes
+tabw_i 792,1159,gixdb_pitchnotes
+tabw_i 796,1160,gixdb_pitchnotes
+tabw_i 753,1161,gixdb_pitchnotes
+tabw_i 792,1162,gixdb_pitchnotes
+tabw_i 796,1163,gixdb_pitchnotes
+tabw_i 753,1164,gixdb_pitchnotes
+tabw_i 792,1165,gixdb_pitchnotes
+tabw_i 796,1166,gixdb_pitchnotes
+tabw_i 753,1167,gixdb_pitchnotes
+tabw_i 792,1168,gixdb_pitchnotes
+tabw_i 796,1169,gixdb_pitchnotes
+tabw_i 753,1170,gixdb_pitchnotes
+tabw_i 792,1171,gixdb_pitchnotes
+tabw_i 796,1172,gixdb_pitchnotes
+tabw_i 753,1173,gixdb_pitchnotes
+tabw_i 792,1174,gixdb_pitchnotes
+tabw_i 796,1175,gixdb_pitchnotes
+tabw_i 753,1176,gixdb_pitchnotes
+tabw_i 792,1177,gixdb_pitchnotes
+tabw_i 796,1178,gixdb_pitchnotes
+tabw_i 753,1179,gixdb_pitchnotes
+tabw_i 792,1180,gixdb_pitchnotes
+tabw_i 796,1181,gixdb_pitchnotes
+tabw_i 753,1182,gixdb_pitchnotes
+tabw_i 792,1183,gixdb_pitchnotes
+tabw_i 796,1184,gixdb_pitchnotes
+tabw_i 753,1185,gixdb_pitchnotes
+tabw_i 792,1186,gixdb_pitchnotes
+tabw_i 796,1187,gixdb_pitchnotes
+tabw_i 753,1188,gixdb_pitchnotes
+tabw_i 792,1189,gixdb_pitchnotes
+tabw_i 796,1190,gixdb_pitchnotes
+tabw_i 0.019686269,0,gixdb_pitchadjust
+tabw_i 0.019686269,1,gixdb_pitchadjust
+tabw_i 0.019686269,2,gixdb_pitchadjust
+tabw_i 0.019686269,3,gixdb_pitchadjust
+tabw_i 0.019686269,4,gixdb_pitchadjust
+tabw_i 0.019686269,5,gixdb_pitchadjust
+tabw_i 0.020856872,6,gixdb_pitchadjust
+tabw_i 0.020856872,7,gixdb_pitchadjust
+tabw_i 0.020856872,8,gixdb_pitchadjust
+tabw_i 0.020856872,9,gixdb_pitchadjust
+tabw_i 0.020856872,10,gixdb_pitchadjust
+tabw_i 0.020856872,11,gixdb_pitchadjust
+tabw_i 0.022097087,12,gixdb_pitchadjust
+tabw_i 0.022097087,13,gixdb_pitchadjust
+tabw_i 0.022097087,14,gixdb_pitchadjust
+tabw_i 0.022097087,15,gixdb_pitchadjust
+tabw_i 0.022097087,16,gixdb_pitchadjust
+tabw_i 0.022097087,17,gixdb_pitchadjust
+tabw_i 0.023411049,18,gixdb_pitchadjust
+tabw_i 0.023411049,19,gixdb_pitchadjust
+tabw_i 0.023411049,20,gixdb_pitchadjust
+tabw_i 0.023411049,21,gixdb_pitchadjust
+tabw_i 0.023411049,22,gixdb_pitchadjust
+tabw_i 0.023411049,23,gixdb_pitchadjust
+tabw_i 0.024803143,24,gixdb_pitchadjust
+tabw_i 0.024803143,25,gixdb_pitchadjust
+tabw_i 0.024803143,26,gixdb_pitchadjust
+tabw_i 0.024803143,27,gixdb_pitchadjust
+tabw_i 0.024803143,28,gixdb_pitchadjust
+tabw_i 0.024803143,29,gixdb_pitchadjust
+tabw_i 0.026278015,30,gixdb_pitchadjust
+tabw_i 0.026278015,31,gixdb_pitchadjust
+tabw_i 0.026278015,32,gixdb_pitchadjust
+tabw_i 0.026278015,33,gixdb_pitchadjust
+tabw_i 0.026278015,34,gixdb_pitchadjust
+tabw_i 0.026278015,35,gixdb_pitchadjust
+tabw_i 0.027840585,36,gixdb_pitchadjust
+tabw_i 0.027840585,37,gixdb_pitchadjust
+tabw_i 0.027840585,38,gixdb_pitchadjust
+tabw_i 0.027840585,39,gixdb_pitchadjust
+tabw_i 0.027840585,40,gixdb_pitchadjust
+tabw_i 0.027840585,41,gixdb_pitchadjust
+tabw_i 0.029496072,42,gixdb_pitchadjust
+tabw_i 0.029496072,43,gixdb_pitchadjust
+tabw_i 0.029496072,44,gixdb_pitchadjust
+tabw_i 0.029496072,45,gixdb_pitchadjust
+tabw_i 0.029496072,46,gixdb_pitchadjust
+tabw_i 0.029496072,47,gixdb_pitchadjust
+tabw_i 0.03125,48,gixdb_pitchadjust
+tabw_i 0.03125,49,gixdb_pitchadjust
+tabw_i 0.03125,50,gixdb_pitchadjust
+tabw_i 0.03125,51,gixdb_pitchadjust
+tabw_i 0.03125,52,gixdb_pitchadjust
+tabw_i 0.03125,53,gixdb_pitchadjust
+tabw_i 0.033108223,54,gixdb_pitchadjust
+tabw_i 0.033108223,55,gixdb_pitchadjust
+tabw_i 0.033108223,56,gixdb_pitchadjust
+tabw_i 0.033108223,57,gixdb_pitchadjust
+tabw_i 0.033108223,58,gixdb_pitchadjust
+tabw_i 0.033108223,59,gixdb_pitchadjust
+tabw_i 0.03507694,60,gixdb_pitchadjust
+tabw_i 0.03507694,61,gixdb_pitchadjust
+tabw_i 0.03507694,62,gixdb_pitchadjust
+tabw_i 0.03507694,63,gixdb_pitchadjust
+tabw_i 0.03507694,64,gixdb_pitchadjust
+tabw_i 0.03507694,65,gixdb_pitchadjust
+tabw_i 0.037162725,66,gixdb_pitchadjust
+tabw_i 0.037162725,67,gixdb_pitchadjust
+tabw_i 0.037162725,68,gixdb_pitchadjust
+tabw_i 0.037162725,69,gixdb_pitchadjust
+tabw_i 0.037162725,70,gixdb_pitchadjust
+tabw_i 0.037162725,71,gixdb_pitchadjust
+tabw_i 0.039372537,72,gixdb_pitchadjust
+tabw_i 0.039372537,73,gixdb_pitchadjust
+tabw_i 0.039372537,74,gixdb_pitchadjust
+tabw_i 0.039372537,75,gixdb_pitchadjust
+tabw_i 0.039372537,76,gixdb_pitchadjust
+tabw_i 0.039372537,77,gixdb_pitchadjust
+tabw_i 0.041713744,78,gixdb_pitchadjust
+tabw_i 0.041713744,79,gixdb_pitchadjust
+tabw_i 0.041713744,80,gixdb_pitchadjust
+tabw_i 0.041713744,81,gixdb_pitchadjust
+tabw_i 0.041713744,82,gixdb_pitchadjust
+tabw_i 0.041713744,83,gixdb_pitchadjust
+tabw_i 0.044194173,84,gixdb_pitchadjust
+tabw_i 0.044194173,85,gixdb_pitchadjust
+tabw_i 0.044194173,86,gixdb_pitchadjust
+tabw_i 0.044194173,87,gixdb_pitchadjust
+tabw_i 0.044194173,88,gixdb_pitchadjust
+tabw_i 0.044194173,89,gixdb_pitchadjust
+tabw_i 0.046822097,90,gixdb_pitchadjust
+tabw_i 0.046822097,91,gixdb_pitchadjust
+tabw_i 0.046822097,92,gixdb_pitchadjust
+tabw_i 0.046822097,93,gixdb_pitchadjust
+tabw_i 0.046822097,94,gixdb_pitchadjust
+tabw_i 0.046822097,95,gixdb_pitchadjust
+tabw_i 0.049606286,96,gixdb_pitchadjust
+tabw_i 0.049606286,97,gixdb_pitchadjust
+tabw_i 0.049606286,98,gixdb_pitchadjust
+tabw_i 0.049606286,99,gixdb_pitchadjust
+tabw_i 0.049606286,100,gixdb_pitchadjust
+tabw_i 0.049606286,101,gixdb_pitchadjust
+tabw_i 0.05255603,102,gixdb_pitchadjust
+tabw_i 0.05255603,103,gixdb_pitchadjust
+tabw_i 0.05255603,104,gixdb_pitchadjust
+tabw_i 0.05255603,105,gixdb_pitchadjust
+tabw_i 0.05255603,106,gixdb_pitchadjust
+tabw_i 0.05255603,107,gixdb_pitchadjust
+tabw_i 0.05568117,108,gixdb_pitchadjust
+tabw_i 0.05568117,109,gixdb_pitchadjust
+tabw_i 0.05568117,110,gixdb_pitchadjust
+tabw_i 0.05568117,111,gixdb_pitchadjust
+tabw_i 0.05568117,112,gixdb_pitchadjust
+tabw_i 0.05568117,113,gixdb_pitchadjust
+tabw_i 0.058992144,114,gixdb_pitchadjust
+tabw_i 0.058992144,115,gixdb_pitchadjust
+tabw_i 0.058992144,116,gixdb_pitchadjust
+tabw_i 0.058992144,117,gixdb_pitchadjust
+tabw_i 0.058992144,118,gixdb_pitchadjust
+tabw_i 0.058992144,119,gixdb_pitchadjust
+tabw_i 0.0625,120,gixdb_pitchadjust
+tabw_i 0.0625,121,gixdb_pitchadjust
+tabw_i 0.0625,122,gixdb_pitchadjust
+tabw_i 0.0625,123,gixdb_pitchadjust
+tabw_i 0.0625,124,gixdb_pitchadjust
+tabw_i 0.0625,125,gixdb_pitchadjust
+tabw_i 0.06621645,126,gixdb_pitchadjust
+tabw_i 0.06621645,127,gixdb_pitchadjust
+tabw_i 0.06621645,128,gixdb_pitchadjust
+tabw_i 0.06621645,129,gixdb_pitchadjust
+tabw_i 0.06621645,130,gixdb_pitchadjust
+tabw_i 0.06621645,131,gixdb_pitchadjust
+tabw_i 0.07015388,132,gixdb_pitchadjust
+tabw_i 0.07015388,133,gixdb_pitchadjust
+tabw_i 0.07015388,134,gixdb_pitchadjust
+tabw_i 0.07015388,135,gixdb_pitchadjust
+tabw_i 0.07015388,136,gixdb_pitchadjust
+tabw_i 0.07015388,137,gixdb_pitchadjust
+tabw_i 0.07432545,138,gixdb_pitchadjust
+tabw_i 0.07432545,139,gixdb_pitchadjust
+tabw_i 0.07432545,140,gixdb_pitchadjust
+tabw_i 0.07432545,141,gixdb_pitchadjust
+tabw_i 0.07432545,142,gixdb_pitchadjust
+tabw_i 0.07432545,143,gixdb_pitchadjust
+tabw_i 0.078745075,144,gixdb_pitchadjust
+tabw_i 0.078745075,145,gixdb_pitchadjust
+tabw_i 0.078745075,146,gixdb_pitchadjust
+tabw_i 0.078745075,147,gixdb_pitchadjust
+tabw_i 0.078745075,148,gixdb_pitchadjust
+tabw_i 0.078745075,149,gixdb_pitchadjust
+tabw_i 0.08342749,150,gixdb_pitchadjust
+tabw_i 0.08342749,151,gixdb_pitchadjust
+tabw_i 0.08342749,152,gixdb_pitchadjust
+tabw_i 0.08342749,153,gixdb_pitchadjust
+tabw_i 0.08342749,154,gixdb_pitchadjust
+tabw_i 0.08342749,155,gixdb_pitchadjust
+tabw_i 0.088388346,156,gixdb_pitchadjust
+tabw_i 0.088388346,157,gixdb_pitchadjust
+tabw_i 0.088388346,158,gixdb_pitchadjust
+tabw_i 0.088388346,159,gixdb_pitchadjust
+tabw_i 0.088388346,160,gixdb_pitchadjust
+tabw_i 0.088388346,161,gixdb_pitchadjust
+tabw_i 0.093644194,162,gixdb_pitchadjust
+tabw_i 0.093644194,163,gixdb_pitchadjust
+tabw_i 0.093644194,164,gixdb_pitchadjust
+tabw_i 0.093644194,165,gixdb_pitchadjust
+tabw_i 0.093644194,166,gixdb_pitchadjust
+tabw_i 0.093644194,167,gixdb_pitchadjust
+tabw_i 0.09921257,168,gixdb_pitchadjust
+tabw_i 0.09921257,169,gixdb_pitchadjust
+tabw_i 0.09921257,170,gixdb_pitchadjust
+tabw_i 0.09921257,171,gixdb_pitchadjust
+tabw_i 0.09921257,172,gixdb_pitchadjust
+tabw_i 0.09921257,173,gixdb_pitchadjust
+tabw_i 0.10511206,174,gixdb_pitchadjust
+tabw_i 0.10511206,175,gixdb_pitchadjust
+tabw_i 0.10511206,176,gixdb_pitchadjust
+tabw_i 0.10511206,177,gixdb_pitchadjust
+tabw_i 0.10511206,178,gixdb_pitchadjust
+tabw_i 0.10511206,179,gixdb_pitchadjust
+tabw_i 0.11136234,180,gixdb_pitchadjust
+tabw_i 0.11136234,181,gixdb_pitchadjust
+tabw_i 0.11136234,182,gixdb_pitchadjust
+tabw_i 0.11136234,183,gixdb_pitchadjust
+tabw_i 0.11136234,184,gixdb_pitchadjust
+tabw_i 0.11136234,185,gixdb_pitchadjust
+tabw_i 0.11798429,186,gixdb_pitchadjust
+tabw_i 0.11798429,187,gixdb_pitchadjust
+tabw_i 0.11798429,188,gixdb_pitchadjust
+tabw_i 0.11798429,189,gixdb_pitchadjust
+tabw_i 0.11798429,190,gixdb_pitchadjust
+tabw_i 0.11798429,191,gixdb_pitchadjust
+tabw_i 0.125,192,gixdb_pitchadjust
+tabw_i 0.125,193,gixdb_pitchadjust
+tabw_i 0.125,194,gixdb_pitchadjust
+tabw_i 0.125,195,gixdb_pitchadjust
+tabw_i 0.125,196,gixdb_pitchadjust
+tabw_i 0.125,197,gixdb_pitchadjust
+tabw_i 0.1324329,198,gixdb_pitchadjust
+tabw_i 0.1324329,199,gixdb_pitchadjust
+tabw_i 0.1324329,200,gixdb_pitchadjust
+tabw_i 0.1324329,201,gixdb_pitchadjust
+tabw_i 0.1324329,202,gixdb_pitchadjust
+tabw_i 0.1324329,203,gixdb_pitchadjust
+tabw_i 0.14030775,204,gixdb_pitchadjust
+tabw_i 0.14030775,205,gixdb_pitchadjust
+tabw_i 0.14030775,206,gixdb_pitchadjust
+tabw_i 0.14030775,207,gixdb_pitchadjust
+tabw_i 0.14030775,208,gixdb_pitchadjust
+tabw_i 0.14030775,209,gixdb_pitchadjust
+tabw_i 0.1486509,210,gixdb_pitchadjust
+tabw_i 0.1486509,211,gixdb_pitchadjust
+tabw_i 0.1486509,212,gixdb_pitchadjust
+tabw_i 0.1486509,213,gixdb_pitchadjust
+tabw_i 0.1486509,214,gixdb_pitchadjust
+tabw_i 0.1486509,215,gixdb_pitchadjust
+tabw_i 0.15749015,216,gixdb_pitchadjust
+tabw_i 0.15749015,217,gixdb_pitchadjust
+tabw_i 0.15749015,218,gixdb_pitchadjust
+tabw_i 0.15749015,219,gixdb_pitchadjust
+tabw_i 0.15749015,220,gixdb_pitchadjust
+tabw_i 0.15749015,221,gixdb_pitchadjust
+tabw_i 0.16685498,222,gixdb_pitchadjust
+tabw_i 0.16685498,223,gixdb_pitchadjust
+tabw_i 0.16685498,224,gixdb_pitchadjust
+tabw_i 0.16685498,225,gixdb_pitchadjust
+tabw_i 0.16685498,226,gixdb_pitchadjust
+tabw_i 0.16685498,227,gixdb_pitchadjust
+tabw_i 0.17677669,228,gixdb_pitchadjust
+tabw_i 0.17677669,229,gixdb_pitchadjust
+tabw_i 0.17677669,230,gixdb_pitchadjust
+tabw_i 0.17677669,231,gixdb_pitchadjust
+tabw_i 0.17677669,232,gixdb_pitchadjust
+tabw_i 0.17677669,233,gixdb_pitchadjust
+tabw_i 0.18728839,234,gixdb_pitchadjust
+tabw_i 0.18728839,235,gixdb_pitchadjust
+tabw_i 0.18728839,236,gixdb_pitchadjust
+tabw_i 0.18728839,237,gixdb_pitchadjust
+tabw_i 0.18728839,238,gixdb_pitchadjust
+tabw_i 0.18728839,239,gixdb_pitchadjust
+tabw_i 0.19842514,240,gixdb_pitchadjust
+tabw_i 0.19842514,241,gixdb_pitchadjust
+tabw_i 0.19842514,242,gixdb_pitchadjust
+tabw_i 0.19842514,243,gixdb_pitchadjust
+tabw_i 0.19842514,244,gixdb_pitchadjust
+tabw_i 0.19842514,245,gixdb_pitchadjust
+tabw_i 0.21022412,246,gixdb_pitchadjust
+tabw_i 0.21022412,247,gixdb_pitchadjust
+tabw_i 0.21022412,248,gixdb_pitchadjust
+tabw_i 0.21022412,249,gixdb_pitchadjust
+tabw_i 0.21022412,250,gixdb_pitchadjust
+tabw_i 0.21022412,251,gixdb_pitchadjust
+tabw_i 0.22272468,252,gixdb_pitchadjust
+tabw_i 0.22272468,253,gixdb_pitchadjust
+tabw_i 0.22272468,254,gixdb_pitchadjust
+tabw_i 0.22272468,255,gixdb_pitchadjust
+tabw_i 0.22272468,256,gixdb_pitchadjust
+tabw_i 0.22272468,257,gixdb_pitchadjust
+tabw_i 0.23596857,258,gixdb_pitchadjust
+tabw_i 0.23596857,259,gixdb_pitchadjust
+tabw_i 0.23596857,260,gixdb_pitchadjust
+tabw_i 0.23596857,261,gixdb_pitchadjust
+tabw_i 0.23596857,262,gixdb_pitchadjust
+tabw_i 0.23596857,263,gixdb_pitchadjust
+tabw_i 0.25,264,gixdb_pitchadjust
+tabw_i 0.25,265,gixdb_pitchadjust
+tabw_i 0.25,266,gixdb_pitchadjust
+tabw_i 0.25,267,gixdb_pitchadjust
+tabw_i 0.25,268,gixdb_pitchadjust
+tabw_i 0.25,269,gixdb_pitchadjust
+tabw_i 0.2648658,270,gixdb_pitchadjust
+tabw_i 0.2648658,271,gixdb_pitchadjust
+tabw_i 0.2648658,272,gixdb_pitchadjust
+tabw_i 0.2648658,273,gixdb_pitchadjust
+tabw_i 0.2648658,274,gixdb_pitchadjust
+tabw_i 0.2648658,275,gixdb_pitchadjust
+tabw_i 0.2806155,276,gixdb_pitchadjust
+tabw_i 0.2806155,277,gixdb_pitchadjust
+tabw_i 0.2806155,278,gixdb_pitchadjust
+tabw_i 0.2806155,279,gixdb_pitchadjust
+tabw_i 0.2806155,280,gixdb_pitchadjust
+tabw_i 0.2806155,281,gixdb_pitchadjust
+tabw_i 0.2973018,282,gixdb_pitchadjust
+tabw_i 0.2973018,283,gixdb_pitchadjust
+tabw_i 0.2973018,284,gixdb_pitchadjust
+tabw_i 0.2973018,285,gixdb_pitchadjust
+tabw_i 0.2973018,286,gixdb_pitchadjust
+tabw_i 0.2973018,287,gixdb_pitchadjust
+tabw_i 0.3149803,288,gixdb_pitchadjust
+tabw_i 0.3149803,289,gixdb_pitchadjust
+tabw_i 0.3149803,290,gixdb_pitchadjust
+tabw_i 0.3149803,291,gixdb_pitchadjust
+tabw_i 0.3149803,292,gixdb_pitchadjust
+tabw_i 0.3149803,293,gixdb_pitchadjust
+tabw_i 0.33370996,294,gixdb_pitchadjust
+tabw_i 0.33370996,295,gixdb_pitchadjust
+tabw_i 0.33370996,296,gixdb_pitchadjust
+tabw_i 0.33370996,297,gixdb_pitchadjust
+tabw_i 0.33370996,298,gixdb_pitchadjust
+tabw_i 0.33370996,299,gixdb_pitchadjust
+tabw_i 0.35355338,300,gixdb_pitchadjust
+tabw_i 0.35355338,301,gixdb_pitchadjust
+tabw_i 0.35355338,302,gixdb_pitchadjust
+tabw_i 0.35355338,303,gixdb_pitchadjust
+tabw_i 0.35355338,304,gixdb_pitchadjust
+tabw_i 0.35355338,305,gixdb_pitchadjust
+tabw_i 0.37457678,306,gixdb_pitchadjust
+tabw_i 0.37457678,307,gixdb_pitchadjust
+tabw_i 0.37457678,308,gixdb_pitchadjust
+tabw_i 0.37457678,309,gixdb_pitchadjust
+tabw_i 0.37457678,310,gixdb_pitchadjust
+tabw_i 0.37457678,311,gixdb_pitchadjust
+tabw_i 0.3968503,312,gixdb_pitchadjust
+tabw_i 0.3968503,313,gixdb_pitchadjust
+tabw_i 0.3968503,314,gixdb_pitchadjust
+tabw_i 0.3968503,315,gixdb_pitchadjust
+tabw_i 0.3968503,316,gixdb_pitchadjust
+tabw_i 0.3968503,317,gixdb_pitchadjust
+tabw_i 0.42044824,318,gixdb_pitchadjust
+tabw_i 0.42044824,319,gixdb_pitchadjust
+tabw_i 0.42044824,320,gixdb_pitchadjust
+tabw_i 0.42044824,321,gixdb_pitchadjust
+tabw_i 0.42044824,322,gixdb_pitchadjust
+tabw_i 0.42044824,323,gixdb_pitchadjust
+tabw_i 0.44544935,324,gixdb_pitchadjust
+tabw_i 0.44544935,325,gixdb_pitchadjust
+tabw_i 0.44544935,326,gixdb_pitchadjust
+tabw_i 0.44544935,327,gixdb_pitchadjust
+tabw_i 0.44544935,328,gixdb_pitchadjust
+tabw_i 0.44544935,329,gixdb_pitchadjust
+tabw_i 0.47193715,330,gixdb_pitchadjust
+tabw_i 0.47193715,331,gixdb_pitchadjust
+tabw_i 0.47193715,332,gixdb_pitchadjust
+tabw_i 0.47193715,333,gixdb_pitchadjust
+tabw_i 0.47193715,334,gixdb_pitchadjust
+tabw_i 0.47193715,335,gixdb_pitchadjust
+tabw_i 0.5,336,gixdb_pitchadjust
+tabw_i 0.5,337,gixdb_pitchadjust
+tabw_i 0.5,338,gixdb_pitchadjust
+tabw_i 0.5,339,gixdb_pitchadjust
+tabw_i 0.5,340,gixdb_pitchadjust
+tabw_i 0.5,341,gixdb_pitchadjust
+tabw_i 0.5297316,342,gixdb_pitchadjust
+tabw_i 0.5297316,343,gixdb_pitchadjust
+tabw_i 0.5297316,344,gixdb_pitchadjust
+tabw_i 0.5297316,345,gixdb_pitchadjust
+tabw_i 0.5297316,346,gixdb_pitchadjust
+tabw_i 0.5297316,347,gixdb_pitchadjust
+tabw_i 0.561231,348,gixdb_pitchadjust
+tabw_i 0.561231,349,gixdb_pitchadjust
+tabw_i 0.561231,350,gixdb_pitchadjust
+tabw_i 0.561231,351,gixdb_pitchadjust
+tabw_i 0.561231,352,gixdb_pitchadjust
+tabw_i 0.561231,353,gixdb_pitchadjust
+tabw_i 0.5946036,354,gixdb_pitchadjust
+tabw_i 0.5946036,355,gixdb_pitchadjust
+tabw_i 0.5946036,356,gixdb_pitchadjust
+tabw_i 0.5946036,357,gixdb_pitchadjust
+tabw_i 0.5946036,358,gixdb_pitchadjust
+tabw_i 0.5946036,359,gixdb_pitchadjust
+tabw_i 0.6299606,360,gixdb_pitchadjust
+tabw_i 0.6299606,361,gixdb_pitchadjust
+tabw_i 0.6299606,362,gixdb_pitchadjust
+tabw_i 0.6299606,363,gixdb_pitchadjust
+tabw_i 0.6299606,364,gixdb_pitchadjust
+tabw_i 0.6299606,365,gixdb_pitchadjust
+tabw_i 0.6674199,366,gixdb_pitchadjust
+tabw_i 0.6674199,367,gixdb_pitchadjust
+tabw_i 0.6674199,368,gixdb_pitchadjust
+tabw_i 0.6674199,369,gixdb_pitchadjust
+tabw_i 0.6674199,370,gixdb_pitchadjust
+tabw_i 0.6674199,371,gixdb_pitchadjust
+tabw_i 0.70710677,372,gixdb_pitchadjust
+tabw_i 0.70710677,373,gixdb_pitchadjust
+tabw_i 0.70710677,374,gixdb_pitchadjust
+tabw_i 0.70710677,375,gixdb_pitchadjust
+tabw_i 0.70710677,376,gixdb_pitchadjust
+tabw_i 0.70710677,377,gixdb_pitchadjust
+tabw_i 0.74915355,378,gixdb_pitchadjust
+tabw_i 0.74915355,379,gixdb_pitchadjust
+tabw_i 0.74915355,380,gixdb_pitchadjust
+tabw_i 0.74915355,381,gixdb_pitchadjust
+tabw_i 0.74915355,382,gixdb_pitchadjust
+tabw_i 0.74915355,383,gixdb_pitchadjust
+tabw_i 0.7937006,384,gixdb_pitchadjust
+tabw_i 0.7937006,385,gixdb_pitchadjust
+tabw_i 0.7937006,386,gixdb_pitchadjust
+tabw_i 0.7937006,387,gixdb_pitchadjust
+tabw_i 0.7937006,388,gixdb_pitchadjust
+tabw_i 0.7937006,389,gixdb_pitchadjust
+tabw_i 0.8408965,390,gixdb_pitchadjust
+tabw_i 0.8408965,391,gixdb_pitchadjust
+tabw_i 0.8408965,392,gixdb_pitchadjust
+tabw_i 0.8408965,393,gixdb_pitchadjust
+tabw_i 0.8408965,394,gixdb_pitchadjust
+tabw_i 0.8408965,395,gixdb_pitchadjust
+tabw_i 0.8908987,396,gixdb_pitchadjust
+tabw_i 0.8908987,397,gixdb_pitchadjust
+tabw_i 0.8908987,398,gixdb_pitchadjust
+tabw_i 0.8908987,399,gixdb_pitchadjust
+tabw_i 0.8908987,400,gixdb_pitchadjust
+tabw_i 0.8908987,401,gixdb_pitchadjust
+tabw_i 0.9438743,402,gixdb_pitchadjust
+tabw_i 0.9438743,403,gixdb_pitchadjust
+tabw_i 0.9438743,404,gixdb_pitchadjust
+tabw_i 0.9438743,405,gixdb_pitchadjust
+tabw_i 0.9438743,406,gixdb_pitchadjust
+tabw_i 0.9438743,407,gixdb_pitchadjust
+tabw_i 1,408,gixdb_pitchadjust
+tabw_i 1,409,gixdb_pitchadjust
+tabw_i 1,410,gixdb_pitchadjust
+tabw_i 1,411,gixdb_pitchadjust
+tabw_i 1,412,gixdb_pitchadjust
+tabw_i 1,413,gixdb_pitchadjust
+tabw_i 1.0594631,414,gixdb_pitchadjust
+tabw_i 1.0594631,415,gixdb_pitchadjust
+tabw_i 1.0594631,416,gixdb_pitchadjust
+tabw_i 0.9438743,417,gixdb_pitchadjust
+tabw_i 0.9438743,418,gixdb_pitchadjust
+tabw_i 1.0594631,419,gixdb_pitchadjust
+tabw_i 0.9438743,420,gixdb_pitchadjust
+tabw_i 0.9438743,421,gixdb_pitchadjust
+tabw_i 0.9438743,422,gixdb_pitchadjust
+tabw_i 1.0594631,423,gixdb_pitchadjust
+tabw_i 1.0594631,424,gixdb_pitchadjust
+tabw_i 1,425,gixdb_pitchadjust
+tabw_i 1,426,gixdb_pitchadjust
+tabw_i 1,427,gixdb_pitchadjust
+tabw_i 1,428,gixdb_pitchadjust
+tabw_i 1,429,gixdb_pitchadjust
+tabw_i 1.0594631,430,gixdb_pitchadjust
+tabw_i 1.0594631,431,gixdb_pitchadjust
+tabw_i 0.94387424,432,gixdb_pitchadjust
+tabw_i 0.94387424,433,gixdb_pitchadjust
+tabw_i 0.94387424,434,gixdb_pitchadjust
+tabw_i 1.0594631,435,gixdb_pitchadjust
+tabw_i 0.94387424,436,gixdb_pitchadjust
+tabw_i 1.0594631,437,gixdb_pitchadjust
+tabw_i 1.0594631,438,gixdb_pitchadjust
+tabw_i 1,439,gixdb_pitchadjust
+tabw_i 1,440,gixdb_pitchadjust
+tabw_i 1,441,gixdb_pitchadjust
+tabw_i 1,442,gixdb_pitchadjust
+tabw_i 1,443,gixdb_pitchadjust
+tabw_i 1,444,gixdb_pitchadjust
+tabw_i 1,445,gixdb_pitchadjust
+tabw_i 1.0594631,446,gixdb_pitchadjust
+tabw_i 0.9438743,447,gixdb_pitchadjust
+tabw_i 0.9438743,448,gixdb_pitchadjust
+tabw_i 1.0594631,449,gixdb_pitchadjust
+tabw_i 1.0594631,450,gixdb_pitchadjust
+tabw_i 0.9438743,451,gixdb_pitchadjust
+tabw_i 1,452,gixdb_pitchadjust
+tabw_i 1,453,gixdb_pitchadjust
+tabw_i 1,454,gixdb_pitchadjust
+tabw_i 0.9438743,455,gixdb_pitchadjust
+tabw_i 1.0594631,456,gixdb_pitchadjust
+tabw_i 1.0594631,457,gixdb_pitchadjust
+tabw_i 0.9438743,458,gixdb_pitchadjust
+tabw_i 0.9438743,459,gixdb_pitchadjust
+tabw_i 0.9438743,460,gixdb_pitchadjust
+tabw_i 1.0594631,461,gixdb_pitchadjust
+tabw_i 1,462,gixdb_pitchadjust
+tabw_i 1,463,gixdb_pitchadjust
+tabw_i 1,464,gixdb_pitchadjust
+tabw_i 1,465,gixdb_pitchadjust
+tabw_i 1.059463,466,gixdb_pitchadjust
+tabw_i 1.059463,467,gixdb_pitchadjust
+tabw_i 0.9438743,468,gixdb_pitchadjust
+tabw_i 0.9438743,469,gixdb_pitchadjust
+tabw_i 1.059463,470,gixdb_pitchadjust
+tabw_i 1.059463,471,gixdb_pitchadjust
+tabw_i 0.9438743,472,gixdb_pitchadjust
+tabw_i 0.9438743,473,gixdb_pitchadjust
+tabw_i 1,474,gixdb_pitchadjust
+tabw_i 1,475,gixdb_pitchadjust
+tabw_i 1,476,gixdb_pitchadjust
+tabw_i 1,477,gixdb_pitchadjust
+tabw_i 1,478,gixdb_pitchadjust
+tabw_i 1,479,gixdb_pitchadjust
+tabw_i 1,480,gixdb_pitchadjust
+tabw_i 1,481,gixdb_pitchadjust
+tabw_i 1.0594631,482,gixdb_pitchadjust
+tabw_i 0.9438743,483,gixdb_pitchadjust
+tabw_i 1.0594631,484,gixdb_pitchadjust
+tabw_i 0.9438743,485,gixdb_pitchadjust
+tabw_i 0.9438743,486,gixdb_pitchadjust
+tabw_i 0.9438743,487,gixdb_pitchadjust
+tabw_i 1.0594631,488,gixdb_pitchadjust
+tabw_i 1.0594631,489,gixdb_pitchadjust
+tabw_i 1,490,gixdb_pitchadjust
+tabw_i 1,491,gixdb_pitchadjust
+tabw_i 1,492,gixdb_pitchadjust
+tabw_i 1,493,gixdb_pitchadjust
+tabw_i 1.0594631,494,gixdb_pitchadjust
+tabw_i 1.0594631,495,gixdb_pitchadjust
+tabw_i 1.0594631,496,gixdb_pitchadjust
+tabw_i 0.94387424,497,gixdb_pitchadjust
+tabw_i 1.0594631,498,gixdb_pitchadjust
+tabw_i 0.94387424,499,gixdb_pitchadjust
+tabw_i 0.94387424,500,gixdb_pitchadjust
+tabw_i 0.94387424,501,gixdb_pitchadjust
+tabw_i 1,502,gixdb_pitchadjust
+tabw_i 1,503,gixdb_pitchadjust
+tabw_i 1,504,gixdb_pitchadjust
+tabw_i 1,505,gixdb_pitchadjust
+tabw_i 1,506,gixdb_pitchadjust
+tabw_i 1,507,gixdb_pitchadjust
+tabw_i 1,508,gixdb_pitchadjust
+tabw_i 1,509,gixdb_pitchadjust
+tabw_i 1.0594631,510,gixdb_pitchadjust
+tabw_i 1.0594631,511,gixdb_pitchadjust
+tabw_i 1.0594631,512,gixdb_pitchadjust
+tabw_i 0.9438743,513,gixdb_pitchadjust
+tabw_i 0.9438743,514,gixdb_pitchadjust
+tabw_i 0.9438743,515,gixdb_pitchadjust
+tabw_i 0.9438743,516,gixdb_pitchadjust
+tabw_i 0.9438743,517,gixdb_pitchadjust
+tabw_i 1.0594631,518,gixdb_pitchadjust
+tabw_i 1,519,gixdb_pitchadjust
+tabw_i 1,520,gixdb_pitchadjust
+tabw_i 1,521,gixdb_pitchadjust
+tabw_i 1,522,gixdb_pitchadjust
+tabw_i 1,523,gixdb_pitchadjust
+tabw_i 0.9438743,524,gixdb_pitchadjust
+tabw_i 1.0594631,525,gixdb_pitchadjust
+tabw_i 0.9438743,526,gixdb_pitchadjust
+tabw_i 1.0594631,527,gixdb_pitchadjust
+tabw_i 1.0594631,528,gixdb_pitchadjust
+tabw_i 1.0594631,529,gixdb_pitchadjust
+tabw_i 1.0594631,530,gixdb_pitchadjust
+tabw_i 0.9438743,531,gixdb_pitchadjust
+tabw_i 0.9438743,532,gixdb_pitchadjust
+tabw_i 1,533,gixdb_pitchadjust
+tabw_i 1,534,gixdb_pitchadjust
+tabw_i 1,535,gixdb_pitchadjust
+tabw_i 1,536,gixdb_pitchadjust
+tabw_i 1.059463,537,gixdb_pitchadjust
+tabw_i 0.9438743,538,gixdb_pitchadjust
+tabw_i 0.9438743,539,gixdb_pitchadjust
+tabw_i 1.059463,540,gixdb_pitchadjust
+tabw_i 0.9438743,541,gixdb_pitchadjust
+tabw_i 1.059463,542,gixdb_pitchadjust
+tabw_i 1.059463,543,gixdb_pitchadjust
+tabw_i 1,544,gixdb_pitchadjust
+tabw_i 1,545,gixdb_pitchadjust
+tabw_i 1,546,gixdb_pitchadjust
+tabw_i 1,547,gixdb_pitchadjust
+tabw_i 1,548,gixdb_pitchadjust
+tabw_i 1,549,gixdb_pitchadjust
+tabw_i 1.0594631,550,gixdb_pitchadjust
+tabw_i 1.0594631,551,gixdb_pitchadjust
+tabw_i 1.0594631,552,gixdb_pitchadjust
+tabw_i 1.122462,553,gixdb_pitchadjust
+tabw_i 1.122462,554,gixdb_pitchadjust
+tabw_i 1.122462,555,gixdb_pitchadjust
+tabw_i 1.1892072,556,gixdb_pitchadjust
+tabw_i 1.1892072,557,gixdb_pitchadjust
+tabw_i 1.1892072,558,gixdb_pitchadjust
+tabw_i 1.2599212,559,gixdb_pitchadjust
+tabw_i 1.2599212,560,gixdb_pitchadjust
+tabw_i 1.2599212,561,gixdb_pitchadjust
+tabw_i 1.3348398,562,gixdb_pitchadjust
+tabw_i 1.3348398,563,gixdb_pitchadjust
+tabw_i 1.3348398,564,gixdb_pitchadjust
+tabw_i 1.4142135,565,gixdb_pitchadjust
+tabw_i 1.4142135,566,gixdb_pitchadjust
+tabw_i 1.4142135,567,gixdb_pitchadjust
+tabw_i 1.4983071,568,gixdb_pitchadjust
+tabw_i 1.4983071,569,gixdb_pitchadjust
+tabw_i 1.4983071,570,gixdb_pitchadjust
+tabw_i 1.5874012,571,gixdb_pitchadjust
+tabw_i 1.5874012,572,gixdb_pitchadjust
+tabw_i 1.5874012,573,gixdb_pitchadjust
+tabw_i 1.681793,574,gixdb_pitchadjust
+tabw_i 1.681793,575,gixdb_pitchadjust
+tabw_i 1.681793,576,gixdb_pitchadjust
+tabw_i 1.7817974,577,gixdb_pitchadjust
+tabw_i 1.7817974,578,gixdb_pitchadjust
+tabw_i 1.7817974,579,gixdb_pitchadjust
+tabw_i 1.8877486,580,gixdb_pitchadjust
+tabw_i 1.8877486,581,gixdb_pitchadjust
+tabw_i 1.8877486,582,gixdb_pitchadjust
+tabw_i 2,583,gixdb_pitchadjust
+tabw_i 2,584,gixdb_pitchadjust
+tabw_i 2,585,gixdb_pitchadjust
+tabw_i 2.1189263,586,gixdb_pitchadjust
+tabw_i 2.1189263,587,gixdb_pitchadjust
+tabw_i 2.1189263,588,gixdb_pitchadjust
+tabw_i 2.244924,589,gixdb_pitchadjust
+tabw_i 2.244924,590,gixdb_pitchadjust
+tabw_i 2.244924,591,gixdb_pitchadjust
+tabw_i 2.3784144,592,gixdb_pitchadjust
+tabw_i 2.3784144,593,gixdb_pitchadjust
+tabw_i 2.3784144,594,gixdb_pitchadjust
+tabw_i 2.5198424,595,gixdb_pitchadjust
+tabw_i 2.5198424,596,gixdb_pitchadjust
+tabw_i 2.5198424,597,gixdb_pitchadjust
+tabw_i 2.6696796,598,gixdb_pitchadjust
+tabw_i 2.6696796,599,gixdb_pitchadjust
+tabw_i 2.6696796,600,gixdb_pitchadjust
+tabw_i 2.828427,601,gixdb_pitchadjust
+tabw_i 2.828427,602,gixdb_pitchadjust
+tabw_i 2.828427,603,gixdb_pitchadjust
+tabw_i 2.9966142,604,gixdb_pitchadjust
+tabw_i 2.9966142,605,gixdb_pitchadjust
+tabw_i 2.9966142,606,gixdb_pitchadjust
+tabw_i 3.1748023,607,gixdb_pitchadjust
+tabw_i 3.1748023,608,gixdb_pitchadjust
+tabw_i 3.1748023,609,gixdb_pitchadjust
+tabw_i 3.363586,610,gixdb_pitchadjust
+tabw_i 3.363586,611,gixdb_pitchadjust
+tabw_i 3.363586,612,gixdb_pitchadjust
+tabw_i 3.5635948,613,gixdb_pitchadjust
+tabw_i 3.5635948,614,gixdb_pitchadjust
+tabw_i 3.5635948,615,gixdb_pitchadjust
+tabw_i 3.7754972,616,gixdb_pitchadjust
+tabw_i 3.7754972,617,gixdb_pitchadjust
+tabw_i 3.7754972,618,gixdb_pitchadjust
+tabw_i 4,619,gixdb_pitchadjust
+tabw_i 4,620,gixdb_pitchadjust
+tabw_i 4,621,gixdb_pitchadjust
+tabw_i 4.2378526,622,gixdb_pitchadjust
+tabw_i 4.2378526,623,gixdb_pitchadjust
+tabw_i 4.2378526,624,gixdb_pitchadjust
+tabw_i 4.489848,625,gixdb_pitchadjust
+tabw_i 4.489848,626,gixdb_pitchadjust
+tabw_i 4.489848,627,gixdb_pitchadjust
+tabw_i 4.756829,628,gixdb_pitchadjust
+tabw_i 4.756829,629,gixdb_pitchadjust
+tabw_i 4.756829,630,gixdb_pitchadjust
+tabw_i 5.039685,631,gixdb_pitchadjust
+tabw_i 5.039685,632,gixdb_pitchadjust
+tabw_i 5.039685,633,gixdb_pitchadjust
+tabw_i 5.3393593,634,gixdb_pitchadjust
+tabw_i 5.3393593,635,gixdb_pitchadjust
+tabw_i 5.3393593,636,gixdb_pitchadjust
+tabw_i 5.656854,637,gixdb_pitchadjust
+tabw_i 5.656854,638,gixdb_pitchadjust
+tabw_i 5.656854,639,gixdb_pitchadjust
+tabw_i 5.9932284,640,gixdb_pitchadjust
+tabw_i 5.9932284,641,gixdb_pitchadjust
+tabw_i 5.9932284,642,gixdb_pitchadjust
+tabw_i 6.3496046,643,gixdb_pitchadjust
+tabw_i 6.3496046,644,gixdb_pitchadjust
+tabw_i 6.3496046,645,gixdb_pitchadjust
+tabw_i 6.727172,646,gixdb_pitchadjust
+tabw_i 6.727172,647,gixdb_pitchadjust
+tabw_i 6.727172,648,gixdb_pitchadjust
+tabw_i 7.1271896,649,gixdb_pitchadjust
+tabw_i 7.1271896,650,gixdb_pitchadjust
+tabw_i 7.1271896,651,gixdb_pitchadjust
+tabw_i 7.5509944,652,gixdb_pitchadjust
+tabw_i 7.5509944,653,gixdb_pitchadjust
+tabw_i 7.5509944,654,gixdb_pitchadjust
+tabw_i 0.03125,655,gixdb_pitchadjust
+tabw_i 0.03125,656,gixdb_pitchadjust
+tabw_i 0.03125,657,gixdb_pitchadjust
+tabw_i 0.03125,658,gixdb_pitchadjust
+tabw_i 0.03310822,659,gixdb_pitchadjust
+tabw_i 0.03310822,660,gixdb_pitchadjust
+tabw_i 0.03310822,661,gixdb_pitchadjust
+tabw_i 0.03310822,662,gixdb_pitchadjust
+tabw_i 0.035076935,663,gixdb_pitchadjust
+tabw_i 0.035076935,664,gixdb_pitchadjust
+tabw_i 0.035076935,665,gixdb_pitchadjust
+tabw_i 0.035076935,666,gixdb_pitchadjust
+tabw_i 0.03716272,667,gixdb_pitchadjust
+tabw_i 0.03716272,668,gixdb_pitchadjust
+tabw_i 0.03716272,669,gixdb_pitchadjust
+tabw_i 0.03716272,670,gixdb_pitchadjust
+tabw_i 0.03937253,671,gixdb_pitchadjust
+tabw_i 0.03937253,672,gixdb_pitchadjust
+tabw_i 0.03937253,673,gixdb_pitchadjust
+tabw_i 0.03937253,674,gixdb_pitchadjust
+tabw_i 0.041713744,675,gixdb_pitchadjust
+tabw_i 0.041713744,676,gixdb_pitchadjust
+tabw_i 0.041713744,677,gixdb_pitchadjust
+tabw_i 0.041713744,678,gixdb_pitchadjust
+tabw_i 0.04419417,679,gixdb_pitchadjust
+tabw_i 0.04419417,680,gixdb_pitchadjust
+tabw_i 0.04419417,681,gixdb_pitchadjust
+tabw_i 0.04419417,682,gixdb_pitchadjust
+tabw_i 0.046822093,683,gixdb_pitchadjust
+tabw_i 0.046822093,684,gixdb_pitchadjust
+tabw_i 0.046822093,685,gixdb_pitchadjust
+tabw_i 0.046822093,686,gixdb_pitchadjust
+tabw_i 0.04960628,687,gixdb_pitchadjust
+tabw_i 0.04960628,688,gixdb_pitchadjust
+tabw_i 0.04960628,689,gixdb_pitchadjust
+tabw_i 0.04960628,690,gixdb_pitchadjust
+tabw_i 0.052556023,691,gixdb_pitchadjust
+tabw_i 0.052556023,692,gixdb_pitchadjust
+tabw_i 0.052556023,693,gixdb_pitchadjust
+tabw_i 0.052556023,694,gixdb_pitchadjust
+tabw_i 0.055681165,695,gixdb_pitchadjust
+tabw_i 0.055681165,696,gixdb_pitchadjust
+tabw_i 0.055681165,697,gixdb_pitchadjust
+tabw_i 0.055681165,698,gixdb_pitchadjust
+tabw_i 0.05899214,699,gixdb_pitchadjust
+tabw_i 0.05899214,700,gixdb_pitchadjust
+tabw_i 0.05899214,701,gixdb_pitchadjust
+tabw_i 0.05899214,702,gixdb_pitchadjust
+tabw_i 0.0625,703,gixdb_pitchadjust
+tabw_i 0.0625,704,gixdb_pitchadjust
+tabw_i 0.0625,705,gixdb_pitchadjust
+tabw_i 0.0625,706,gixdb_pitchadjust
+tabw_i 0.06621644,707,gixdb_pitchadjust
+tabw_i 0.06621644,708,gixdb_pitchadjust
+tabw_i 0.06621644,709,gixdb_pitchadjust
+tabw_i 0.06621644,710,gixdb_pitchadjust
+tabw_i 0.07015387,711,gixdb_pitchadjust
+tabw_i 0.07015387,712,gixdb_pitchadjust
+tabw_i 0.07015387,713,gixdb_pitchadjust
+tabw_i 0.07015387,714,gixdb_pitchadjust
+tabw_i 0.07432544,715,gixdb_pitchadjust
+tabw_i 0.07432544,716,gixdb_pitchadjust
+tabw_i 0.07432544,717,gixdb_pitchadjust
+tabw_i 0.07432544,718,gixdb_pitchadjust
+tabw_i 0.07874506,719,gixdb_pitchadjust
+tabw_i 0.07874506,720,gixdb_pitchadjust
+tabw_i 0.07874506,721,gixdb_pitchadjust
+tabw_i 0.07874506,722,gixdb_pitchadjust
+tabw_i 0.08342749,723,gixdb_pitchadjust
+tabw_i 0.08342749,724,gixdb_pitchadjust
+tabw_i 0.08342749,725,gixdb_pitchadjust
+tabw_i 0.08342749,726,gixdb_pitchadjust
+tabw_i 0.08838834,727,gixdb_pitchadjust
+tabw_i 0.08838834,728,gixdb_pitchadjust
+tabw_i 0.08838834,729,gixdb_pitchadjust
+tabw_i 0.08838834,730,gixdb_pitchadjust
+tabw_i 0.09364419,731,gixdb_pitchadjust
+tabw_i 0.09364419,732,gixdb_pitchadjust
+tabw_i 0.09364419,733,gixdb_pitchadjust
+tabw_i 0.09364419,734,gixdb_pitchadjust
+tabw_i 0.09921256,735,gixdb_pitchadjust
+tabw_i 0.09921256,736,gixdb_pitchadjust
+tabw_i 0.09921256,737,gixdb_pitchadjust
+tabw_i 0.09921256,738,gixdb_pitchadjust
+tabw_i 0.105112046,739,gixdb_pitchadjust
+tabw_i 0.105112046,740,gixdb_pitchadjust
+tabw_i 0.105112046,741,gixdb_pitchadjust
+tabw_i 0.105112046,742,gixdb_pitchadjust
+tabw_i 0.11136233,743,gixdb_pitchadjust
+tabw_i 0.11136233,744,gixdb_pitchadjust
+tabw_i 0.11136233,745,gixdb_pitchadjust
+tabw_i 0.11136233,746,gixdb_pitchadjust
+tabw_i 0.11798428,747,gixdb_pitchadjust
+tabw_i 0.11798428,748,gixdb_pitchadjust
+tabw_i 0.11798428,749,gixdb_pitchadjust
+tabw_i 0.11798428,750,gixdb_pitchadjust
+tabw_i 0.125,751,gixdb_pitchadjust
+tabw_i 0.125,752,gixdb_pitchadjust
+tabw_i 0.125,753,gixdb_pitchadjust
+tabw_i 0.125,754,gixdb_pitchadjust
+tabw_i 0.13243288,755,gixdb_pitchadjust
+tabw_i 0.13243288,756,gixdb_pitchadjust
+tabw_i 0.13243288,757,gixdb_pitchadjust
+tabw_i 0.13243288,758,gixdb_pitchadjust
+tabw_i 0.14030774,759,gixdb_pitchadjust
+tabw_i 0.14030774,760,gixdb_pitchadjust
+tabw_i 0.14030774,761,gixdb_pitchadjust
+tabw_i 0.14030774,762,gixdb_pitchadjust
+tabw_i 0.14865088,763,gixdb_pitchadjust
+tabw_i 0.14865088,764,gixdb_pitchadjust
+tabw_i 0.14865088,765,gixdb_pitchadjust
+tabw_i 0.14865088,766,gixdb_pitchadjust
+tabw_i 0.15749012,767,gixdb_pitchadjust
+tabw_i 0.15749012,768,gixdb_pitchadjust
+tabw_i 0.15749012,769,gixdb_pitchadjust
+tabw_i 0.15749012,770,gixdb_pitchadjust
+tabw_i 0.16685498,771,gixdb_pitchadjust
+tabw_i 0.16685498,772,gixdb_pitchadjust
+tabw_i 0.16685498,773,gixdb_pitchadjust
+tabw_i 0.16685498,774,gixdb_pitchadjust
+tabw_i 0.17677668,775,gixdb_pitchadjust
+tabw_i 0.17677668,776,gixdb_pitchadjust
+tabw_i 0.17677668,777,gixdb_pitchadjust
+tabw_i 0.17677668,778,gixdb_pitchadjust
+tabw_i 0.18728837,779,gixdb_pitchadjust
+tabw_i 0.18728837,780,gixdb_pitchadjust
+tabw_i 0.18728837,781,gixdb_pitchadjust
+tabw_i 0.18728837,782,gixdb_pitchadjust
+tabw_i 0.19842511,783,gixdb_pitchadjust
+tabw_i 0.19842511,784,gixdb_pitchadjust
+tabw_i 0.19842511,785,gixdb_pitchadjust
+tabw_i 0.19842511,786,gixdb_pitchadjust
+tabw_i 0.21022409,787,gixdb_pitchadjust
+tabw_i 0.21022409,788,gixdb_pitchadjust
+tabw_i 0.21022409,789,gixdb_pitchadjust
+tabw_i 0.21022409,790,gixdb_pitchadjust
+tabw_i 0.22272466,791,gixdb_pitchadjust
+tabw_i 0.22272466,792,gixdb_pitchadjust
+tabw_i 0.22272466,793,gixdb_pitchadjust
+tabw_i 0.22272466,794,gixdb_pitchadjust
+tabw_i 0.23596856,795,gixdb_pitchadjust
+tabw_i 0.23596856,796,gixdb_pitchadjust
+tabw_i 0.23596856,797,gixdb_pitchadjust
+tabw_i 0.23596856,798,gixdb_pitchadjust
+tabw_i 0.25,799,gixdb_pitchadjust
+tabw_i 0.25,800,gixdb_pitchadjust
+tabw_i 0.25,801,gixdb_pitchadjust
+tabw_i 0.25,802,gixdb_pitchadjust
+tabw_i 0.26486576,803,gixdb_pitchadjust
+tabw_i 0.26486576,804,gixdb_pitchadjust
+tabw_i 0.26486576,805,gixdb_pitchadjust
+tabw_i 0.26486576,806,gixdb_pitchadjust
+tabw_i 0.28061548,807,gixdb_pitchadjust
+tabw_i 0.28061548,808,gixdb_pitchadjust
+tabw_i 0.28061548,809,gixdb_pitchadjust
+tabw_i 0.28061548,810,gixdb_pitchadjust
+tabw_i 0.29730177,811,gixdb_pitchadjust
+tabw_i 0.29730177,812,gixdb_pitchadjust
+tabw_i 0.29730177,813,gixdb_pitchadjust
+tabw_i 0.29730177,814,gixdb_pitchadjust
+tabw_i 0.31498024,815,gixdb_pitchadjust
+tabw_i 0.31498024,816,gixdb_pitchadjust
+tabw_i 0.31498024,817,gixdb_pitchadjust
+tabw_i 0.31498024,818,gixdb_pitchadjust
+tabw_i 0.33370996,819,gixdb_pitchadjust
+tabw_i 0.33370996,820,gixdb_pitchadjust
+tabw_i 0.33370996,821,gixdb_pitchadjust
+tabw_i 0.33370996,822,gixdb_pitchadjust
+tabw_i 0.35355335,823,gixdb_pitchadjust
+tabw_i 0.35355335,824,gixdb_pitchadjust
+tabw_i 0.35355335,825,gixdb_pitchadjust
+tabw_i 0.35355335,826,gixdb_pitchadjust
+tabw_i 0.37457675,827,gixdb_pitchadjust
+tabw_i 0.37457675,828,gixdb_pitchadjust
+tabw_i 0.37457675,829,gixdb_pitchadjust
+tabw_i 0.37457675,830,gixdb_pitchadjust
+tabw_i 0.39685023,831,gixdb_pitchadjust
+tabw_i 0.39685023,832,gixdb_pitchadjust
+tabw_i 0.39685023,833,gixdb_pitchadjust
+tabw_i 0.39685023,834,gixdb_pitchadjust
+tabw_i 0.42044818,835,gixdb_pitchadjust
+tabw_i 0.42044818,836,gixdb_pitchadjust
+tabw_i 0.42044818,837,gixdb_pitchadjust
+tabw_i 0.42044818,838,gixdb_pitchadjust
+tabw_i 0.44544932,839,gixdb_pitchadjust
+tabw_i 0.44544932,840,gixdb_pitchadjust
+tabw_i 0.44544932,841,gixdb_pitchadjust
+tabw_i 0.44544932,842,gixdb_pitchadjust
+tabw_i 0.47193712,843,gixdb_pitchadjust
+tabw_i 0.47193712,844,gixdb_pitchadjust
+tabw_i 0.47193712,845,gixdb_pitchadjust
+tabw_i 0.47193712,846,gixdb_pitchadjust
+tabw_i 0.5,847,gixdb_pitchadjust
+tabw_i 0.5,848,gixdb_pitchadjust
+tabw_i 0.5,849,gixdb_pitchadjust
+tabw_i 0.5,850,gixdb_pitchadjust
+tabw_i 0.5297315,851,gixdb_pitchadjust
+tabw_i 0.5297315,852,gixdb_pitchadjust
+tabw_i 0.5297315,853,gixdb_pitchadjust
+tabw_i 0.5297315,854,gixdb_pitchadjust
+tabw_i 0.56123096,855,gixdb_pitchadjust
+tabw_i 0.56123096,856,gixdb_pitchadjust
+tabw_i 0.56123096,857,gixdb_pitchadjust
+tabw_i 0.56123096,858,gixdb_pitchadjust
+tabw_i 0.59460354,859,gixdb_pitchadjust
+tabw_i 0.59460354,860,gixdb_pitchadjust
+tabw_i 0.59460354,861,gixdb_pitchadjust
+tabw_i 0.59460354,862,gixdb_pitchadjust
+tabw_i 0.6299605,863,gixdb_pitchadjust
+tabw_i 0.6299605,864,gixdb_pitchadjust
+tabw_i 0.6299605,865,gixdb_pitchadjust
+tabw_i 0.6299605,866,gixdb_pitchadjust
+tabw_i 0.6674199,867,gixdb_pitchadjust
+tabw_i 0.6674199,868,gixdb_pitchadjust
+tabw_i 0.6674199,869,gixdb_pitchadjust
+tabw_i 0.6674199,870,gixdb_pitchadjust
+tabw_i 0.7071067,871,gixdb_pitchadjust
+tabw_i 0.7071067,872,gixdb_pitchadjust
+tabw_i 0.7071067,873,gixdb_pitchadjust
+tabw_i 0.7071067,874,gixdb_pitchadjust
+tabw_i 0.7491535,875,gixdb_pitchadjust
+tabw_i 0.7491535,876,gixdb_pitchadjust
+tabw_i 0.7491535,877,gixdb_pitchadjust
+tabw_i 0.7491535,878,gixdb_pitchadjust
+tabw_i 0.79370046,879,gixdb_pitchadjust
+tabw_i 0.79370046,880,gixdb_pitchadjust
+tabw_i 0.79370046,881,gixdb_pitchadjust
+tabw_i 0.79370046,882,gixdb_pitchadjust
+tabw_i 0.84089637,883,gixdb_pitchadjust
+tabw_i 0.84089637,884,gixdb_pitchadjust
+tabw_i 0.84089637,885,gixdb_pitchadjust
+tabw_i 0.84089637,886,gixdb_pitchadjust
+tabw_i 0.89089864,887,gixdb_pitchadjust
+tabw_i 0.89089864,888,gixdb_pitchadjust
+tabw_i 0.89089864,889,gixdb_pitchadjust
+tabw_i 0.89089864,890,gixdb_pitchadjust
+tabw_i 0.94387424,891,gixdb_pitchadjust
+tabw_i 0.94387424,892,gixdb_pitchadjust
+tabw_i 0.94387424,893,gixdb_pitchadjust
+tabw_i 0.94387424,894,gixdb_pitchadjust
+tabw_i 1,895,gixdb_pitchadjust
+tabw_i 1,896,gixdb_pitchadjust
+tabw_i 1,897,gixdb_pitchadjust
+tabw_i 1,898,gixdb_pitchadjust
+tabw_i 1.059463,899,gixdb_pitchadjust
+tabw_i 0.9438743,900,gixdb_pitchadjust
+tabw_i 0.9438743,901,gixdb_pitchadjust
+tabw_i 1.059463,902,gixdb_pitchadjust
+tabw_i 0.9438743,903,gixdb_pitchadjust
+tabw_i 1.059463,904,gixdb_pitchadjust
+tabw_i 1.059463,905,gixdb_pitchadjust
+tabw_i 0.9438743,906,gixdb_pitchadjust
+tabw_i 1,907,gixdb_pitchadjust
+tabw_i 1,908,gixdb_pitchadjust
+tabw_i 1,909,gixdb_pitchadjust
+tabw_i 1,910,gixdb_pitchadjust
+tabw_i 0.9438743,911,gixdb_pitchadjust
+tabw_i 1.0594631,912,gixdb_pitchadjust
+tabw_i 1.0594631,913,gixdb_pitchadjust
+tabw_i 0.9438743,914,gixdb_pitchadjust
+tabw_i 1.0594631,915,gixdb_pitchadjust
+tabw_i 0.9438743,916,gixdb_pitchadjust
+tabw_i 0.9438743,917,gixdb_pitchadjust
+tabw_i 1.0594631,918,gixdb_pitchadjust
+tabw_i 1,919,gixdb_pitchadjust
+tabw_i 1,920,gixdb_pitchadjust
+tabw_i 1,921,gixdb_pitchadjust
+tabw_i 1,922,gixdb_pitchadjust
+tabw_i 1,923,gixdb_pitchadjust
+tabw_i 1,924,gixdb_pitchadjust
+tabw_i 1,925,gixdb_pitchadjust
+tabw_i 1,926,gixdb_pitchadjust
+tabw_i 1,927,gixdb_pitchadjust
+tabw_i 1.059463,928,gixdb_pitchadjust
+tabw_i 0.9438743,929,gixdb_pitchadjust
+tabw_i 1.059463,930,gixdb_pitchadjust
+tabw_i 0.9438743,931,gixdb_pitchadjust
+tabw_i 1.059463,932,gixdb_pitchadjust
+tabw_i 0.9438743,933,gixdb_pitchadjust
+tabw_i 1.059463,934,gixdb_pitchadjust
+tabw_i 1.059463,935,gixdb_pitchadjust
+tabw_i 0.9438743,936,gixdb_pitchadjust
+tabw_i 0.9438743,937,gixdb_pitchadjust
+tabw_i 1,938,gixdb_pitchadjust
+tabw_i 1,939,gixdb_pitchadjust
+tabw_i 1,940,gixdb_pitchadjust
+tabw_i 1,941,gixdb_pitchadjust
+tabw_i 1,942,gixdb_pitchadjust
+tabw_i 0.9438743,943,gixdb_pitchadjust
+tabw_i 0.9438743,944,gixdb_pitchadjust
+tabw_i 1.0594631,945,gixdb_pitchadjust
+tabw_i 1.0594631,946,gixdb_pitchadjust
+tabw_i 0.9438743,947,gixdb_pitchadjust
+tabw_i 0.9438743,948,gixdb_pitchadjust
+tabw_i 1.0594631,949,gixdb_pitchadjust
+tabw_i 0.9438743,950,gixdb_pitchadjust
+tabw_i 1.0594631,951,gixdb_pitchadjust
+tabw_i 1.0594631,952,gixdb_pitchadjust
+tabw_i 1,953,gixdb_pitchadjust
+tabw_i 1,954,gixdb_pitchadjust
+tabw_i 1,955,gixdb_pitchadjust
+tabw_i 1,956,gixdb_pitchadjust
+tabw_i 1,957,gixdb_pitchadjust
+tabw_i 1.0594631,958,gixdb_pitchadjust
+tabw_i 1.0594631,959,gixdb_pitchadjust
+tabw_i 1.0594631,960,gixdb_pitchadjust
+tabw_i 1.0594631,961,gixdb_pitchadjust
+tabw_i 0.9438743,962,gixdb_pitchadjust
+tabw_i 0.9438743,963,gixdb_pitchadjust
+tabw_i 1.0594631,964,gixdb_pitchadjust
+tabw_i 0.9438743,965,gixdb_pitchadjust
+tabw_i 0.9438743,966,gixdb_pitchadjust
+tabw_i 0.9438743,967,gixdb_pitchadjust
+tabw_i 1,968,gixdb_pitchadjust
+tabw_i 1,969,gixdb_pitchadjust
+tabw_i 1,970,gixdb_pitchadjust
+tabw_i 1,971,gixdb_pitchadjust
+tabw_i 1,972,gixdb_pitchadjust
+tabw_i 1,973,gixdb_pitchadjust
+tabw_i 1,974,gixdb_pitchadjust
+tabw_i 1,975,gixdb_pitchadjust
+tabw_i 1,976,gixdb_pitchadjust
+tabw_i 0.9438743,977,gixdb_pitchadjust
+tabw_i 0.9438743,978,gixdb_pitchadjust
+tabw_i 1.059463,979,gixdb_pitchadjust
+tabw_i 1.059463,980,gixdb_pitchadjust
+tabw_i 1.059463,981,gixdb_pitchadjust
+tabw_i 0.9438743,982,gixdb_pitchadjust
+tabw_i 1.059463,983,gixdb_pitchadjust
+tabw_i 0.9438743,984,gixdb_pitchadjust
+tabw_i 1,985,gixdb_pitchadjust
+tabw_i 1,986,gixdb_pitchadjust
+tabw_i 1,987,gixdb_pitchadjust
+tabw_i 1,988,gixdb_pitchadjust
+tabw_i 0.9438743,989,gixdb_pitchadjust
+tabw_i 1.0594631,990,gixdb_pitchadjust
+tabw_i 1.0594631,991,gixdb_pitchadjust
+tabw_i 1.0594631,992,gixdb_pitchadjust
+tabw_i 0.9438743,993,gixdb_pitchadjust
+tabw_i 0.9438743,994,gixdb_pitchadjust
+tabw_i 1.0594631,995,gixdb_pitchadjust
+tabw_i 0.9438743,996,gixdb_pitchadjust
+tabw_i 1,997,gixdb_pitchadjust
+tabw_i 1,998,gixdb_pitchadjust
+tabw_i 1,999,gixdb_pitchadjust
+tabw_i 1,1000,gixdb_pitchadjust
+tabw_i 1,1001,gixdb_pitchadjust
+tabw_i 1,1002,gixdb_pitchadjust
+tabw_i 1,1003,gixdb_pitchadjust
+tabw_i 1,1004,gixdb_pitchadjust
+tabw_i 1,1005,gixdb_pitchadjust
+tabw_i 1.059463,1006,gixdb_pitchadjust
+tabw_i 1.059463,1007,gixdb_pitchadjust
+tabw_i 0.9438743,1008,gixdb_pitchadjust
+tabw_i 0.9438743,1009,gixdb_pitchadjust
+tabw_i 1.059463,1010,gixdb_pitchadjust
+tabw_i 1.059463,1011,gixdb_pitchadjust
+tabw_i 1.059463,1012,gixdb_pitchadjust
+tabw_i 0.9438743,1013,gixdb_pitchadjust
+tabw_i 0.9438743,1014,gixdb_pitchadjust
+tabw_i 1,1015,gixdb_pitchadjust
+tabw_i 1,1016,gixdb_pitchadjust
+tabw_i 1,1017,gixdb_pitchadjust
+tabw_i 1,1018,gixdb_pitchadjust
+tabw_i 1.0594631,1019,gixdb_pitchadjust
+tabw_i 0.9438743,1020,gixdb_pitchadjust
+tabw_i 0.9438743,1021,gixdb_pitchadjust
+tabw_i 1.0594631,1022,gixdb_pitchadjust
+tabw_i 0.9438743,1023,gixdb_pitchadjust
+tabw_i 0.9438743,1024,gixdb_pitchadjust
+tabw_i 0.9438743,1025,gixdb_pitchadjust
+tabw_i 1.0594631,1026,gixdb_pitchadjust
+tabw_i 1.0594631,1027,gixdb_pitchadjust
+tabw_i 1,1028,gixdb_pitchadjust
+tabw_i 1,1029,gixdb_pitchadjust
+tabw_i 1,1030,gixdb_pitchadjust
+tabw_i 1,1031,gixdb_pitchadjust
+tabw_i 1,1032,gixdb_pitchadjust
+tabw_i 0.9438743,1033,gixdb_pitchadjust
+tabw_i 0.9438743,1034,gixdb_pitchadjust
+tabw_i 0.9438743,1035,gixdb_pitchadjust
+tabw_i 1.0594631,1036,gixdb_pitchadjust
+tabw_i 1.0594631,1037,gixdb_pitchadjust
+tabw_i 1.0594631,1038,gixdb_pitchadjust
+tabw_i 1.0594631,1039,gixdb_pitchadjust
+tabw_i 0.9438743,1040,gixdb_pitchadjust
+tabw_i 1.0594631,1041,gixdb_pitchadjust
+tabw_i 0.9438743,1042,gixdb_pitchadjust
+tabw_i 1,1043,gixdb_pitchadjust
+tabw_i 1,1044,gixdb_pitchadjust
+tabw_i 1,1045,gixdb_pitchadjust
+tabw_i 1,1046,gixdb_pitchadjust
+tabw_i 1,1047,gixdb_pitchadjust
+tabw_i 1,1048,gixdb_pitchadjust
+tabw_i 1,1049,gixdb_pitchadjust
+tabw_i 1,1050,gixdb_pitchadjust
+tabw_i 1,1051,gixdb_pitchadjust
+tabw_i 0.9438743,1052,gixdb_pitchadjust
+tabw_i 0.9438743,1053,gixdb_pitchadjust
+tabw_i 1.059463,1054,gixdb_pitchadjust
+tabw_i 0.9438743,1055,gixdb_pitchadjust
+tabw_i 1.059463,1056,gixdb_pitchadjust
+tabw_i 1.059463,1057,gixdb_pitchadjust
+tabw_i 0.9438743,1058,gixdb_pitchadjust
+tabw_i 1.059463,1059,gixdb_pitchadjust
+tabw_i 1,1060,gixdb_pitchadjust
+tabw_i 1,1061,gixdb_pitchadjust
+tabw_i 1,1062,gixdb_pitchadjust
+tabw_i 1,1063,gixdb_pitchadjust
+tabw_i 0.9438743,1064,gixdb_pitchadjust
+tabw_i 1.0594631,1065,gixdb_pitchadjust
+tabw_i 1.0594631,1066,gixdb_pitchadjust
+tabw_i 1.0594631,1067,gixdb_pitchadjust
+tabw_i 0.9438743,1068,gixdb_pitchadjust
+tabw_i 0.9438743,1069,gixdb_pitchadjust
+tabw_i 1.0594631,1070,gixdb_pitchadjust
+tabw_i 1,1071,gixdb_pitchadjust
+tabw_i 1,1072,gixdb_pitchadjust
+tabw_i 1,1073,gixdb_pitchadjust
+tabw_i 1.0594631,1074,gixdb_pitchadjust
+tabw_i 1.0594631,1075,gixdb_pitchadjust
+tabw_i 1.0594631,1076,gixdb_pitchadjust
+tabw_i 1.122462,1077,gixdb_pitchadjust
+tabw_i 1.122462,1078,gixdb_pitchadjust
+tabw_i 1.122462,1079,gixdb_pitchadjust
+tabw_i 1.1892071,1080,gixdb_pitchadjust
+tabw_i 1.1892071,1081,gixdb_pitchadjust
+tabw_i 1.1892071,1082,gixdb_pitchadjust
+tabw_i 1.259921,1083,gixdb_pitchadjust
+tabw_i 1.259921,1084,gixdb_pitchadjust
+tabw_i 1.259921,1085,gixdb_pitchadjust
+tabw_i 1.3348398,1086,gixdb_pitchadjust
+tabw_i 1.3348398,1087,gixdb_pitchadjust
+tabw_i 1.3348398,1088,gixdb_pitchadjust
+tabw_i 1.4142135,1089,gixdb_pitchadjust
+tabw_i 1.4142135,1090,gixdb_pitchadjust
+tabw_i 1.4142135,1091,gixdb_pitchadjust
+tabw_i 1.498307,1092,gixdb_pitchadjust
+tabw_i 1.498307,1093,gixdb_pitchadjust
+tabw_i 1.498307,1094,gixdb_pitchadjust
+tabw_i 1.5874012,1095,gixdb_pitchadjust
+tabw_i 1.5874012,1096,gixdb_pitchadjust
+tabw_i 1.5874012,1097,gixdb_pitchadjust
+tabw_i 1.6817927,1098,gixdb_pitchadjust
+tabw_i 1.6817927,1099,gixdb_pitchadjust
+tabw_i 1.6817927,1100,gixdb_pitchadjust
+tabw_i 1.7817974,1101,gixdb_pitchadjust
+tabw_i 1.7817974,1102,gixdb_pitchadjust
+tabw_i 1.7817974,1103,gixdb_pitchadjust
+tabw_i 1.8877486,1104,gixdb_pitchadjust
+tabw_i 1.8877486,1105,gixdb_pitchadjust
+tabw_i 1.8877486,1106,gixdb_pitchadjust
+tabw_i 2,1107,gixdb_pitchadjust
+tabw_i 2,1108,gixdb_pitchadjust
+tabw_i 2,1109,gixdb_pitchadjust
+tabw_i 2.1189263,1110,gixdb_pitchadjust
+tabw_i 2.1189263,1111,gixdb_pitchadjust
+tabw_i 2.1189263,1112,gixdb_pitchadjust
+tabw_i 2.244924,1113,gixdb_pitchadjust
+tabw_i 2.244924,1114,gixdb_pitchadjust
+tabw_i 2.244924,1115,gixdb_pitchadjust
+tabw_i 2.3784142,1116,gixdb_pitchadjust
+tabw_i 2.3784142,1117,gixdb_pitchadjust
+tabw_i 2.3784142,1118,gixdb_pitchadjust
+tabw_i 2.519842,1119,gixdb_pitchadjust
+tabw_i 2.519842,1120,gixdb_pitchadjust
+tabw_i 2.519842,1121,gixdb_pitchadjust
+tabw_i 2.6696796,1122,gixdb_pitchadjust
+tabw_i 2.6696796,1123,gixdb_pitchadjust
+tabw_i 2.6696796,1124,gixdb_pitchadjust
+tabw_i 2.828427,1125,gixdb_pitchadjust
+tabw_i 2.828427,1126,gixdb_pitchadjust
+tabw_i 2.828427,1127,gixdb_pitchadjust
+tabw_i 2.996614,1128,gixdb_pitchadjust
+tabw_i 2.996614,1129,gixdb_pitchadjust
+tabw_i 2.996614,1130,gixdb_pitchadjust
+tabw_i 3.1748023,1131,gixdb_pitchadjust
+tabw_i 3.1748023,1132,gixdb_pitchadjust
+tabw_i 3.1748023,1133,gixdb_pitchadjust
+tabw_i 3.3635855,1134,gixdb_pitchadjust
+tabw_i 3.3635855,1135,gixdb_pitchadjust
+tabw_i 3.3635855,1136,gixdb_pitchadjust
+tabw_i 3.5635948,1137,gixdb_pitchadjust
+tabw_i 3.5635948,1138,gixdb_pitchadjust
+tabw_i 3.5635948,1139,gixdb_pitchadjust
+tabw_i 3.7754972,1140,gixdb_pitchadjust
+tabw_i 3.7754972,1141,gixdb_pitchadjust
+tabw_i 3.7754972,1142,gixdb_pitchadjust
+tabw_i 4,1143,gixdb_pitchadjust
+tabw_i 4,1144,gixdb_pitchadjust
+tabw_i 4,1145,gixdb_pitchadjust
+tabw_i 4.2378526,1146,gixdb_pitchadjust
+tabw_i 4.2378526,1147,gixdb_pitchadjust
+tabw_i 4.2378526,1148,gixdb_pitchadjust
+tabw_i 4.489848,1149,gixdb_pitchadjust
+tabw_i 4.489848,1150,gixdb_pitchadjust
+tabw_i 4.489848,1151,gixdb_pitchadjust
+tabw_i 4.7568283,1152,gixdb_pitchadjust
+tabw_i 4.7568283,1153,gixdb_pitchadjust
+tabw_i 4.7568283,1154,gixdb_pitchadjust
+tabw_i 5.039684,1155,gixdb_pitchadjust
+tabw_i 5.039684,1156,gixdb_pitchadjust
+tabw_i 5.039684,1157,gixdb_pitchadjust
+tabw_i 5.3393593,1158,gixdb_pitchadjust
+tabw_i 5.3393593,1159,gixdb_pitchadjust
+tabw_i 5.3393593,1160,gixdb_pitchadjust
+tabw_i 5.656854,1161,gixdb_pitchadjust
+tabw_i 5.656854,1162,gixdb_pitchadjust
+tabw_i 5.656854,1163,gixdb_pitchadjust
+tabw_i 5.993228,1164,gixdb_pitchadjust
+tabw_i 5.993228,1165,gixdb_pitchadjust
+tabw_i 5.993228,1166,gixdb_pitchadjust
+tabw_i 6.3496046,1167,gixdb_pitchadjust
+tabw_i 6.3496046,1168,gixdb_pitchadjust
+tabw_i 6.3496046,1169,gixdb_pitchadjust
+tabw_i 6.727171,1170,gixdb_pitchadjust
+tabw_i 6.727171,1171,gixdb_pitchadjust
+tabw_i 6.727171,1172,gixdb_pitchadjust
+tabw_i 7.1271896,1173,gixdb_pitchadjust
+tabw_i 7.1271896,1174,gixdb_pitchadjust
+tabw_i 7.1271896,1175,gixdb_pitchadjust
+tabw_i 7.5509944,1176,gixdb_pitchadjust
+tabw_i 7.5509944,1177,gixdb_pitchadjust
+tabw_i 7.5509944,1178,gixdb_pitchadjust
+tabw_i 8,1179,gixdb_pitchadjust
+tabw_i 8,1180,gixdb_pitchadjust
+tabw_i 8,1181,gixdb_pitchadjust
+tabw_i 8.475705,1182,gixdb_pitchadjust
+tabw_i 8.475705,1183,gixdb_pitchadjust
+tabw_i 8.475705,1184,gixdb_pitchadjust
+tabw_i 8.979696,1185,gixdb_pitchadjust
+tabw_i 8.979696,1186,gixdb_pitchadjust
+tabw_i 8.979696,1187,gixdb_pitchadjust
+tabw_i 9.513657,1188,gixdb_pitchadjust
+tabw_i 9.513657,1189,gixdb_pitchadjust
+tabw_i 9.513657,1190,gixdb_pitchadjust
diff --git a/site/app/partialemergence/sounds/Kalimba/60.0.mp3 b/site/app/partialemergence/sounds/Kalimba/60.0.mp3 Binary files differnew file mode 100644 index 0000000..63ab3ae --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/60.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/60.1.mp3 b/site/app/partialemergence/sounds/Kalimba/60.1.mp3 Binary files differnew file mode 100644 index 0000000..347c5af --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/60.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/60.2.mp3 b/site/app/partialemergence/sounds/Kalimba/60.2.mp3 Binary files differnew file mode 100644 index 0000000..f1ddfe7 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/60.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/60.3.mp3 b/site/app/partialemergence/sounds/Kalimba/60.3.mp3 Binary files differnew file mode 100644 index 0000000..fd0e300 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/60.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/62.0.mp3 b/site/app/partialemergence/sounds/Kalimba/62.0.mp3 Binary files differnew file mode 100644 index 0000000..759075f --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/62.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/62.1.mp3 b/site/app/partialemergence/sounds/Kalimba/62.1.mp3 Binary files differnew file mode 100644 index 0000000..c9b023c --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/62.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/62.2.mp3 b/site/app/partialemergence/sounds/Kalimba/62.2.mp3 Binary files differnew file mode 100644 index 0000000..0954eea --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/62.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/62.3.mp3 b/site/app/partialemergence/sounds/Kalimba/62.3.mp3 Binary files differnew file mode 100644 index 0000000..b8675c7 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/62.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/64.0.mp3 b/site/app/partialemergence/sounds/Kalimba/64.0.mp3 Binary files differnew file mode 100644 index 0000000..6f82a28 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/64.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/64.1.mp3 b/site/app/partialemergence/sounds/Kalimba/64.1.mp3 Binary files differnew file mode 100644 index 0000000..49ae0f3 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/64.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/64.2.mp3 b/site/app/partialemergence/sounds/Kalimba/64.2.mp3 Binary files differnew file mode 100644 index 0000000..4fe11e0 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/64.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/64.3.mp3 b/site/app/partialemergence/sounds/Kalimba/64.3.mp3 Binary files differnew file mode 100644 index 0000000..63299a6 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/64.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/65.0.mp3 b/site/app/partialemergence/sounds/Kalimba/65.0.mp3 Binary files differnew file mode 100644 index 0000000..744a297 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/65.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/65.1.mp3 b/site/app/partialemergence/sounds/Kalimba/65.1.mp3 Binary files differnew file mode 100644 index 0000000..2a87845 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/65.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/65.2.mp3 b/site/app/partialemergence/sounds/Kalimba/65.2.mp3 Binary files differnew file mode 100644 index 0000000..d5ab60f --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/65.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/65.3.mp3 b/site/app/partialemergence/sounds/Kalimba/65.3.mp3 Binary files differnew file mode 100644 index 0000000..3da5771 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/65.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/65.4.mp3 b/site/app/partialemergence/sounds/Kalimba/65.4.mp3 Binary files differnew file mode 100644 index 0000000..95acc43 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/65.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/67.0.mp3 b/site/app/partialemergence/sounds/Kalimba/67.0.mp3 Binary files differnew file mode 100644 index 0000000..b5d681d --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/67.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/67.1.mp3 b/site/app/partialemergence/sounds/Kalimba/67.1.mp3 Binary files differnew file mode 100644 index 0000000..c80b8f8 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/67.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/67.2.mp3 b/site/app/partialemergence/sounds/Kalimba/67.2.mp3 Binary files differnew file mode 100644 index 0000000..eb8e56e --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/67.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/67.3.mp3 b/site/app/partialemergence/sounds/Kalimba/67.3.mp3 Binary files differnew file mode 100644 index 0000000..7b16c62 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/67.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/67.4.mp3 b/site/app/partialemergence/sounds/Kalimba/67.4.mp3 Binary files differnew file mode 100644 index 0000000..edc4956 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/67.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/69.0.mp3 b/site/app/partialemergence/sounds/Kalimba/69.0.mp3 Binary files differnew file mode 100644 index 0000000..b052fba --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/69.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/69.1.mp3 b/site/app/partialemergence/sounds/Kalimba/69.1.mp3 Binary files differnew file mode 100644 index 0000000..e9707a3 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/69.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/69.2.mp3 b/site/app/partialemergence/sounds/Kalimba/69.2.mp3 Binary files differnew file mode 100644 index 0000000..2481606 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/69.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/69.3.mp3 b/site/app/partialemergence/sounds/Kalimba/69.3.mp3 Binary files differnew file mode 100644 index 0000000..ab9f063 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/69.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/69.4.mp3 b/site/app/partialemergence/sounds/Kalimba/69.4.mp3 Binary files differnew file mode 100644 index 0000000..f5141ea --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/69.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/71.0.mp3 b/site/app/partialemergence/sounds/Kalimba/71.0.mp3 Binary files differnew file mode 100644 index 0000000..b002709 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/71.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/71.1.mp3 b/site/app/partialemergence/sounds/Kalimba/71.1.mp3 Binary files differnew file mode 100644 index 0000000..84911f3 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/71.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/71.2.mp3 b/site/app/partialemergence/sounds/Kalimba/71.2.mp3 Binary files differnew file mode 100644 index 0000000..1fd314c --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/71.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/71.3.mp3 b/site/app/partialemergence/sounds/Kalimba/71.3.mp3 Binary files differnew file mode 100644 index 0000000..b63143d --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/71.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/71.4.mp3 b/site/app/partialemergence/sounds/Kalimba/71.4.mp3 Binary files differnew file mode 100644 index 0000000..983f435 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/71.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/72.0.mp3 b/site/app/partialemergence/sounds/Kalimba/72.0.mp3 Binary files differnew file mode 100644 index 0000000..2dd622c --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/72.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/72.1.mp3 b/site/app/partialemergence/sounds/Kalimba/72.1.mp3 Binary files differnew file mode 100644 index 0000000..df2770a --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/72.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/72.2.mp3 b/site/app/partialemergence/sounds/Kalimba/72.2.mp3 Binary files differnew file mode 100644 index 0000000..38b391a --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/72.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/72.3.mp3 b/site/app/partialemergence/sounds/Kalimba/72.3.mp3 Binary files differnew file mode 100644 index 0000000..e792a22 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/72.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/74.0.mp3 b/site/app/partialemergence/sounds/Kalimba/74.0.mp3 Binary files differnew file mode 100644 index 0000000..56cc890 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/74.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/74.1.mp3 b/site/app/partialemergence/sounds/Kalimba/74.1.mp3 Binary files differnew file mode 100644 index 0000000..24e0be3 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/74.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/74.2.mp3 b/site/app/partialemergence/sounds/Kalimba/74.2.mp3 Binary files differnew file mode 100644 index 0000000..756bf84 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/74.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/74.3.mp3 b/site/app/partialemergence/sounds/Kalimba/74.3.mp3 Binary files differnew file mode 100644 index 0000000..5b86735 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/74.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/76.0.mp3 b/site/app/partialemergence/sounds/Kalimba/76.0.mp3 Binary files differnew file mode 100644 index 0000000..6af8e62 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/76.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/76.1.mp3 b/site/app/partialemergence/sounds/Kalimba/76.1.mp3 Binary files differnew file mode 100644 index 0000000..e748b9d --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/76.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/76.2.mp3 b/site/app/partialemergence/sounds/Kalimba/76.2.mp3 Binary files differnew file mode 100644 index 0000000..7e2e703 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/76.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/76.3.mp3 b/site/app/partialemergence/sounds/Kalimba/76.3.mp3 Binary files differnew file mode 100644 index 0000000..3afd998 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/76.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/77.0.mp3 b/site/app/partialemergence/sounds/Kalimba/77.0.mp3 Binary files differnew file mode 100644 index 0000000..10526b9 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/77.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/77.1.mp3 b/site/app/partialemergence/sounds/Kalimba/77.1.mp3 Binary files differnew file mode 100644 index 0000000..6578b62 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/77.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/77.2.mp3 b/site/app/partialemergence/sounds/Kalimba/77.2.mp3 Binary files differnew file mode 100644 index 0000000..2c1d510 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/77.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/77.3.mp3 b/site/app/partialemergence/sounds/Kalimba/77.3.mp3 Binary files differnew file mode 100644 index 0000000..bf4ea31 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/77.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/77.4.mp3 b/site/app/partialemergence/sounds/Kalimba/77.4.mp3 Binary files differnew file mode 100644 index 0000000..435ee84 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/77.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/79.0.mp3 b/site/app/partialemergence/sounds/Kalimba/79.0.mp3 Binary files differnew file mode 100644 index 0000000..73b7bfa --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/79.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/79.1.mp3 b/site/app/partialemergence/sounds/Kalimba/79.1.mp3 Binary files differnew file mode 100644 index 0000000..c8e9113 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/79.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/79.2.mp3 b/site/app/partialemergence/sounds/Kalimba/79.2.mp3 Binary files differnew file mode 100644 index 0000000..889bccd --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/79.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/79.3.mp3 b/site/app/partialemergence/sounds/Kalimba/79.3.mp3 Binary files differnew file mode 100644 index 0000000..31d6efb --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/79.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/81.0.mp3 b/site/app/partialemergence/sounds/Kalimba/81.0.mp3 Binary files differnew file mode 100644 index 0000000..c06b8b9 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/81.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/81.1.mp3 b/site/app/partialemergence/sounds/Kalimba/81.1.mp3 Binary files differnew file mode 100644 index 0000000..da3bd28 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/81.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/81.2.mp3 b/site/app/partialemergence/sounds/Kalimba/81.2.mp3 Binary files differnew file mode 100644 index 0000000..3899002 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/81.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/81.3.mp3 b/site/app/partialemergence/sounds/Kalimba/81.3.mp3 Binary files differnew file mode 100644 index 0000000..65851b3 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/81.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/81.4.mp3 b/site/app/partialemergence/sounds/Kalimba/81.4.mp3 Binary files differnew file mode 100644 index 0000000..ce5f34e --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/81.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/83.0.mp3 b/site/app/partialemergence/sounds/Kalimba/83.0.mp3 Binary files differnew file mode 100644 index 0000000..5a82b39 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/83.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/83.1.mp3 b/site/app/partialemergence/sounds/Kalimba/83.1.mp3 Binary files differnew file mode 100644 index 0000000..79781ef --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/83.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/83.2.mp3 b/site/app/partialemergence/sounds/Kalimba/83.2.mp3 Binary files differnew file mode 100644 index 0000000..1c4c97b --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/83.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/83.3.mp3 b/site/app/partialemergence/sounds/Kalimba/83.3.mp3 Binary files differnew file mode 100644 index 0000000..df816ef --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/83.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/83.4.mp3 b/site/app/partialemergence/sounds/Kalimba/83.4.mp3 Binary files differnew file mode 100644 index 0000000..f7cb62c --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/83.4.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/84.0.mp3 b/site/app/partialemergence/sounds/Kalimba/84.0.mp3 Binary files differnew file mode 100644 index 0000000..5bf1e3a --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/84.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/84.1.mp3 b/site/app/partialemergence/sounds/Kalimba/84.1.mp3 Binary files differnew file mode 100644 index 0000000..0ce17e8 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/84.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/84.2.mp3 b/site/app/partialemergence/sounds/Kalimba/84.2.mp3 Binary files differnew file mode 100644 index 0000000..ac496e0 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/84.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/84.3.mp3 b/site/app/partialemergence/sounds/Kalimba/84.3.mp3 Binary files differnew file mode 100644 index 0000000..9c54285 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/84.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/86.0.mp3 b/site/app/partialemergence/sounds/Kalimba/86.0.mp3 Binary files differnew file mode 100644 index 0000000..7042234 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/86.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/86.1.mp3 b/site/app/partialemergence/sounds/Kalimba/86.1.mp3 Binary files differnew file mode 100644 index 0000000..27b553f --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/86.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/86.2.mp3 b/site/app/partialemergence/sounds/Kalimba/86.2.mp3 Binary files differnew file mode 100644 index 0000000..f89a0d7 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/86.2.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/86.3.mp3 b/site/app/partialemergence/sounds/Kalimba/86.3.mp3 Binary files differnew file mode 100644 index 0000000..5124740 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/86.3.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/88.0.mp3 b/site/app/partialemergence/sounds/Kalimba/88.0.mp3 Binary files differnew file mode 100644 index 0000000..3097bac --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/88.0.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/88.1.mp3 b/site/app/partialemergence/sounds/Kalimba/88.1.mp3 Binary files differnew file mode 100644 index 0000000..924d962 --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/88.1.mp3 diff --git a/site/app/partialemergence/sounds/Kalimba/88.2.mp3 b/site/app/partialemergence/sounds/Kalimba/88.2.mp3 Binary files differnew file mode 100644 index 0000000..5fde74f --- /dev/null +++ b/site/app/partialemergence/sounds/Kalimba/88.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.0.mp3 b/site/app/partialemergence/sounds/MusicBox/68.0.mp3 Binary files differnew file mode 100644 index 0000000..3cba4dd --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.1.mp3 b/site/app/partialemergence/sounds/MusicBox/68.1.mp3 Binary files differnew file mode 100644 index 0000000..29943ee --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.2.mp3 b/site/app/partialemergence/sounds/MusicBox/68.2.mp3 Binary files differnew file mode 100644 index 0000000..9a25208 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.3.mp3 b/site/app/partialemergence/sounds/MusicBox/68.3.mp3 Binary files differnew file mode 100644 index 0000000..4847168 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.4.mp3 b/site/app/partialemergence/sounds/MusicBox/68.4.mp3 Binary files differnew file mode 100644 index 0000000..1642bb6 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.4.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/68.5.mp3 b/site/app/partialemergence/sounds/MusicBox/68.5.mp3 Binary files differnew file mode 100644 index 0000000..a107d83 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/68.5.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/70.0.mp3 b/site/app/partialemergence/sounds/MusicBox/70.0.mp3 Binary files differnew file mode 100644 index 0000000..695671e --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/70.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/70.1.mp3 b/site/app/partialemergence/sounds/MusicBox/70.1.mp3 Binary files differnew file mode 100644 index 0000000..07642e1 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/70.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/70.2.mp3 b/site/app/partialemergence/sounds/MusicBox/70.2.mp3 Binary files differnew file mode 100644 index 0000000..c758665 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/70.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/70.3.mp3 b/site/app/partialemergence/sounds/MusicBox/70.3.mp3 Binary files differnew file mode 100644 index 0000000..e9a02ed --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/70.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/70.4.mp3 b/site/app/partialemergence/sounds/MusicBox/70.4.mp3 Binary files differnew file mode 100644 index 0000000..dea302f --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/70.4.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/72.0.mp3 b/site/app/partialemergence/sounds/MusicBox/72.0.mp3 Binary files differnew file mode 100644 index 0000000..b873e2a --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/72.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/72.1.mp3 b/site/app/partialemergence/sounds/MusicBox/72.1.mp3 Binary files differnew file mode 100644 index 0000000..9e6a248 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/72.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/72.2.mp3 b/site/app/partialemergence/sounds/MusicBox/72.2.mp3 Binary files differnew file mode 100644 index 0000000..3d13386 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/72.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/72.3.mp3 b/site/app/partialemergence/sounds/MusicBox/72.3.mp3 Binary files differnew file mode 100644 index 0000000..d579d7e --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/72.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/73.0.mp3 b/site/app/partialemergence/sounds/MusicBox/73.0.mp3 Binary files differnew file mode 100644 index 0000000..103db48 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/73.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/73.1.mp3 b/site/app/partialemergence/sounds/MusicBox/73.1.mp3 Binary files differnew file mode 100644 index 0000000..c2dd5b1 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/73.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/73.2.mp3 b/site/app/partialemergence/sounds/MusicBox/73.2.mp3 Binary files differnew file mode 100644 index 0000000..5e5ce84 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/73.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/75.0.mp3 b/site/app/partialemergence/sounds/MusicBox/75.0.mp3 Binary files differnew file mode 100644 index 0000000..d1af15d --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/75.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/75.1.mp3 b/site/app/partialemergence/sounds/MusicBox/75.1.mp3 Binary files differnew file mode 100644 index 0000000..7080ca0 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/75.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/75.2.mp3 b/site/app/partialemergence/sounds/MusicBox/75.2.mp3 Binary files differnew file mode 100644 index 0000000..f5a3792 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/75.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/77.0.mp3 b/site/app/partialemergence/sounds/MusicBox/77.0.mp3 Binary files differnew file mode 100644 index 0000000..5258d3e --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/77.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/77.1.mp3 b/site/app/partialemergence/sounds/MusicBox/77.1.mp3 Binary files differnew file mode 100644 index 0000000..72dcd0b --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/77.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/77.2.mp3 b/site/app/partialemergence/sounds/MusicBox/77.2.mp3 Binary files differnew file mode 100644 index 0000000..141a6f7 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/77.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/77.3.mp3 b/site/app/partialemergence/sounds/MusicBox/77.3.mp3 Binary files differnew file mode 100644 index 0000000..8394958 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/77.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/79.0.mp3 b/site/app/partialemergence/sounds/MusicBox/79.0.mp3 Binary files differnew file mode 100644 index 0000000..cf3d403 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/79.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/79.1.mp3 b/site/app/partialemergence/sounds/MusicBox/79.1.mp3 Binary files differnew file mode 100644 index 0000000..e4aadb0 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/79.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/79.2.mp3 b/site/app/partialemergence/sounds/MusicBox/79.2.mp3 Binary files differnew file mode 100644 index 0000000..2fc69d2 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/79.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/79.3.mp3 b/site/app/partialemergence/sounds/MusicBox/79.3.mp3 Binary files differnew file mode 100644 index 0000000..b787a4a --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/79.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/80.0.mp3 b/site/app/partialemergence/sounds/MusicBox/80.0.mp3 Binary files differnew file mode 100644 index 0000000..a47d5d9 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/80.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/80.1.mp3 b/site/app/partialemergence/sounds/MusicBox/80.1.mp3 Binary files differnew file mode 100644 index 0000000..a92072a --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/80.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/80.2.mp3 b/site/app/partialemergence/sounds/MusicBox/80.2.mp3 Binary files differnew file mode 100644 index 0000000..7172e56 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/80.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/80.3.mp3 b/site/app/partialemergence/sounds/MusicBox/80.3.mp3 Binary files differnew file mode 100644 index 0000000..8bd3431 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/80.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/82.0.mp3 b/site/app/partialemergence/sounds/MusicBox/82.0.mp3 Binary files differnew file mode 100644 index 0000000..def26fb --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/82.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/82.1.mp3 b/site/app/partialemergence/sounds/MusicBox/82.1.mp3 Binary files differnew file mode 100644 index 0000000..12c104d --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/82.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/82.2.mp3 b/site/app/partialemergence/sounds/MusicBox/82.2.mp3 Binary files differnew file mode 100644 index 0000000..b1b6604 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/82.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/82.3.mp3 b/site/app/partialemergence/sounds/MusicBox/82.3.mp3 Binary files differnew file mode 100644 index 0000000..5d5927f --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/82.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/84.0.mp3 b/site/app/partialemergence/sounds/MusicBox/84.0.mp3 Binary files differnew file mode 100644 index 0000000..94f7da7 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/84.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/84.1.mp3 b/site/app/partialemergence/sounds/MusicBox/84.1.mp3 Binary files differnew file mode 100644 index 0000000..14e9e13 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/84.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/84.2.mp3 b/site/app/partialemergence/sounds/MusicBox/84.2.mp3 Binary files differnew file mode 100644 index 0000000..848c535 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/84.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/84.3.mp3 b/site/app/partialemergence/sounds/MusicBox/84.3.mp3 Binary files differnew file mode 100644 index 0000000..89d65e4 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/84.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/85.0.mp3 b/site/app/partialemergence/sounds/MusicBox/85.0.mp3 Binary files differnew file mode 100644 index 0000000..f458a73 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/85.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/85.1.mp3 b/site/app/partialemergence/sounds/MusicBox/85.1.mp3 Binary files differnew file mode 100644 index 0000000..373c982 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/85.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/85.2.mp3 b/site/app/partialemergence/sounds/MusicBox/85.2.mp3 Binary files differnew file mode 100644 index 0000000..2ecf8fd --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/85.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/85.3.mp3 b/site/app/partialemergence/sounds/MusicBox/85.3.mp3 Binary files differnew file mode 100644 index 0000000..1820904 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/85.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/87.0.mp3 b/site/app/partialemergence/sounds/MusicBox/87.0.mp3 Binary files differnew file mode 100644 index 0000000..252b814 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/87.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/87.1.mp3 b/site/app/partialemergence/sounds/MusicBox/87.1.mp3 Binary files differnew file mode 100644 index 0000000..c9e28af --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/87.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/87.2.mp3 b/site/app/partialemergence/sounds/MusicBox/87.2.mp3 Binary files differnew file mode 100644 index 0000000..4ba0166 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/87.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/87.3.mp3 b/site/app/partialemergence/sounds/MusicBox/87.3.mp3 Binary files differnew file mode 100644 index 0000000..ea639a4 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/87.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/87.4.mp3 b/site/app/partialemergence/sounds/MusicBox/87.4.mp3 Binary files differnew file mode 100644 index 0000000..156d74b --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/87.4.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/89.0.mp3 b/site/app/partialemergence/sounds/MusicBox/89.0.mp3 Binary files differnew file mode 100644 index 0000000..14bae17 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/89.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/89.1.mp3 b/site/app/partialemergence/sounds/MusicBox/89.1.mp3 Binary files differnew file mode 100644 index 0000000..a1b2066 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/89.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/89.2.mp3 b/site/app/partialemergence/sounds/MusicBox/89.2.mp3 Binary files differnew file mode 100644 index 0000000..099b672 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/89.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/89.3.mp3 b/site/app/partialemergence/sounds/MusicBox/89.3.mp3 Binary files differnew file mode 100644 index 0000000..eb3887c --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/89.3.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/91.0.mp3 b/site/app/partialemergence/sounds/MusicBox/91.0.mp3 Binary files differnew file mode 100644 index 0000000..99c5294 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/91.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/91.1.mp3 b/site/app/partialemergence/sounds/MusicBox/91.1.mp3 Binary files differnew file mode 100644 index 0000000..b91a4d6 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/91.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/91.2.mp3 b/site/app/partialemergence/sounds/MusicBox/91.2.mp3 Binary files differnew file mode 100644 index 0000000..0eea22a --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/91.2.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/92.0.mp3 b/site/app/partialemergence/sounds/MusicBox/92.0.mp3 Binary files differnew file mode 100644 index 0000000..f41ea47 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/92.0.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/92.1.mp3 b/site/app/partialemergence/sounds/MusicBox/92.1.mp3 Binary files differnew file mode 100644 index 0000000..9c4f180 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/92.1.mp3 diff --git a/site/app/partialemergence/sounds/MusicBox/92.2.mp3 b/site/app/partialemergence/sounds/MusicBox/92.2.mp3 Binary files differnew file mode 100644 index 0000000..09a7c82 --- /dev/null +++ b/site/app/partialemergence/sounds/MusicBox/92.2.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/1.mp3 b/site/app/partialemergence/sounds/Water/Droplets/1.mp3 Binary files differnew file mode 100644 index 0000000..b4f0b98 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/1.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/10.mp3 b/site/app/partialemergence/sounds/Water/Droplets/10.mp3 Binary files differnew file mode 100644 index 0000000..8568013 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/10.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/100.mp3 b/site/app/partialemergence/sounds/Water/Droplets/100.mp3 Binary files differnew file mode 100644 index 0000000..9208d12 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/100.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/101.mp3 b/site/app/partialemergence/sounds/Water/Droplets/101.mp3 Binary files differnew file mode 100644 index 0000000..245a189 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/101.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/102.mp3 b/site/app/partialemergence/sounds/Water/Droplets/102.mp3 Binary files differnew file mode 100644 index 0000000..d163f03 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/102.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/103.mp3 b/site/app/partialemergence/sounds/Water/Droplets/103.mp3 Binary files differnew file mode 100644 index 0000000..6ac3fe6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/103.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/104.mp3 b/site/app/partialemergence/sounds/Water/Droplets/104.mp3 Binary files differnew file mode 100644 index 0000000..1ac83c9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/104.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/105.mp3 b/site/app/partialemergence/sounds/Water/Droplets/105.mp3 Binary files differnew file mode 100644 index 0000000..8c91dab --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/105.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/106.mp3 b/site/app/partialemergence/sounds/Water/Droplets/106.mp3 Binary files differnew file mode 100644 index 0000000..fcf4cff --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/106.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/107.mp3 b/site/app/partialemergence/sounds/Water/Droplets/107.mp3 Binary files differnew file mode 100644 index 0000000..a2b7d4c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/107.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/108.mp3 b/site/app/partialemergence/sounds/Water/Droplets/108.mp3 Binary files differnew file mode 100644 index 0000000..0ae741a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/108.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/109.mp3 b/site/app/partialemergence/sounds/Water/Droplets/109.mp3 Binary files differnew file mode 100644 index 0000000..96cb9a5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/109.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/11.mp3 b/site/app/partialemergence/sounds/Water/Droplets/11.mp3 Binary files differnew file mode 100644 index 0000000..4d720fa --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/11.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/110.mp3 b/site/app/partialemergence/sounds/Water/Droplets/110.mp3 Binary files differnew file mode 100644 index 0000000..a6fc5ca --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/110.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/111.mp3 b/site/app/partialemergence/sounds/Water/Droplets/111.mp3 Binary files differnew file mode 100644 index 0000000..d0db885 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/111.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/112.mp3 b/site/app/partialemergence/sounds/Water/Droplets/112.mp3 Binary files differnew file mode 100644 index 0000000..f34046f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/112.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/113.mp3 b/site/app/partialemergence/sounds/Water/Droplets/113.mp3 Binary files differnew file mode 100644 index 0000000..9dacb68 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/113.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/114.mp3 b/site/app/partialemergence/sounds/Water/Droplets/114.mp3 Binary files differnew file mode 100644 index 0000000..3a35979 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/114.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/115.mp3 b/site/app/partialemergence/sounds/Water/Droplets/115.mp3 Binary files differnew file mode 100644 index 0000000..602c674 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/115.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/116.mp3 b/site/app/partialemergence/sounds/Water/Droplets/116.mp3 Binary files differnew file mode 100644 index 0000000..ebf997f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/116.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/117.mp3 b/site/app/partialemergence/sounds/Water/Droplets/117.mp3 Binary files differnew file mode 100644 index 0000000..9003976 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/117.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/118.mp3 b/site/app/partialemergence/sounds/Water/Droplets/118.mp3 Binary files differnew file mode 100644 index 0000000..97134d8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/118.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/119.mp3 b/site/app/partialemergence/sounds/Water/Droplets/119.mp3 Binary files differnew file mode 100644 index 0000000..511eec9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/119.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/12.mp3 b/site/app/partialemergence/sounds/Water/Droplets/12.mp3 Binary files differnew file mode 100644 index 0000000..00d30a0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/12.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/120.mp3 b/site/app/partialemergence/sounds/Water/Droplets/120.mp3 Binary files differnew file mode 100644 index 0000000..20febc9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/120.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/121.mp3 b/site/app/partialemergence/sounds/Water/Droplets/121.mp3 Binary files differnew file mode 100644 index 0000000..3418a9d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/121.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/122.mp3 b/site/app/partialemergence/sounds/Water/Droplets/122.mp3 Binary files differnew file mode 100644 index 0000000..5610087 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/122.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/123.mp3 b/site/app/partialemergence/sounds/Water/Droplets/123.mp3 Binary files differnew file mode 100644 index 0000000..6c94232 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/123.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/124.mp3 b/site/app/partialemergence/sounds/Water/Droplets/124.mp3 Binary files differnew file mode 100644 index 0000000..6ae202e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/124.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/125.mp3 b/site/app/partialemergence/sounds/Water/Droplets/125.mp3 Binary files differnew file mode 100644 index 0000000..6347a24 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/125.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/126.mp3 b/site/app/partialemergence/sounds/Water/Droplets/126.mp3 Binary files differnew file mode 100644 index 0000000..6acefb0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/126.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/127.mp3 b/site/app/partialemergence/sounds/Water/Droplets/127.mp3 Binary files differnew file mode 100644 index 0000000..a3107f7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/127.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/128.mp3 b/site/app/partialemergence/sounds/Water/Droplets/128.mp3 Binary files differnew file mode 100644 index 0000000..38ef2c8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/128.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/129.mp3 b/site/app/partialemergence/sounds/Water/Droplets/129.mp3 Binary files differnew file mode 100644 index 0000000..9ed1ebe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/129.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/13.mp3 b/site/app/partialemergence/sounds/Water/Droplets/13.mp3 Binary files differnew file mode 100644 index 0000000..4969bb3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/13.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/130.mp3 b/site/app/partialemergence/sounds/Water/Droplets/130.mp3 Binary files differnew file mode 100644 index 0000000..c94dc91 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/130.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/131.mp3 b/site/app/partialemergence/sounds/Water/Droplets/131.mp3 Binary files differnew file mode 100644 index 0000000..e6f6a25 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/131.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/132.mp3 b/site/app/partialemergence/sounds/Water/Droplets/132.mp3 Binary files differnew file mode 100644 index 0000000..e1fc426 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/132.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/133.mp3 b/site/app/partialemergence/sounds/Water/Droplets/133.mp3 Binary files differnew file mode 100644 index 0000000..64025a7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/133.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/134.mp3 b/site/app/partialemergence/sounds/Water/Droplets/134.mp3 Binary files differnew file mode 100644 index 0000000..74a4e02 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/134.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/135.mp3 b/site/app/partialemergence/sounds/Water/Droplets/135.mp3 Binary files differnew file mode 100644 index 0000000..1942484 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/135.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/136.mp3 b/site/app/partialemergence/sounds/Water/Droplets/136.mp3 Binary files differnew file mode 100644 index 0000000..39e79fe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/136.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/137.mp3 b/site/app/partialemergence/sounds/Water/Droplets/137.mp3 Binary files differnew file mode 100644 index 0000000..e996eb3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/137.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/138.mp3 b/site/app/partialemergence/sounds/Water/Droplets/138.mp3 Binary files differnew file mode 100644 index 0000000..b6e286c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/138.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/139.mp3 b/site/app/partialemergence/sounds/Water/Droplets/139.mp3 Binary files differnew file mode 100644 index 0000000..3bbc8c1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/139.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/14.mp3 b/site/app/partialemergence/sounds/Water/Droplets/14.mp3 Binary files differnew file mode 100644 index 0000000..3a27d98 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/14.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/140.mp3 b/site/app/partialemergence/sounds/Water/Droplets/140.mp3 Binary files differnew file mode 100644 index 0000000..cfd9548 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/140.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/141.mp3 b/site/app/partialemergence/sounds/Water/Droplets/141.mp3 Binary files differnew file mode 100644 index 0000000..4354acd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/141.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/142.mp3 b/site/app/partialemergence/sounds/Water/Droplets/142.mp3 Binary files differnew file mode 100644 index 0000000..60ee6db --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/142.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/143.mp3 b/site/app/partialemergence/sounds/Water/Droplets/143.mp3 Binary files differnew file mode 100644 index 0000000..c982204 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/143.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/144.mp3 b/site/app/partialemergence/sounds/Water/Droplets/144.mp3 Binary files differnew file mode 100644 index 0000000..6473048 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/144.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/145.mp3 b/site/app/partialemergence/sounds/Water/Droplets/145.mp3 Binary files differnew file mode 100644 index 0000000..fbfa59d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/145.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/146.mp3 b/site/app/partialemergence/sounds/Water/Droplets/146.mp3 Binary files differnew file mode 100644 index 0000000..80b1535 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/146.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/147.mp3 b/site/app/partialemergence/sounds/Water/Droplets/147.mp3 Binary files differnew file mode 100644 index 0000000..bf60d3f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/147.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/148.mp3 b/site/app/partialemergence/sounds/Water/Droplets/148.mp3 Binary files differnew file mode 100644 index 0000000..5047271 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/148.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/149.mp3 b/site/app/partialemergence/sounds/Water/Droplets/149.mp3 Binary files differnew file mode 100644 index 0000000..8540c7f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/149.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/15.mp3 b/site/app/partialemergence/sounds/Water/Droplets/15.mp3 Binary files differnew file mode 100644 index 0000000..7cc1f1c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/15.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/150.mp3 b/site/app/partialemergence/sounds/Water/Droplets/150.mp3 Binary files differnew file mode 100644 index 0000000..86614d4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/150.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/151.mp3 b/site/app/partialemergence/sounds/Water/Droplets/151.mp3 Binary files differnew file mode 100644 index 0000000..c8c53ea --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/151.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/152.mp3 b/site/app/partialemergence/sounds/Water/Droplets/152.mp3 Binary files differnew file mode 100644 index 0000000..db1edd2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/152.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/153.mp3 b/site/app/partialemergence/sounds/Water/Droplets/153.mp3 Binary files differnew file mode 100644 index 0000000..fbec12f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/153.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/154.mp3 b/site/app/partialemergence/sounds/Water/Droplets/154.mp3 Binary files differnew file mode 100644 index 0000000..f9366ac --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/154.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/155.mp3 b/site/app/partialemergence/sounds/Water/Droplets/155.mp3 Binary files differnew file mode 100644 index 0000000..c1c272f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/155.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/156.mp3 b/site/app/partialemergence/sounds/Water/Droplets/156.mp3 Binary files differnew file mode 100644 index 0000000..16fa0bb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/156.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/157.mp3 b/site/app/partialemergence/sounds/Water/Droplets/157.mp3 Binary files differnew file mode 100644 index 0000000..024afd6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/157.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/158.mp3 b/site/app/partialemergence/sounds/Water/Droplets/158.mp3 Binary files differnew file mode 100644 index 0000000..f4d89c3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/158.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/159.mp3 b/site/app/partialemergence/sounds/Water/Droplets/159.mp3 Binary files differnew file mode 100644 index 0000000..61e162c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/159.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/16.mp3 b/site/app/partialemergence/sounds/Water/Droplets/16.mp3 Binary files differnew file mode 100644 index 0000000..b441307 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/16.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/160.mp3 b/site/app/partialemergence/sounds/Water/Droplets/160.mp3 Binary files differnew file mode 100644 index 0000000..72109b2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/160.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/161.mp3 b/site/app/partialemergence/sounds/Water/Droplets/161.mp3 Binary files differnew file mode 100644 index 0000000..5f45a7e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/161.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/162.mp3 b/site/app/partialemergence/sounds/Water/Droplets/162.mp3 Binary files differnew file mode 100644 index 0000000..437d56b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/162.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/163.mp3 b/site/app/partialemergence/sounds/Water/Droplets/163.mp3 Binary files differnew file mode 100644 index 0000000..107cb3c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/163.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/164.mp3 b/site/app/partialemergence/sounds/Water/Droplets/164.mp3 Binary files differnew file mode 100644 index 0000000..5d9c3ee --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/164.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/165.mp3 b/site/app/partialemergence/sounds/Water/Droplets/165.mp3 Binary files differnew file mode 100644 index 0000000..14be4ae --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/165.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/166.mp3 b/site/app/partialemergence/sounds/Water/Droplets/166.mp3 Binary files differnew file mode 100644 index 0000000..824d646 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/166.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/167.mp3 b/site/app/partialemergence/sounds/Water/Droplets/167.mp3 Binary files differnew file mode 100644 index 0000000..bcce9f1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/167.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/168.mp3 b/site/app/partialemergence/sounds/Water/Droplets/168.mp3 Binary files differnew file mode 100644 index 0000000..5405da2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/168.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/169.mp3 b/site/app/partialemergence/sounds/Water/Droplets/169.mp3 Binary files differnew file mode 100644 index 0000000..bc1cf68 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/169.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/17.mp3 b/site/app/partialemergence/sounds/Water/Droplets/17.mp3 Binary files differnew file mode 100644 index 0000000..c785d99 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/17.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/170.mp3 b/site/app/partialemergence/sounds/Water/Droplets/170.mp3 Binary files differnew file mode 100644 index 0000000..3235ff7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/170.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/171.mp3 b/site/app/partialemergence/sounds/Water/Droplets/171.mp3 Binary files differnew file mode 100644 index 0000000..1aacc16 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/171.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/172.mp3 b/site/app/partialemergence/sounds/Water/Droplets/172.mp3 Binary files differnew file mode 100644 index 0000000..0b07f05 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/172.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/173.mp3 b/site/app/partialemergence/sounds/Water/Droplets/173.mp3 Binary files differnew file mode 100644 index 0000000..30df4ea --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/173.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/174.mp3 b/site/app/partialemergence/sounds/Water/Droplets/174.mp3 Binary files differnew file mode 100644 index 0000000..641214e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/174.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/175.mp3 b/site/app/partialemergence/sounds/Water/Droplets/175.mp3 Binary files differnew file mode 100644 index 0000000..b40e8f0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/175.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/176.mp3 b/site/app/partialemergence/sounds/Water/Droplets/176.mp3 Binary files differnew file mode 100644 index 0000000..193e005 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/176.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/177.mp3 b/site/app/partialemergence/sounds/Water/Droplets/177.mp3 Binary files differnew file mode 100644 index 0000000..8e48c1c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/177.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/178.mp3 b/site/app/partialemergence/sounds/Water/Droplets/178.mp3 Binary files differnew file mode 100644 index 0000000..2182c92 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/178.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/179.mp3 b/site/app/partialemergence/sounds/Water/Droplets/179.mp3 Binary files differnew file mode 100644 index 0000000..571603d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/179.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/18.mp3 b/site/app/partialemergence/sounds/Water/Droplets/18.mp3 Binary files differnew file mode 100644 index 0000000..1a147bb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/18.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/180.mp3 b/site/app/partialemergence/sounds/Water/Droplets/180.mp3 Binary files differnew file mode 100644 index 0000000..c3ee6ec --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/180.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/181.mp3 b/site/app/partialemergence/sounds/Water/Droplets/181.mp3 Binary files differnew file mode 100644 index 0000000..4d93cbe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/181.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/182.mp3 b/site/app/partialemergence/sounds/Water/Droplets/182.mp3 Binary files differnew file mode 100644 index 0000000..a5faa54 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/182.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/183.mp3 b/site/app/partialemergence/sounds/Water/Droplets/183.mp3 Binary files differnew file mode 100644 index 0000000..7f09888 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/183.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/184.mp3 b/site/app/partialemergence/sounds/Water/Droplets/184.mp3 Binary files differnew file mode 100644 index 0000000..5659860 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/184.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/185.mp3 b/site/app/partialemergence/sounds/Water/Droplets/185.mp3 Binary files differnew file mode 100644 index 0000000..88961dc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/185.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/186.mp3 b/site/app/partialemergence/sounds/Water/Droplets/186.mp3 Binary files differnew file mode 100644 index 0000000..4082715 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/186.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/187.mp3 b/site/app/partialemergence/sounds/Water/Droplets/187.mp3 Binary files differnew file mode 100644 index 0000000..d61dabb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/187.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/188.mp3 b/site/app/partialemergence/sounds/Water/Droplets/188.mp3 Binary files differnew file mode 100644 index 0000000..491371a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/188.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/189.mp3 b/site/app/partialemergence/sounds/Water/Droplets/189.mp3 Binary files differnew file mode 100644 index 0000000..89d3dec --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/189.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/19.mp3 b/site/app/partialemergence/sounds/Water/Droplets/19.mp3 Binary files differnew file mode 100644 index 0000000..65ea735 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/19.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/190.mp3 b/site/app/partialemergence/sounds/Water/Droplets/190.mp3 Binary files differnew file mode 100644 index 0000000..7793dbb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/190.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/191.mp3 b/site/app/partialemergence/sounds/Water/Droplets/191.mp3 Binary files differnew file mode 100644 index 0000000..d0fbc3d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/191.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/192.mp3 b/site/app/partialemergence/sounds/Water/Droplets/192.mp3 Binary files differnew file mode 100644 index 0000000..3bd54e5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/192.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/193.mp3 b/site/app/partialemergence/sounds/Water/Droplets/193.mp3 Binary files differnew file mode 100644 index 0000000..5e17fff --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/193.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/194.mp3 b/site/app/partialemergence/sounds/Water/Droplets/194.mp3 Binary files differnew file mode 100644 index 0000000..72ccc55 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/194.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/195.mp3 b/site/app/partialemergence/sounds/Water/Droplets/195.mp3 Binary files differnew file mode 100644 index 0000000..f147a05 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/195.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/196.mp3 b/site/app/partialemergence/sounds/Water/Droplets/196.mp3 Binary files differnew file mode 100644 index 0000000..79a31ef --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/196.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/197.mp3 b/site/app/partialemergence/sounds/Water/Droplets/197.mp3 Binary files differnew file mode 100644 index 0000000..bd79dc5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/197.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/198.mp3 b/site/app/partialemergence/sounds/Water/Droplets/198.mp3 Binary files differnew file mode 100644 index 0000000..1027cc0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/198.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/199.mp3 b/site/app/partialemergence/sounds/Water/Droplets/199.mp3 Binary files differnew file mode 100644 index 0000000..384dacb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/199.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/2.mp3 b/site/app/partialemergence/sounds/Water/Droplets/2.mp3 Binary files differnew file mode 100644 index 0000000..251f5aa --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/2.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/20.mp3 b/site/app/partialemergence/sounds/Water/Droplets/20.mp3 Binary files differnew file mode 100644 index 0000000..1c14b38 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/20.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/200.mp3 b/site/app/partialemergence/sounds/Water/Droplets/200.mp3 Binary files differnew file mode 100644 index 0000000..1fa9685 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/200.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/201.mp3 b/site/app/partialemergence/sounds/Water/Droplets/201.mp3 Binary files differnew file mode 100644 index 0000000..ad7579d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/201.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/202.mp3 b/site/app/partialemergence/sounds/Water/Droplets/202.mp3 Binary files differnew file mode 100644 index 0000000..f23980b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/202.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/203.mp3 b/site/app/partialemergence/sounds/Water/Droplets/203.mp3 Binary files differnew file mode 100644 index 0000000..431ca56 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/203.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/204.mp3 b/site/app/partialemergence/sounds/Water/Droplets/204.mp3 Binary files differnew file mode 100644 index 0000000..a327123 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/204.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/205.mp3 b/site/app/partialemergence/sounds/Water/Droplets/205.mp3 Binary files differnew file mode 100644 index 0000000..8095ab0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/205.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/206.mp3 b/site/app/partialemergence/sounds/Water/Droplets/206.mp3 Binary files differnew file mode 100644 index 0000000..3f70218 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/206.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/207.mp3 b/site/app/partialemergence/sounds/Water/Droplets/207.mp3 Binary files differnew file mode 100644 index 0000000..7e22b0e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/207.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/208.mp3 b/site/app/partialemergence/sounds/Water/Droplets/208.mp3 Binary files differnew file mode 100644 index 0000000..e5c5763 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/208.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/209.mp3 b/site/app/partialemergence/sounds/Water/Droplets/209.mp3 Binary files differnew file mode 100644 index 0000000..2aa7463 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/209.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/21.mp3 b/site/app/partialemergence/sounds/Water/Droplets/21.mp3 Binary files differnew file mode 100644 index 0000000..7eda693 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/21.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/210.mp3 b/site/app/partialemergence/sounds/Water/Droplets/210.mp3 Binary files differnew file mode 100644 index 0000000..46b9d22 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/210.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/211.mp3 b/site/app/partialemergence/sounds/Water/Droplets/211.mp3 Binary files differnew file mode 100644 index 0000000..1b2d79f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/211.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/212.mp3 b/site/app/partialemergence/sounds/Water/Droplets/212.mp3 Binary files differnew file mode 100644 index 0000000..f38a38b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/212.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/213.mp3 b/site/app/partialemergence/sounds/Water/Droplets/213.mp3 Binary files differnew file mode 100644 index 0000000..2c17a95 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/213.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/214.mp3 b/site/app/partialemergence/sounds/Water/Droplets/214.mp3 Binary files differnew file mode 100644 index 0000000..de5f549 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/214.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/215.mp3 b/site/app/partialemergence/sounds/Water/Droplets/215.mp3 Binary files differnew file mode 100644 index 0000000..72dd43e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/215.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/216.mp3 b/site/app/partialemergence/sounds/Water/Droplets/216.mp3 Binary files differnew file mode 100644 index 0000000..ac2fd00 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/216.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/217.mp3 b/site/app/partialemergence/sounds/Water/Droplets/217.mp3 Binary files differnew file mode 100644 index 0000000..47d3af1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/217.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/218.mp3 b/site/app/partialemergence/sounds/Water/Droplets/218.mp3 Binary files differnew file mode 100644 index 0000000..33d7396 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/218.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/219.mp3 b/site/app/partialemergence/sounds/Water/Droplets/219.mp3 Binary files differnew file mode 100644 index 0000000..35996e1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/219.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/22.mp3 b/site/app/partialemergence/sounds/Water/Droplets/22.mp3 Binary files differnew file mode 100644 index 0000000..96668cf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/22.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/220.mp3 b/site/app/partialemergence/sounds/Water/Droplets/220.mp3 Binary files differnew file mode 100644 index 0000000..a9c02c4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/220.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/221.mp3 b/site/app/partialemergence/sounds/Water/Droplets/221.mp3 Binary files differnew file mode 100644 index 0000000..444c48a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/221.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/222.mp3 b/site/app/partialemergence/sounds/Water/Droplets/222.mp3 Binary files differnew file mode 100644 index 0000000..7c43205 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/222.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/223.mp3 b/site/app/partialemergence/sounds/Water/Droplets/223.mp3 Binary files differnew file mode 100644 index 0000000..cd7f5a1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/223.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/224.mp3 b/site/app/partialemergence/sounds/Water/Droplets/224.mp3 Binary files differnew file mode 100644 index 0000000..1d085ab --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/224.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/225.mp3 b/site/app/partialemergence/sounds/Water/Droplets/225.mp3 Binary files differnew file mode 100644 index 0000000..f031965 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/225.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/226.mp3 b/site/app/partialemergence/sounds/Water/Droplets/226.mp3 Binary files differnew file mode 100644 index 0000000..4ce8c42 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/226.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/227.mp3 b/site/app/partialemergence/sounds/Water/Droplets/227.mp3 Binary files differnew file mode 100644 index 0000000..8b7f0c9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/227.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/228.mp3 b/site/app/partialemergence/sounds/Water/Droplets/228.mp3 Binary files differnew file mode 100644 index 0000000..6c2a9ec --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/228.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/229.mp3 b/site/app/partialemergence/sounds/Water/Droplets/229.mp3 Binary files differnew file mode 100644 index 0000000..5dda72a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/229.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/23.mp3 b/site/app/partialemergence/sounds/Water/Droplets/23.mp3 Binary files differnew file mode 100644 index 0000000..5c752ce --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/23.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/230.mp3 b/site/app/partialemergence/sounds/Water/Droplets/230.mp3 Binary files differnew file mode 100644 index 0000000..6a40553 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/230.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/231.mp3 b/site/app/partialemergence/sounds/Water/Droplets/231.mp3 Binary files differnew file mode 100644 index 0000000..720940e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/231.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/232.mp3 b/site/app/partialemergence/sounds/Water/Droplets/232.mp3 Binary files differnew file mode 100644 index 0000000..a8d8cee --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/232.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/233.mp3 b/site/app/partialemergence/sounds/Water/Droplets/233.mp3 Binary files differnew file mode 100644 index 0000000..549ca4b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/233.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/234.mp3 b/site/app/partialemergence/sounds/Water/Droplets/234.mp3 Binary files differnew file mode 100644 index 0000000..12ed374 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/234.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/235.mp3 b/site/app/partialemergence/sounds/Water/Droplets/235.mp3 Binary files differnew file mode 100644 index 0000000..165bdce --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/235.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/236.mp3 b/site/app/partialemergence/sounds/Water/Droplets/236.mp3 Binary files differnew file mode 100644 index 0000000..8594d4c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/236.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/237.mp3 b/site/app/partialemergence/sounds/Water/Droplets/237.mp3 Binary files differnew file mode 100644 index 0000000..5955f00 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/237.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/238.mp3 b/site/app/partialemergence/sounds/Water/Droplets/238.mp3 Binary files differnew file mode 100644 index 0000000..de9f350 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/238.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/239.mp3 b/site/app/partialemergence/sounds/Water/Droplets/239.mp3 Binary files differnew file mode 100644 index 0000000..08a2946 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/239.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/24.mp3 b/site/app/partialemergence/sounds/Water/Droplets/24.mp3 Binary files differnew file mode 100644 index 0000000..8f35505 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/24.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/240.mp3 b/site/app/partialemergence/sounds/Water/Droplets/240.mp3 Binary files differnew file mode 100644 index 0000000..2481a60 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/240.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/241.mp3 b/site/app/partialemergence/sounds/Water/Droplets/241.mp3 Binary files differnew file mode 100644 index 0000000..587d0ca --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/241.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/242.mp3 b/site/app/partialemergence/sounds/Water/Droplets/242.mp3 Binary files differnew file mode 100644 index 0000000..b863534 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/242.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/243.mp3 b/site/app/partialemergence/sounds/Water/Droplets/243.mp3 Binary files differnew file mode 100644 index 0000000..7257503 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/243.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/244.mp3 b/site/app/partialemergence/sounds/Water/Droplets/244.mp3 Binary files differnew file mode 100644 index 0000000..e23c6c1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/244.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/245.mp3 b/site/app/partialemergence/sounds/Water/Droplets/245.mp3 Binary files differnew file mode 100644 index 0000000..b501f78 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/245.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/246.mp3 b/site/app/partialemergence/sounds/Water/Droplets/246.mp3 Binary files differnew file mode 100644 index 0000000..d0d0387 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/246.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/247.mp3 b/site/app/partialemergence/sounds/Water/Droplets/247.mp3 Binary files differnew file mode 100644 index 0000000..765a27c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/247.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/248.mp3 b/site/app/partialemergence/sounds/Water/Droplets/248.mp3 Binary files differnew file mode 100644 index 0000000..34823a2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/248.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/249.mp3 b/site/app/partialemergence/sounds/Water/Droplets/249.mp3 Binary files differnew file mode 100644 index 0000000..9a2d7e4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/249.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/25.mp3 b/site/app/partialemergence/sounds/Water/Droplets/25.mp3 Binary files differnew file mode 100644 index 0000000..57c023e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/25.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/250.mp3 b/site/app/partialemergence/sounds/Water/Droplets/250.mp3 Binary files differnew file mode 100644 index 0000000..58ca626 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/250.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/251.mp3 b/site/app/partialemergence/sounds/Water/Droplets/251.mp3 Binary files differnew file mode 100644 index 0000000..4130d2a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/251.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/252.mp3 b/site/app/partialemergence/sounds/Water/Droplets/252.mp3 Binary files differnew file mode 100644 index 0000000..f1e3193 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/252.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/253.mp3 b/site/app/partialemergence/sounds/Water/Droplets/253.mp3 Binary files differnew file mode 100644 index 0000000..546b04c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/253.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/254.mp3 b/site/app/partialemergence/sounds/Water/Droplets/254.mp3 Binary files differnew file mode 100644 index 0000000..a1a66bd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/254.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/255.mp3 b/site/app/partialemergence/sounds/Water/Droplets/255.mp3 Binary files differnew file mode 100644 index 0000000..f2eeadf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/255.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/256.mp3 b/site/app/partialemergence/sounds/Water/Droplets/256.mp3 Binary files differnew file mode 100644 index 0000000..a426113 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/256.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/257.mp3 b/site/app/partialemergence/sounds/Water/Droplets/257.mp3 Binary files differnew file mode 100644 index 0000000..2482688 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/257.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/258.mp3 b/site/app/partialemergence/sounds/Water/Droplets/258.mp3 Binary files differnew file mode 100644 index 0000000..7b761ea --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/258.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/259.mp3 b/site/app/partialemergence/sounds/Water/Droplets/259.mp3 Binary files differnew file mode 100644 index 0000000..6828e2f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/259.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/26.mp3 b/site/app/partialemergence/sounds/Water/Droplets/26.mp3 Binary files differnew file mode 100644 index 0000000..abb4803 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/26.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/260.mp3 b/site/app/partialemergence/sounds/Water/Droplets/260.mp3 Binary files differnew file mode 100644 index 0000000..1da1ce7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/260.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/261.mp3 b/site/app/partialemergence/sounds/Water/Droplets/261.mp3 Binary files differnew file mode 100644 index 0000000..de6b115 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/261.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/262.mp3 b/site/app/partialemergence/sounds/Water/Droplets/262.mp3 Binary files differnew file mode 100644 index 0000000..cd1f7f3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/262.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/263.mp3 b/site/app/partialemergence/sounds/Water/Droplets/263.mp3 Binary files differnew file mode 100644 index 0000000..f1c25d8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/263.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/264.mp3 b/site/app/partialemergence/sounds/Water/Droplets/264.mp3 Binary files differnew file mode 100644 index 0000000..1364fb0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/264.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/265.mp3 b/site/app/partialemergence/sounds/Water/Droplets/265.mp3 Binary files differnew file mode 100644 index 0000000..8821a5c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/265.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/266.mp3 b/site/app/partialemergence/sounds/Water/Droplets/266.mp3 Binary files differnew file mode 100644 index 0000000..30885e0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/266.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/267.mp3 b/site/app/partialemergence/sounds/Water/Droplets/267.mp3 Binary files differnew file mode 100644 index 0000000..f647958 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/267.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/268.mp3 b/site/app/partialemergence/sounds/Water/Droplets/268.mp3 Binary files differnew file mode 100644 index 0000000..032d6e2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/268.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/269.mp3 b/site/app/partialemergence/sounds/Water/Droplets/269.mp3 Binary files differnew file mode 100644 index 0000000..06dcc69 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/269.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/27.mp3 b/site/app/partialemergence/sounds/Water/Droplets/27.mp3 Binary files differnew file mode 100644 index 0000000..0fce697 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/27.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/270.mp3 b/site/app/partialemergence/sounds/Water/Droplets/270.mp3 Binary files differnew file mode 100644 index 0000000..412e8b6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/270.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/271.mp3 b/site/app/partialemergence/sounds/Water/Droplets/271.mp3 Binary files differnew file mode 100644 index 0000000..3895a9d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/271.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/272.mp3 b/site/app/partialemergence/sounds/Water/Droplets/272.mp3 Binary files differnew file mode 100644 index 0000000..a606972 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/272.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/273.mp3 b/site/app/partialemergence/sounds/Water/Droplets/273.mp3 Binary files differnew file mode 100644 index 0000000..2d766eb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/273.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/274.mp3 b/site/app/partialemergence/sounds/Water/Droplets/274.mp3 Binary files differnew file mode 100644 index 0000000..0b60243 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/274.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/275.mp3 b/site/app/partialemergence/sounds/Water/Droplets/275.mp3 Binary files differnew file mode 100644 index 0000000..5913ac4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/275.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/276.mp3 b/site/app/partialemergence/sounds/Water/Droplets/276.mp3 Binary files differnew file mode 100644 index 0000000..567e666 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/276.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/277.mp3 b/site/app/partialemergence/sounds/Water/Droplets/277.mp3 Binary files differnew file mode 100644 index 0000000..88653ea --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/277.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/278.mp3 b/site/app/partialemergence/sounds/Water/Droplets/278.mp3 Binary files differnew file mode 100644 index 0000000..04beb99 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/278.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/279.mp3 b/site/app/partialemergence/sounds/Water/Droplets/279.mp3 Binary files differnew file mode 100644 index 0000000..0a8980b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/279.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/28.mp3 b/site/app/partialemergence/sounds/Water/Droplets/28.mp3 Binary files differnew file mode 100644 index 0000000..55efe81 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/28.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/280.mp3 b/site/app/partialemergence/sounds/Water/Droplets/280.mp3 Binary files differnew file mode 100644 index 0000000..380d4af --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/280.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/281.mp3 b/site/app/partialemergence/sounds/Water/Droplets/281.mp3 Binary files differnew file mode 100644 index 0000000..28e1116 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/281.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/282.mp3 b/site/app/partialemergence/sounds/Water/Droplets/282.mp3 Binary files differnew file mode 100644 index 0000000..a097e26 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/282.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/283.mp3 b/site/app/partialemergence/sounds/Water/Droplets/283.mp3 Binary files differnew file mode 100644 index 0000000..a77ef30 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/283.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/284.mp3 b/site/app/partialemergence/sounds/Water/Droplets/284.mp3 Binary files differnew file mode 100644 index 0000000..cc881cb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/284.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/285.mp3 b/site/app/partialemergence/sounds/Water/Droplets/285.mp3 Binary files differnew file mode 100644 index 0000000..7d4c9a7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/285.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/286.mp3 b/site/app/partialemergence/sounds/Water/Droplets/286.mp3 Binary files differnew file mode 100644 index 0000000..d8a8911 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/286.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/287.mp3 b/site/app/partialemergence/sounds/Water/Droplets/287.mp3 Binary files differnew file mode 100644 index 0000000..7763ace --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/287.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/288.mp3 b/site/app/partialemergence/sounds/Water/Droplets/288.mp3 Binary files differnew file mode 100644 index 0000000..e900cf8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/288.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/289.mp3 b/site/app/partialemergence/sounds/Water/Droplets/289.mp3 Binary files differnew file mode 100644 index 0000000..820e172 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/289.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/29.mp3 b/site/app/partialemergence/sounds/Water/Droplets/29.mp3 Binary files differnew file mode 100644 index 0000000..d209f98 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/29.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/290.mp3 b/site/app/partialemergence/sounds/Water/Droplets/290.mp3 Binary files differnew file mode 100644 index 0000000..08659c3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/290.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/291.mp3 b/site/app/partialemergence/sounds/Water/Droplets/291.mp3 Binary files differnew file mode 100644 index 0000000..cbd8283 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/291.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/292.mp3 b/site/app/partialemergence/sounds/Water/Droplets/292.mp3 Binary files differnew file mode 100644 index 0000000..fe5997f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/292.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/293.mp3 b/site/app/partialemergence/sounds/Water/Droplets/293.mp3 Binary files differnew file mode 100644 index 0000000..9caee62 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/293.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/294.mp3 b/site/app/partialemergence/sounds/Water/Droplets/294.mp3 Binary files differnew file mode 100644 index 0000000..cab7176 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/294.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/295.mp3 b/site/app/partialemergence/sounds/Water/Droplets/295.mp3 Binary files differnew file mode 100644 index 0000000..20d52e5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/295.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/296.mp3 b/site/app/partialemergence/sounds/Water/Droplets/296.mp3 Binary files differnew file mode 100644 index 0000000..7387fe1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/296.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/297.mp3 b/site/app/partialemergence/sounds/Water/Droplets/297.mp3 Binary files differnew file mode 100644 index 0000000..e6f60f5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/297.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/298.mp3 b/site/app/partialemergence/sounds/Water/Droplets/298.mp3 Binary files differnew file mode 100644 index 0000000..4cc0213 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/298.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/299.mp3 b/site/app/partialemergence/sounds/Water/Droplets/299.mp3 Binary files differnew file mode 100644 index 0000000..61c3eff --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/299.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/3.mp3 b/site/app/partialemergence/sounds/Water/Droplets/3.mp3 Binary files differnew file mode 100644 index 0000000..658418f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/3.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/30.mp3 b/site/app/partialemergence/sounds/Water/Droplets/30.mp3 Binary files differnew file mode 100644 index 0000000..05a46b9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/30.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/300.mp3 b/site/app/partialemergence/sounds/Water/Droplets/300.mp3 Binary files differnew file mode 100644 index 0000000..5e70e79 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/300.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/301.mp3 b/site/app/partialemergence/sounds/Water/Droplets/301.mp3 Binary files differnew file mode 100644 index 0000000..542de58 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/301.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/302.mp3 b/site/app/partialemergence/sounds/Water/Droplets/302.mp3 Binary files differnew file mode 100644 index 0000000..9dc534a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/302.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/303.mp3 b/site/app/partialemergence/sounds/Water/Droplets/303.mp3 Binary files differnew file mode 100644 index 0000000..247884c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/303.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/304.mp3 b/site/app/partialemergence/sounds/Water/Droplets/304.mp3 Binary files differnew file mode 100644 index 0000000..ff9c8a8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/304.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/305.mp3 b/site/app/partialemergence/sounds/Water/Droplets/305.mp3 Binary files differnew file mode 100644 index 0000000..e46c3e7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/305.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/306.mp3 b/site/app/partialemergence/sounds/Water/Droplets/306.mp3 Binary files differnew file mode 100644 index 0000000..9961c91 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/306.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/307.mp3 b/site/app/partialemergence/sounds/Water/Droplets/307.mp3 Binary files differnew file mode 100644 index 0000000..39fd980 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/307.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/308.mp3 b/site/app/partialemergence/sounds/Water/Droplets/308.mp3 Binary files differnew file mode 100644 index 0000000..bc77ec4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/308.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/309.mp3 b/site/app/partialemergence/sounds/Water/Droplets/309.mp3 Binary files differnew file mode 100644 index 0000000..f45ea3f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/309.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/31.mp3 b/site/app/partialemergence/sounds/Water/Droplets/31.mp3 Binary files differnew file mode 100644 index 0000000..3be7b75 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/31.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/310.mp3 b/site/app/partialemergence/sounds/Water/Droplets/310.mp3 Binary files differnew file mode 100644 index 0000000..a8a1f9d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/310.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/311.mp3 b/site/app/partialemergence/sounds/Water/Droplets/311.mp3 Binary files differnew file mode 100644 index 0000000..805802c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/311.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/312.mp3 b/site/app/partialemergence/sounds/Water/Droplets/312.mp3 Binary files differnew file mode 100644 index 0000000..929d59a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/312.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/313.mp3 b/site/app/partialemergence/sounds/Water/Droplets/313.mp3 Binary files differnew file mode 100644 index 0000000..3f9a989 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/313.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/314.mp3 b/site/app/partialemergence/sounds/Water/Droplets/314.mp3 Binary files differnew file mode 100644 index 0000000..959d11a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/314.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/315.mp3 b/site/app/partialemergence/sounds/Water/Droplets/315.mp3 Binary files differnew file mode 100644 index 0000000..d854229 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/315.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/316.mp3 b/site/app/partialemergence/sounds/Water/Droplets/316.mp3 Binary files differnew file mode 100644 index 0000000..c86e1ce --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/316.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/317.mp3 b/site/app/partialemergence/sounds/Water/Droplets/317.mp3 Binary files differnew file mode 100644 index 0000000..5118364 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/317.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/318.mp3 b/site/app/partialemergence/sounds/Water/Droplets/318.mp3 Binary files differnew file mode 100644 index 0000000..0918fee --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/318.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/319.mp3 b/site/app/partialemergence/sounds/Water/Droplets/319.mp3 Binary files differnew file mode 100644 index 0000000..5dc6067 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/319.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/32.mp3 b/site/app/partialemergence/sounds/Water/Droplets/32.mp3 Binary files differnew file mode 100644 index 0000000..4cd64c5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/32.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/320.mp3 b/site/app/partialemergence/sounds/Water/Droplets/320.mp3 Binary files differnew file mode 100644 index 0000000..2551027 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/320.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/321.mp3 b/site/app/partialemergence/sounds/Water/Droplets/321.mp3 Binary files differnew file mode 100644 index 0000000..1254684 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/321.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/322.mp3 b/site/app/partialemergence/sounds/Water/Droplets/322.mp3 Binary files differnew file mode 100644 index 0000000..a8b4761 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/322.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/323.mp3 b/site/app/partialemergence/sounds/Water/Droplets/323.mp3 Binary files differnew file mode 100644 index 0000000..09d3361 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/323.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/324.mp3 b/site/app/partialemergence/sounds/Water/Droplets/324.mp3 Binary files differnew file mode 100644 index 0000000..9ac169a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/324.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/325.mp3 b/site/app/partialemergence/sounds/Water/Droplets/325.mp3 Binary files differnew file mode 100644 index 0000000..c5dd7dd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/325.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/326.mp3 b/site/app/partialemergence/sounds/Water/Droplets/326.mp3 Binary files differnew file mode 100644 index 0000000..fd83c64 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/326.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/327.mp3 b/site/app/partialemergence/sounds/Water/Droplets/327.mp3 Binary files differnew file mode 100644 index 0000000..2e520fc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/327.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/328.mp3 b/site/app/partialemergence/sounds/Water/Droplets/328.mp3 Binary files differnew file mode 100644 index 0000000..006735d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/328.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/329.mp3 b/site/app/partialemergence/sounds/Water/Droplets/329.mp3 Binary files differnew file mode 100644 index 0000000..d2b1845 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/329.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/33.mp3 b/site/app/partialemergence/sounds/Water/Droplets/33.mp3 Binary files differnew file mode 100644 index 0000000..0ffdf5b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/33.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/330.mp3 b/site/app/partialemergence/sounds/Water/Droplets/330.mp3 Binary files differnew file mode 100644 index 0000000..8be7309 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/330.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/331.mp3 b/site/app/partialemergence/sounds/Water/Droplets/331.mp3 Binary files differnew file mode 100644 index 0000000..0b8568a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/331.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/332.mp3 b/site/app/partialemergence/sounds/Water/Droplets/332.mp3 Binary files differnew file mode 100644 index 0000000..99a50e4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/332.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/333.mp3 b/site/app/partialemergence/sounds/Water/Droplets/333.mp3 Binary files differnew file mode 100644 index 0000000..8b16f23 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/333.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/334.mp3 b/site/app/partialemergence/sounds/Water/Droplets/334.mp3 Binary files differnew file mode 100644 index 0000000..f1c17f2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/334.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/335.mp3 b/site/app/partialemergence/sounds/Water/Droplets/335.mp3 Binary files differnew file mode 100644 index 0000000..7e8bdfb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/335.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/336.mp3 b/site/app/partialemergence/sounds/Water/Droplets/336.mp3 Binary files differnew file mode 100644 index 0000000..683c8b1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/336.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/337.mp3 b/site/app/partialemergence/sounds/Water/Droplets/337.mp3 Binary files differnew file mode 100644 index 0000000..db5f72c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/337.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/338.mp3 b/site/app/partialemergence/sounds/Water/Droplets/338.mp3 Binary files differnew file mode 100644 index 0000000..ccc8798 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/338.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/339.mp3 b/site/app/partialemergence/sounds/Water/Droplets/339.mp3 Binary files differnew file mode 100644 index 0000000..84cb648 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/339.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/34.mp3 b/site/app/partialemergence/sounds/Water/Droplets/34.mp3 Binary files differnew file mode 100644 index 0000000..472b245 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/34.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/340.mp3 b/site/app/partialemergence/sounds/Water/Droplets/340.mp3 Binary files differnew file mode 100644 index 0000000..911dd49 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/340.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/341.mp3 b/site/app/partialemergence/sounds/Water/Droplets/341.mp3 Binary files differnew file mode 100644 index 0000000..59aa242 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/341.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/342.mp3 b/site/app/partialemergence/sounds/Water/Droplets/342.mp3 Binary files differnew file mode 100644 index 0000000..c717bde --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/342.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/343.mp3 b/site/app/partialemergence/sounds/Water/Droplets/343.mp3 Binary files differnew file mode 100644 index 0000000..99be7f2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/343.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/344.mp3 b/site/app/partialemergence/sounds/Water/Droplets/344.mp3 Binary files differnew file mode 100644 index 0000000..54943dc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/344.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/345.mp3 b/site/app/partialemergence/sounds/Water/Droplets/345.mp3 Binary files differnew file mode 100644 index 0000000..613c7e0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/345.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/346.mp3 b/site/app/partialemergence/sounds/Water/Droplets/346.mp3 Binary files differnew file mode 100644 index 0000000..5c798fe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/346.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/347.mp3 b/site/app/partialemergence/sounds/Water/Droplets/347.mp3 Binary files differnew file mode 100644 index 0000000..6a81894 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/347.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/348.mp3 b/site/app/partialemergence/sounds/Water/Droplets/348.mp3 Binary files differnew file mode 100644 index 0000000..8c986ba --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/348.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/349.mp3 b/site/app/partialemergence/sounds/Water/Droplets/349.mp3 Binary files differnew file mode 100644 index 0000000..5782791 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/349.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/35.mp3 b/site/app/partialemergence/sounds/Water/Droplets/35.mp3 Binary files differnew file mode 100644 index 0000000..1274b7c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/35.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/350.mp3 b/site/app/partialemergence/sounds/Water/Droplets/350.mp3 Binary files differnew file mode 100644 index 0000000..9a79241 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/350.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/351.mp3 b/site/app/partialemergence/sounds/Water/Droplets/351.mp3 Binary files differnew file mode 100644 index 0000000..ba3f75b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/351.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/352.mp3 b/site/app/partialemergence/sounds/Water/Droplets/352.mp3 Binary files differnew file mode 100644 index 0000000..e9b9bd8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/352.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/353.mp3 b/site/app/partialemergence/sounds/Water/Droplets/353.mp3 Binary files differnew file mode 100644 index 0000000..763401c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/353.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/354.mp3 b/site/app/partialemergence/sounds/Water/Droplets/354.mp3 Binary files differnew file mode 100644 index 0000000..09881f4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/354.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/355.mp3 b/site/app/partialemergence/sounds/Water/Droplets/355.mp3 Binary files differnew file mode 100644 index 0000000..61534cf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/355.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/356.mp3 b/site/app/partialemergence/sounds/Water/Droplets/356.mp3 Binary files differnew file mode 100644 index 0000000..3e7dfc0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/356.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/357.mp3 b/site/app/partialemergence/sounds/Water/Droplets/357.mp3 Binary files differnew file mode 100644 index 0000000..bb3babf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/357.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/358.mp3 b/site/app/partialemergence/sounds/Water/Droplets/358.mp3 Binary files differnew file mode 100644 index 0000000..9864a4b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/358.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/359.mp3 b/site/app/partialemergence/sounds/Water/Droplets/359.mp3 Binary files differnew file mode 100644 index 0000000..3f48321 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/359.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/36.mp3 b/site/app/partialemergence/sounds/Water/Droplets/36.mp3 Binary files differnew file mode 100644 index 0000000..1a775dc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/36.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/360.mp3 b/site/app/partialemergence/sounds/Water/Droplets/360.mp3 Binary files differnew file mode 100644 index 0000000..0a0a3d5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/360.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/361.mp3 b/site/app/partialemergence/sounds/Water/Droplets/361.mp3 Binary files differnew file mode 100644 index 0000000..0943c3c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/361.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/362.mp3 b/site/app/partialemergence/sounds/Water/Droplets/362.mp3 Binary files differnew file mode 100644 index 0000000..5564f64 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/362.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/363.mp3 b/site/app/partialemergence/sounds/Water/Droplets/363.mp3 Binary files differnew file mode 100644 index 0000000..87192c0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/363.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/364.mp3 b/site/app/partialemergence/sounds/Water/Droplets/364.mp3 Binary files differnew file mode 100644 index 0000000..a4785b2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/364.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/365.mp3 b/site/app/partialemergence/sounds/Water/Droplets/365.mp3 Binary files differnew file mode 100644 index 0000000..897393c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/365.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/366.mp3 b/site/app/partialemergence/sounds/Water/Droplets/366.mp3 Binary files differnew file mode 100644 index 0000000..f2cf146 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/366.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/367.mp3 b/site/app/partialemergence/sounds/Water/Droplets/367.mp3 Binary files differnew file mode 100644 index 0000000..a1d6163 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/367.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/368.mp3 b/site/app/partialemergence/sounds/Water/Droplets/368.mp3 Binary files differnew file mode 100644 index 0000000..2760769 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/368.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/369.mp3 b/site/app/partialemergence/sounds/Water/Droplets/369.mp3 Binary files differnew file mode 100644 index 0000000..2620a2a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/369.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/37.mp3 b/site/app/partialemergence/sounds/Water/Droplets/37.mp3 Binary files differnew file mode 100644 index 0000000..b86e36c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/37.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/370.mp3 b/site/app/partialemergence/sounds/Water/Droplets/370.mp3 Binary files differnew file mode 100644 index 0000000..f6a2dfd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/370.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/371.mp3 b/site/app/partialemergence/sounds/Water/Droplets/371.mp3 Binary files differnew file mode 100644 index 0000000..de222cd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/371.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/372.mp3 b/site/app/partialemergence/sounds/Water/Droplets/372.mp3 Binary files differnew file mode 100644 index 0000000..d22d0d8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/372.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/373.mp3 b/site/app/partialemergence/sounds/Water/Droplets/373.mp3 Binary files differnew file mode 100644 index 0000000..ce1c786 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/373.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/374.mp3 b/site/app/partialemergence/sounds/Water/Droplets/374.mp3 Binary files differnew file mode 100644 index 0000000..d682d6d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/374.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/375.mp3 b/site/app/partialemergence/sounds/Water/Droplets/375.mp3 Binary files differnew file mode 100644 index 0000000..3e0fd0b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/375.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/376.mp3 b/site/app/partialemergence/sounds/Water/Droplets/376.mp3 Binary files differnew file mode 100644 index 0000000..6851a65 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/376.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/377.mp3 b/site/app/partialemergence/sounds/Water/Droplets/377.mp3 Binary files differnew file mode 100644 index 0000000..1e97ddb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/377.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/378.mp3 b/site/app/partialemergence/sounds/Water/Droplets/378.mp3 Binary files differnew file mode 100644 index 0000000..afc2478 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/378.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/379.mp3 b/site/app/partialemergence/sounds/Water/Droplets/379.mp3 Binary files differnew file mode 100644 index 0000000..fe1bd6f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/379.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/38.mp3 b/site/app/partialemergence/sounds/Water/Droplets/38.mp3 Binary files differnew file mode 100644 index 0000000..2ca366c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/38.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/380.mp3 b/site/app/partialemergence/sounds/Water/Droplets/380.mp3 Binary files differnew file mode 100644 index 0000000..159c232 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/380.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/381.mp3 b/site/app/partialemergence/sounds/Water/Droplets/381.mp3 Binary files differnew file mode 100644 index 0000000..22709cf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/381.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/382.mp3 b/site/app/partialemergence/sounds/Water/Droplets/382.mp3 Binary files differnew file mode 100644 index 0000000..af0dbc6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/382.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/383.mp3 b/site/app/partialemergence/sounds/Water/Droplets/383.mp3 Binary files differnew file mode 100644 index 0000000..c50c3c8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/383.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/384.mp3 b/site/app/partialemergence/sounds/Water/Droplets/384.mp3 Binary files differnew file mode 100644 index 0000000..07ad65a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/384.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/385.mp3 b/site/app/partialemergence/sounds/Water/Droplets/385.mp3 Binary files differnew file mode 100644 index 0000000..5fb2f61 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/385.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/386.mp3 b/site/app/partialemergence/sounds/Water/Droplets/386.mp3 Binary files differnew file mode 100644 index 0000000..4a383db --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/386.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/387.mp3 b/site/app/partialemergence/sounds/Water/Droplets/387.mp3 Binary files differnew file mode 100644 index 0000000..bbb51b0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/387.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/388.mp3 b/site/app/partialemergence/sounds/Water/Droplets/388.mp3 Binary files differnew file mode 100644 index 0000000..6eeed7c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/388.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/389.mp3 b/site/app/partialemergence/sounds/Water/Droplets/389.mp3 Binary files differnew file mode 100644 index 0000000..8890751 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/389.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/39.mp3 b/site/app/partialemergence/sounds/Water/Droplets/39.mp3 Binary files differnew file mode 100644 index 0000000..0747981 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/39.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/390.mp3 b/site/app/partialemergence/sounds/Water/Droplets/390.mp3 Binary files differnew file mode 100644 index 0000000..e70a9c5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/390.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/391.mp3 b/site/app/partialemergence/sounds/Water/Droplets/391.mp3 Binary files differnew file mode 100644 index 0000000..c50c6db --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/391.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/392.mp3 b/site/app/partialemergence/sounds/Water/Droplets/392.mp3 Binary files differnew file mode 100644 index 0000000..1350525 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/392.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/393.mp3 b/site/app/partialemergence/sounds/Water/Droplets/393.mp3 Binary files differnew file mode 100644 index 0000000..9e51eda --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/393.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/394.mp3 b/site/app/partialemergence/sounds/Water/Droplets/394.mp3 Binary files differnew file mode 100644 index 0000000..1313c69 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/394.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/395.mp3 b/site/app/partialemergence/sounds/Water/Droplets/395.mp3 Binary files differnew file mode 100644 index 0000000..514d8b3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/395.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/396.mp3 b/site/app/partialemergence/sounds/Water/Droplets/396.mp3 Binary files differnew file mode 100644 index 0000000..3a3dec7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/396.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/397.mp3 b/site/app/partialemergence/sounds/Water/Droplets/397.mp3 Binary files differnew file mode 100644 index 0000000..adaa5fe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/397.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/398.mp3 b/site/app/partialemergence/sounds/Water/Droplets/398.mp3 Binary files differnew file mode 100644 index 0000000..943dbfa --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/398.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/399.mp3 b/site/app/partialemergence/sounds/Water/Droplets/399.mp3 Binary files differnew file mode 100644 index 0000000..0b22e34 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/399.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/4.mp3 b/site/app/partialemergence/sounds/Water/Droplets/4.mp3 Binary files differnew file mode 100644 index 0000000..4f3565e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/4.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/40.mp3 b/site/app/partialemergence/sounds/Water/Droplets/40.mp3 Binary files differnew file mode 100644 index 0000000..118ecf4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/40.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/400.mp3 b/site/app/partialemergence/sounds/Water/Droplets/400.mp3 Binary files differnew file mode 100644 index 0000000..30c9af4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/400.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/401.mp3 b/site/app/partialemergence/sounds/Water/Droplets/401.mp3 Binary files differnew file mode 100644 index 0000000..42b5552 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/401.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/402.mp3 b/site/app/partialemergence/sounds/Water/Droplets/402.mp3 Binary files differnew file mode 100644 index 0000000..687f155 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/402.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/403.mp3 b/site/app/partialemergence/sounds/Water/Droplets/403.mp3 Binary files differnew file mode 100644 index 0000000..2c0b4db --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/403.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/404.mp3 b/site/app/partialemergence/sounds/Water/Droplets/404.mp3 Binary files differnew file mode 100644 index 0000000..05ca2e0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/404.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/405.mp3 b/site/app/partialemergence/sounds/Water/Droplets/405.mp3 Binary files differnew file mode 100644 index 0000000..b67f497 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/405.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/406.mp3 b/site/app/partialemergence/sounds/Water/Droplets/406.mp3 Binary files differnew file mode 100644 index 0000000..aecffc2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/406.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/407.mp3 b/site/app/partialemergence/sounds/Water/Droplets/407.mp3 Binary files differnew file mode 100644 index 0000000..6b41c6b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/407.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/408.mp3 b/site/app/partialemergence/sounds/Water/Droplets/408.mp3 Binary files differnew file mode 100644 index 0000000..8a30682 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/408.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/409.mp3 b/site/app/partialemergence/sounds/Water/Droplets/409.mp3 Binary files differnew file mode 100644 index 0000000..892577a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/409.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/41.mp3 b/site/app/partialemergence/sounds/Water/Droplets/41.mp3 Binary files differnew file mode 100644 index 0000000..6ca406f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/41.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/410.mp3 b/site/app/partialemergence/sounds/Water/Droplets/410.mp3 Binary files differnew file mode 100644 index 0000000..77c8ad8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/410.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/411.mp3 b/site/app/partialemergence/sounds/Water/Droplets/411.mp3 Binary files differnew file mode 100644 index 0000000..269510a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/411.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/412.mp3 b/site/app/partialemergence/sounds/Water/Droplets/412.mp3 Binary files differnew file mode 100644 index 0000000..c9ec6da --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/412.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/413.mp3 b/site/app/partialemergence/sounds/Water/Droplets/413.mp3 Binary files differnew file mode 100644 index 0000000..f8a42a8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/413.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/414.mp3 b/site/app/partialemergence/sounds/Water/Droplets/414.mp3 Binary files differnew file mode 100644 index 0000000..3bbf727 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/414.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/415.mp3 b/site/app/partialemergence/sounds/Water/Droplets/415.mp3 Binary files differnew file mode 100644 index 0000000..220ef75 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/415.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/416.mp3 b/site/app/partialemergence/sounds/Water/Droplets/416.mp3 Binary files differnew file mode 100644 index 0000000..25945a7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/416.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/417.mp3 b/site/app/partialemergence/sounds/Water/Droplets/417.mp3 Binary files differnew file mode 100644 index 0000000..830ba10 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/417.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/418.mp3 b/site/app/partialemergence/sounds/Water/Droplets/418.mp3 Binary files differnew file mode 100644 index 0000000..6f1c8a2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/418.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/419.mp3 b/site/app/partialemergence/sounds/Water/Droplets/419.mp3 Binary files differnew file mode 100644 index 0000000..e899697 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/419.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/42.mp3 b/site/app/partialemergence/sounds/Water/Droplets/42.mp3 Binary files differnew file mode 100644 index 0000000..5a6af44 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/42.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/420.mp3 b/site/app/partialemergence/sounds/Water/Droplets/420.mp3 Binary files differnew file mode 100644 index 0000000..b772a0c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/420.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/421.mp3 b/site/app/partialemergence/sounds/Water/Droplets/421.mp3 Binary files differnew file mode 100644 index 0000000..33fade3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/421.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/422.mp3 b/site/app/partialemergence/sounds/Water/Droplets/422.mp3 Binary files differnew file mode 100644 index 0000000..11bd2c1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/422.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/423.mp3 b/site/app/partialemergence/sounds/Water/Droplets/423.mp3 Binary files differnew file mode 100644 index 0000000..0420da7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/423.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/424.mp3 b/site/app/partialemergence/sounds/Water/Droplets/424.mp3 Binary files differnew file mode 100644 index 0000000..eef20bd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/424.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/425.mp3 b/site/app/partialemergence/sounds/Water/Droplets/425.mp3 Binary files differnew file mode 100644 index 0000000..4d0850e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/425.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/426.mp3 b/site/app/partialemergence/sounds/Water/Droplets/426.mp3 Binary files differnew file mode 100644 index 0000000..686c192 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/426.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/427.mp3 b/site/app/partialemergence/sounds/Water/Droplets/427.mp3 Binary files differnew file mode 100644 index 0000000..c3019ea --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/427.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/428.mp3 b/site/app/partialemergence/sounds/Water/Droplets/428.mp3 Binary files differnew file mode 100644 index 0000000..da4f073 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/428.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/429.mp3 b/site/app/partialemergence/sounds/Water/Droplets/429.mp3 Binary files differnew file mode 100644 index 0000000..b2d9bf0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/429.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/43.mp3 b/site/app/partialemergence/sounds/Water/Droplets/43.mp3 Binary files differnew file mode 100644 index 0000000..561e76e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/43.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/430.mp3 b/site/app/partialemergence/sounds/Water/Droplets/430.mp3 Binary files differnew file mode 100644 index 0000000..f78b80b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/430.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/431.mp3 b/site/app/partialemergence/sounds/Water/Droplets/431.mp3 Binary files differnew file mode 100644 index 0000000..472c981 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/431.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/432.mp3 b/site/app/partialemergence/sounds/Water/Droplets/432.mp3 Binary files differnew file mode 100644 index 0000000..a147125 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/432.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/433.mp3 b/site/app/partialemergence/sounds/Water/Droplets/433.mp3 Binary files differnew file mode 100644 index 0000000..3ec1f38 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/433.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/434.mp3 b/site/app/partialemergence/sounds/Water/Droplets/434.mp3 Binary files differnew file mode 100644 index 0000000..e61fe15 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/434.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/435.mp3 b/site/app/partialemergence/sounds/Water/Droplets/435.mp3 Binary files differnew file mode 100644 index 0000000..687ca40 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/435.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/436.mp3 b/site/app/partialemergence/sounds/Water/Droplets/436.mp3 Binary files differnew file mode 100644 index 0000000..bf0feef --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/436.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/437.mp3 b/site/app/partialemergence/sounds/Water/Droplets/437.mp3 Binary files differnew file mode 100644 index 0000000..7e7004c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/437.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/438.mp3 b/site/app/partialemergence/sounds/Water/Droplets/438.mp3 Binary files differnew file mode 100644 index 0000000..71f03e4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/438.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/439.mp3 b/site/app/partialemergence/sounds/Water/Droplets/439.mp3 Binary files differnew file mode 100644 index 0000000..fa8fb11 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/439.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/44.mp3 b/site/app/partialemergence/sounds/Water/Droplets/44.mp3 Binary files differnew file mode 100644 index 0000000..347770f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/44.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/440.mp3 b/site/app/partialemergence/sounds/Water/Droplets/440.mp3 Binary files differnew file mode 100644 index 0000000..c4b8bc6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/440.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/441.mp3 b/site/app/partialemergence/sounds/Water/Droplets/441.mp3 Binary files differnew file mode 100644 index 0000000..0dedd94 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/441.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/442.mp3 b/site/app/partialemergence/sounds/Water/Droplets/442.mp3 Binary files differnew file mode 100644 index 0000000..bfb9fca --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/442.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/443.mp3 b/site/app/partialemergence/sounds/Water/Droplets/443.mp3 Binary files differnew file mode 100644 index 0000000..1547456 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/443.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/444.mp3 b/site/app/partialemergence/sounds/Water/Droplets/444.mp3 Binary files differnew file mode 100644 index 0000000..34f1ecd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/444.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/445.mp3 b/site/app/partialemergence/sounds/Water/Droplets/445.mp3 Binary files differnew file mode 100644 index 0000000..8401ddf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/445.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/446.mp3 b/site/app/partialemergence/sounds/Water/Droplets/446.mp3 Binary files differnew file mode 100644 index 0000000..a41fcd6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/446.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/447.mp3 b/site/app/partialemergence/sounds/Water/Droplets/447.mp3 Binary files differnew file mode 100644 index 0000000..243ec00 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/447.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/448.mp3 b/site/app/partialemergence/sounds/Water/Droplets/448.mp3 Binary files differnew file mode 100644 index 0000000..354517f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/448.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/449.mp3 b/site/app/partialemergence/sounds/Water/Droplets/449.mp3 Binary files differnew file mode 100644 index 0000000..8aaecfd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/449.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/45.mp3 b/site/app/partialemergence/sounds/Water/Droplets/45.mp3 Binary files differnew file mode 100644 index 0000000..acd0fc6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/45.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/450.mp3 b/site/app/partialemergence/sounds/Water/Droplets/450.mp3 Binary files differnew file mode 100644 index 0000000..c561572 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/450.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/451.mp3 b/site/app/partialemergence/sounds/Water/Droplets/451.mp3 Binary files differnew file mode 100644 index 0000000..8660a7c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/451.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/452.mp3 b/site/app/partialemergence/sounds/Water/Droplets/452.mp3 Binary files differnew file mode 100644 index 0000000..3ffffaa --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/452.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/453.mp3 b/site/app/partialemergence/sounds/Water/Droplets/453.mp3 Binary files differnew file mode 100644 index 0000000..baedda1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/453.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/454.mp3 b/site/app/partialemergence/sounds/Water/Droplets/454.mp3 Binary files differnew file mode 100644 index 0000000..cabcd97 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/454.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/455.mp3 b/site/app/partialemergence/sounds/Water/Droplets/455.mp3 Binary files differnew file mode 100644 index 0000000..8a33e35 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/455.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/456.mp3 b/site/app/partialemergence/sounds/Water/Droplets/456.mp3 Binary files differnew file mode 100644 index 0000000..ca1c8ef --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/456.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/457.mp3 b/site/app/partialemergence/sounds/Water/Droplets/457.mp3 Binary files differnew file mode 100644 index 0000000..02afd44 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/457.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/458.mp3 b/site/app/partialemergence/sounds/Water/Droplets/458.mp3 Binary files differnew file mode 100644 index 0000000..3fca4ff --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/458.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/459.mp3 b/site/app/partialemergence/sounds/Water/Droplets/459.mp3 Binary files differnew file mode 100644 index 0000000..d5abd99 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/459.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/46.mp3 b/site/app/partialemergence/sounds/Water/Droplets/46.mp3 Binary files differnew file mode 100644 index 0000000..5b8d181 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/46.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/460.mp3 b/site/app/partialemergence/sounds/Water/Droplets/460.mp3 Binary files differnew file mode 100644 index 0000000..a3485bb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/460.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/461.mp3 b/site/app/partialemergence/sounds/Water/Droplets/461.mp3 Binary files differnew file mode 100644 index 0000000..79acc5e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/461.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/462.mp3 b/site/app/partialemergence/sounds/Water/Droplets/462.mp3 Binary files differnew file mode 100644 index 0000000..8e18474 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/462.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/463.mp3 b/site/app/partialemergence/sounds/Water/Droplets/463.mp3 Binary files differnew file mode 100644 index 0000000..afc845c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/463.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/464.mp3 b/site/app/partialemergence/sounds/Water/Droplets/464.mp3 Binary files differnew file mode 100644 index 0000000..9b058c3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/464.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/465.mp3 b/site/app/partialemergence/sounds/Water/Droplets/465.mp3 Binary files differnew file mode 100644 index 0000000..0e0ba88 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/465.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/466.mp3 b/site/app/partialemergence/sounds/Water/Droplets/466.mp3 Binary files differnew file mode 100644 index 0000000..b5b98b1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/466.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/467.mp3 b/site/app/partialemergence/sounds/Water/Droplets/467.mp3 Binary files differnew file mode 100644 index 0000000..ff2b53f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/467.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/468.mp3 b/site/app/partialemergence/sounds/Water/Droplets/468.mp3 Binary files differnew file mode 100644 index 0000000..93545ab --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/468.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/469.mp3 b/site/app/partialemergence/sounds/Water/Droplets/469.mp3 Binary files differnew file mode 100644 index 0000000..0e01fe8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/469.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/47.mp3 b/site/app/partialemergence/sounds/Water/Droplets/47.mp3 Binary files differnew file mode 100644 index 0000000..407441e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/47.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/470.mp3 b/site/app/partialemergence/sounds/Water/Droplets/470.mp3 Binary files differnew file mode 100644 index 0000000..2f9dbee --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/470.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/471.mp3 b/site/app/partialemergence/sounds/Water/Droplets/471.mp3 Binary files differnew file mode 100644 index 0000000..0b6d68a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/471.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/472.mp3 b/site/app/partialemergence/sounds/Water/Droplets/472.mp3 Binary files differnew file mode 100644 index 0000000..72e9a81 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/472.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/473.mp3 b/site/app/partialemergence/sounds/Water/Droplets/473.mp3 Binary files differnew file mode 100644 index 0000000..e464dc0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/473.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/474.mp3 b/site/app/partialemergence/sounds/Water/Droplets/474.mp3 Binary files differnew file mode 100644 index 0000000..06bdcf5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/474.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/475.mp3 b/site/app/partialemergence/sounds/Water/Droplets/475.mp3 Binary files differnew file mode 100644 index 0000000..d8f51ef --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/475.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/476.mp3 b/site/app/partialemergence/sounds/Water/Droplets/476.mp3 Binary files differnew file mode 100644 index 0000000..4e8bc4e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/476.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/477.mp3 b/site/app/partialemergence/sounds/Water/Droplets/477.mp3 Binary files differnew file mode 100644 index 0000000..70c983e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/477.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/478.mp3 b/site/app/partialemergence/sounds/Water/Droplets/478.mp3 Binary files differnew file mode 100644 index 0000000..aff8dba --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/478.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/479.mp3 b/site/app/partialemergence/sounds/Water/Droplets/479.mp3 Binary files differnew file mode 100644 index 0000000..d9e3e32 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/479.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/48.mp3 b/site/app/partialemergence/sounds/Water/Droplets/48.mp3 Binary files differnew file mode 100644 index 0000000..4471fe7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/48.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/480.mp3 b/site/app/partialemergence/sounds/Water/Droplets/480.mp3 Binary files differnew file mode 100644 index 0000000..eac0f83 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/480.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/481.mp3 b/site/app/partialemergence/sounds/Water/Droplets/481.mp3 Binary files differnew file mode 100644 index 0000000..83d5d6c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/481.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/482.mp3 b/site/app/partialemergence/sounds/Water/Droplets/482.mp3 Binary files differnew file mode 100644 index 0000000..9065aba --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/482.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/483.mp3 b/site/app/partialemergence/sounds/Water/Droplets/483.mp3 Binary files differnew file mode 100644 index 0000000..c773ae3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/483.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/484.mp3 b/site/app/partialemergence/sounds/Water/Droplets/484.mp3 Binary files differnew file mode 100644 index 0000000..7fd66f8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/484.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/485.mp3 b/site/app/partialemergence/sounds/Water/Droplets/485.mp3 Binary files differnew file mode 100644 index 0000000..fa1572a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/485.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/486.mp3 b/site/app/partialemergence/sounds/Water/Droplets/486.mp3 Binary files differnew file mode 100644 index 0000000..2db8508 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/486.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/487.mp3 b/site/app/partialemergence/sounds/Water/Droplets/487.mp3 Binary files differnew file mode 100644 index 0000000..5c261ca --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/487.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/488.mp3 b/site/app/partialemergence/sounds/Water/Droplets/488.mp3 Binary files differnew file mode 100644 index 0000000..d048f66 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/488.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/489.mp3 b/site/app/partialemergence/sounds/Water/Droplets/489.mp3 Binary files differnew file mode 100644 index 0000000..ef18637 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/489.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/49.mp3 b/site/app/partialemergence/sounds/Water/Droplets/49.mp3 Binary files differnew file mode 100644 index 0000000..d805683 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/49.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/490.mp3 b/site/app/partialemergence/sounds/Water/Droplets/490.mp3 Binary files differnew file mode 100644 index 0000000..3b141ab --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/490.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/491.mp3 b/site/app/partialemergence/sounds/Water/Droplets/491.mp3 Binary files differnew file mode 100644 index 0000000..93f49fe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/491.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/492.mp3 b/site/app/partialemergence/sounds/Water/Droplets/492.mp3 Binary files differnew file mode 100644 index 0000000..2b5ce86 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/492.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/493.mp3 b/site/app/partialemergence/sounds/Water/Droplets/493.mp3 Binary files differnew file mode 100644 index 0000000..51c92d5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/493.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/494.mp3 b/site/app/partialemergence/sounds/Water/Droplets/494.mp3 Binary files differnew file mode 100644 index 0000000..fa045c3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/494.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/495.mp3 b/site/app/partialemergence/sounds/Water/Droplets/495.mp3 Binary files differnew file mode 100644 index 0000000..1c3fd59 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/495.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/496.mp3 b/site/app/partialemergence/sounds/Water/Droplets/496.mp3 Binary files differnew file mode 100644 index 0000000..8f9f71a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/496.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/497.mp3 b/site/app/partialemergence/sounds/Water/Droplets/497.mp3 Binary files differnew file mode 100644 index 0000000..30b01b6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/497.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/498.mp3 b/site/app/partialemergence/sounds/Water/Droplets/498.mp3 Binary files differnew file mode 100644 index 0000000..c385116 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/498.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/499.mp3 b/site/app/partialemergence/sounds/Water/Droplets/499.mp3 Binary files differnew file mode 100644 index 0000000..6376b57 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/499.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/5.mp3 b/site/app/partialemergence/sounds/Water/Droplets/5.mp3 Binary files differnew file mode 100644 index 0000000..1afe7b1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/5.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/50.mp3 b/site/app/partialemergence/sounds/Water/Droplets/50.mp3 Binary files differnew file mode 100644 index 0000000..d02abe8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/50.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/500.mp3 b/site/app/partialemergence/sounds/Water/Droplets/500.mp3 Binary files differnew file mode 100644 index 0000000..8a210f1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/500.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/501.mp3 b/site/app/partialemergence/sounds/Water/Droplets/501.mp3 Binary files differnew file mode 100644 index 0000000..47bfcc6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/501.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/502.mp3 b/site/app/partialemergence/sounds/Water/Droplets/502.mp3 Binary files differnew file mode 100644 index 0000000..5a92a48 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/502.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/503.mp3 b/site/app/partialemergence/sounds/Water/Droplets/503.mp3 Binary files differnew file mode 100644 index 0000000..4896c50 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/503.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/504.mp3 b/site/app/partialemergence/sounds/Water/Droplets/504.mp3 Binary files differnew file mode 100644 index 0000000..66e2cd1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/504.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/505.mp3 b/site/app/partialemergence/sounds/Water/Droplets/505.mp3 Binary files differnew file mode 100644 index 0000000..406db03 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/505.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/506.mp3 b/site/app/partialemergence/sounds/Water/Droplets/506.mp3 Binary files differnew file mode 100644 index 0000000..60988f4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/506.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/507.mp3 b/site/app/partialemergence/sounds/Water/Droplets/507.mp3 Binary files differnew file mode 100644 index 0000000..7dc3662 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/507.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/508.mp3 b/site/app/partialemergence/sounds/Water/Droplets/508.mp3 Binary files differnew file mode 100644 index 0000000..ba57d16 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/508.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/509.mp3 b/site/app/partialemergence/sounds/Water/Droplets/509.mp3 Binary files differnew file mode 100644 index 0000000..663e594 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/509.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/51.mp3 b/site/app/partialemergence/sounds/Water/Droplets/51.mp3 Binary files differnew file mode 100644 index 0000000..264ca7d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/51.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/510.mp3 b/site/app/partialemergence/sounds/Water/Droplets/510.mp3 Binary files differnew file mode 100644 index 0000000..8e37848 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/510.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/511.mp3 b/site/app/partialemergence/sounds/Water/Droplets/511.mp3 Binary files differnew file mode 100644 index 0000000..1789a30 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/511.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/512.mp3 b/site/app/partialemergence/sounds/Water/Droplets/512.mp3 Binary files differnew file mode 100644 index 0000000..a728104 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/512.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/513.mp3 b/site/app/partialemergence/sounds/Water/Droplets/513.mp3 Binary files differnew file mode 100644 index 0000000..95a78c2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/513.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/514.mp3 b/site/app/partialemergence/sounds/Water/Droplets/514.mp3 Binary files differnew file mode 100644 index 0000000..1b32cc9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/514.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/515.mp3 b/site/app/partialemergence/sounds/Water/Droplets/515.mp3 Binary files differnew file mode 100644 index 0000000..d77ffd8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/515.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/516.mp3 b/site/app/partialemergence/sounds/Water/Droplets/516.mp3 Binary files differnew file mode 100644 index 0000000..3502c4b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/516.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/517.mp3 b/site/app/partialemergence/sounds/Water/Droplets/517.mp3 Binary files differnew file mode 100644 index 0000000..130c074 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/517.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/518.mp3 b/site/app/partialemergence/sounds/Water/Droplets/518.mp3 Binary files differnew file mode 100644 index 0000000..6940776 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/518.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/519.mp3 b/site/app/partialemergence/sounds/Water/Droplets/519.mp3 Binary files differnew file mode 100644 index 0000000..18f179a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/519.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/52.mp3 b/site/app/partialemergence/sounds/Water/Droplets/52.mp3 Binary files differnew file mode 100644 index 0000000..0740868 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/52.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/520.mp3 b/site/app/partialemergence/sounds/Water/Droplets/520.mp3 Binary files differnew file mode 100644 index 0000000..c63e64c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/520.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/521.mp3 b/site/app/partialemergence/sounds/Water/Droplets/521.mp3 Binary files differnew file mode 100644 index 0000000..61d2978 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/521.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/522.mp3 b/site/app/partialemergence/sounds/Water/Droplets/522.mp3 Binary files differnew file mode 100644 index 0000000..5baa849 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/522.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/523.mp3 b/site/app/partialemergence/sounds/Water/Droplets/523.mp3 Binary files differnew file mode 100644 index 0000000..b889034 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/523.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/524.mp3 b/site/app/partialemergence/sounds/Water/Droplets/524.mp3 Binary files differnew file mode 100644 index 0000000..51e9bb4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/524.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/525.mp3 b/site/app/partialemergence/sounds/Water/Droplets/525.mp3 Binary files differnew file mode 100644 index 0000000..d4ad072 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/525.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/526.mp3 b/site/app/partialemergence/sounds/Water/Droplets/526.mp3 Binary files differnew file mode 100644 index 0000000..98ef33d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/526.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/527.mp3 b/site/app/partialemergence/sounds/Water/Droplets/527.mp3 Binary files differnew file mode 100644 index 0000000..5e5f9b8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/527.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/528.mp3 b/site/app/partialemergence/sounds/Water/Droplets/528.mp3 Binary files differnew file mode 100644 index 0000000..d1f40ef --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/528.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/529.mp3 b/site/app/partialemergence/sounds/Water/Droplets/529.mp3 Binary files differnew file mode 100644 index 0000000..13028a3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/529.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/53.mp3 b/site/app/partialemergence/sounds/Water/Droplets/53.mp3 Binary files differnew file mode 100644 index 0000000..fbcf4ba --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/53.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/530.mp3 b/site/app/partialemergence/sounds/Water/Droplets/530.mp3 Binary files differnew file mode 100644 index 0000000..09171bd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/530.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/531.mp3 b/site/app/partialemergence/sounds/Water/Droplets/531.mp3 Binary files differnew file mode 100644 index 0000000..33b43ec --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/531.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/532.mp3 b/site/app/partialemergence/sounds/Water/Droplets/532.mp3 Binary files differnew file mode 100644 index 0000000..07aa24e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/532.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/533.mp3 b/site/app/partialemergence/sounds/Water/Droplets/533.mp3 Binary files differnew file mode 100644 index 0000000..e1c3149 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/533.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/534.mp3 b/site/app/partialemergence/sounds/Water/Droplets/534.mp3 Binary files differnew file mode 100644 index 0000000..2b35e71 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/534.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/535.mp3 b/site/app/partialemergence/sounds/Water/Droplets/535.mp3 Binary files differnew file mode 100644 index 0000000..63b783a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/535.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/536.mp3 b/site/app/partialemergence/sounds/Water/Droplets/536.mp3 Binary files differnew file mode 100644 index 0000000..5c7f354 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/536.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/537.mp3 b/site/app/partialemergence/sounds/Water/Droplets/537.mp3 Binary files differnew file mode 100644 index 0000000..65212f5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/537.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/538.mp3 b/site/app/partialemergence/sounds/Water/Droplets/538.mp3 Binary files differnew file mode 100644 index 0000000..1ab81be --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/538.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/539.mp3 b/site/app/partialemergence/sounds/Water/Droplets/539.mp3 Binary files differnew file mode 100644 index 0000000..293e6e7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/539.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/54.mp3 b/site/app/partialemergence/sounds/Water/Droplets/54.mp3 Binary files differnew file mode 100644 index 0000000..f14f576 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/54.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/540.mp3 b/site/app/partialemergence/sounds/Water/Droplets/540.mp3 Binary files differnew file mode 100644 index 0000000..f843cc0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/540.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/541.mp3 b/site/app/partialemergence/sounds/Water/Droplets/541.mp3 Binary files differnew file mode 100644 index 0000000..efc6396 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/541.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/542.mp3 b/site/app/partialemergence/sounds/Water/Droplets/542.mp3 Binary files differnew file mode 100644 index 0000000..0fd4dde --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/542.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/543.mp3 b/site/app/partialemergence/sounds/Water/Droplets/543.mp3 Binary files differnew file mode 100644 index 0000000..ae8b083 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/543.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/545.mp3 b/site/app/partialemergence/sounds/Water/Droplets/545.mp3 Binary files differnew file mode 100644 index 0000000..0411199 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/545.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/546.mp3 b/site/app/partialemergence/sounds/Water/Droplets/546.mp3 Binary files differnew file mode 100644 index 0000000..36e4b40 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/546.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/547.mp3 b/site/app/partialemergence/sounds/Water/Droplets/547.mp3 Binary files differnew file mode 100644 index 0000000..8d8ab05 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/547.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/548.mp3 b/site/app/partialemergence/sounds/Water/Droplets/548.mp3 Binary files differnew file mode 100644 index 0000000..4272e7d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/548.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/549.mp3 b/site/app/partialemergence/sounds/Water/Droplets/549.mp3 Binary files differnew file mode 100644 index 0000000..2c92e68 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/549.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/55.mp3 b/site/app/partialemergence/sounds/Water/Droplets/55.mp3 Binary files differnew file mode 100644 index 0000000..02dd1d8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/55.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/550.mp3 b/site/app/partialemergence/sounds/Water/Droplets/550.mp3 Binary files differnew file mode 100644 index 0000000..e0fb675 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/550.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/551.mp3 b/site/app/partialemergence/sounds/Water/Droplets/551.mp3 Binary files differnew file mode 100644 index 0000000..cd07f4e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/551.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/552.mp3 b/site/app/partialemergence/sounds/Water/Droplets/552.mp3 Binary files differnew file mode 100644 index 0000000..5c029b6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/552.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/553.mp3 b/site/app/partialemergence/sounds/Water/Droplets/553.mp3 Binary files differnew file mode 100644 index 0000000..8c0f1ee --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/553.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/554.mp3 b/site/app/partialemergence/sounds/Water/Droplets/554.mp3 Binary files differnew file mode 100644 index 0000000..d5defa5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/554.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/555.mp3 b/site/app/partialemergence/sounds/Water/Droplets/555.mp3 Binary files differnew file mode 100644 index 0000000..f3feb21 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/555.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/556.mp3 b/site/app/partialemergence/sounds/Water/Droplets/556.mp3 Binary files differnew file mode 100644 index 0000000..aa79e32 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/556.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/557.mp3 b/site/app/partialemergence/sounds/Water/Droplets/557.mp3 Binary files differnew file mode 100644 index 0000000..f6f572a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/557.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/558.mp3 b/site/app/partialemergence/sounds/Water/Droplets/558.mp3 Binary files differnew file mode 100644 index 0000000..ec461fd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/558.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/559.mp3 b/site/app/partialemergence/sounds/Water/Droplets/559.mp3 Binary files differnew file mode 100644 index 0000000..fef97fc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/559.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/56.mp3 b/site/app/partialemergence/sounds/Water/Droplets/56.mp3 Binary files differnew file mode 100644 index 0000000..66cd072 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/56.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/560.mp3 b/site/app/partialemergence/sounds/Water/Droplets/560.mp3 Binary files differnew file mode 100644 index 0000000..da17a9b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/560.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/561.mp3 b/site/app/partialemergence/sounds/Water/Droplets/561.mp3 Binary files differnew file mode 100644 index 0000000..e978547 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/561.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/562.mp3 b/site/app/partialemergence/sounds/Water/Droplets/562.mp3 Binary files differnew file mode 100644 index 0000000..3d3f0ae --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/562.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/563.mp3 b/site/app/partialemergence/sounds/Water/Droplets/563.mp3 Binary files differnew file mode 100644 index 0000000..66eaea8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/563.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/564.mp3 b/site/app/partialemergence/sounds/Water/Droplets/564.mp3 Binary files differnew file mode 100644 index 0000000..6dc04cf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/564.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/565.mp3 b/site/app/partialemergence/sounds/Water/Droplets/565.mp3 Binary files differnew file mode 100644 index 0000000..d2f3474 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/565.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/566.mp3 b/site/app/partialemergence/sounds/Water/Droplets/566.mp3 Binary files differnew file mode 100644 index 0000000..0d6f6e1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/566.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/567.mp3 b/site/app/partialemergence/sounds/Water/Droplets/567.mp3 Binary files differnew file mode 100644 index 0000000..0ef0a03 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/567.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/568.mp3 b/site/app/partialemergence/sounds/Water/Droplets/568.mp3 Binary files differnew file mode 100644 index 0000000..c94b782 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/568.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/569.mp3 b/site/app/partialemergence/sounds/Water/Droplets/569.mp3 Binary files differnew file mode 100644 index 0000000..6244931 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/569.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/57.mp3 b/site/app/partialemergence/sounds/Water/Droplets/57.mp3 Binary files differnew file mode 100644 index 0000000..c558150 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/57.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/570.mp3 b/site/app/partialemergence/sounds/Water/Droplets/570.mp3 Binary files differnew file mode 100644 index 0000000..bde716a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/570.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/571.mp3 b/site/app/partialemergence/sounds/Water/Droplets/571.mp3 Binary files differnew file mode 100644 index 0000000..fe91950 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/571.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/572.mp3 b/site/app/partialemergence/sounds/Water/Droplets/572.mp3 Binary files differnew file mode 100644 index 0000000..609c2d9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/572.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/573.mp3 b/site/app/partialemergence/sounds/Water/Droplets/573.mp3 Binary files differnew file mode 100644 index 0000000..acc7acd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/573.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/574.mp3 b/site/app/partialemergence/sounds/Water/Droplets/574.mp3 Binary files differnew file mode 100644 index 0000000..14ee8f7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/574.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/575.mp3 b/site/app/partialemergence/sounds/Water/Droplets/575.mp3 Binary files differnew file mode 100644 index 0000000..cd6f3f1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/575.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/576.mp3 b/site/app/partialemergence/sounds/Water/Droplets/576.mp3 Binary files differnew file mode 100644 index 0000000..71d54d8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/576.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/577.mp3 b/site/app/partialemergence/sounds/Water/Droplets/577.mp3 Binary files differnew file mode 100644 index 0000000..b57b99c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/577.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/578.mp3 b/site/app/partialemergence/sounds/Water/Droplets/578.mp3 Binary files differnew file mode 100644 index 0000000..dba3ab3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/578.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/579.mp3 b/site/app/partialemergence/sounds/Water/Droplets/579.mp3 Binary files differnew file mode 100644 index 0000000..8efa11c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/579.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/58.mp3 b/site/app/partialemergence/sounds/Water/Droplets/58.mp3 Binary files differnew file mode 100644 index 0000000..7143f0f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/58.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/59.mp3 b/site/app/partialemergence/sounds/Water/Droplets/59.mp3 Binary files differnew file mode 100644 index 0000000..53f6350 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/59.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/6.mp3 b/site/app/partialemergence/sounds/Water/Droplets/6.mp3 Binary files differnew file mode 100644 index 0000000..2281a04 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/6.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/60.mp3 b/site/app/partialemergence/sounds/Water/Droplets/60.mp3 Binary files differnew file mode 100644 index 0000000..ddc6117 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/60.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/61.mp3 b/site/app/partialemergence/sounds/Water/Droplets/61.mp3 Binary files differnew file mode 100644 index 0000000..a017a8f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/61.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/62.mp3 b/site/app/partialemergence/sounds/Water/Droplets/62.mp3 Binary files differnew file mode 100644 index 0000000..2ba578a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/62.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/63.mp3 b/site/app/partialemergence/sounds/Water/Droplets/63.mp3 Binary files differnew file mode 100644 index 0000000..348d906 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/63.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/64.mp3 b/site/app/partialemergence/sounds/Water/Droplets/64.mp3 Binary files differnew file mode 100644 index 0000000..3a55ef0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/64.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/65.mp3 b/site/app/partialemergence/sounds/Water/Droplets/65.mp3 Binary files differnew file mode 100644 index 0000000..88f9410 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/65.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/66.mp3 b/site/app/partialemergence/sounds/Water/Droplets/66.mp3 Binary files differnew file mode 100644 index 0000000..aee32e2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/66.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/67.mp3 b/site/app/partialemergence/sounds/Water/Droplets/67.mp3 Binary files differnew file mode 100644 index 0000000..b007b33 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/67.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/68.mp3 b/site/app/partialemergence/sounds/Water/Droplets/68.mp3 Binary files differnew file mode 100644 index 0000000..b07c4f2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/68.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/69.mp3 b/site/app/partialemergence/sounds/Water/Droplets/69.mp3 Binary files differnew file mode 100644 index 0000000..746c8dd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/69.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/7.mp3 b/site/app/partialemergence/sounds/Water/Droplets/7.mp3 Binary files differnew file mode 100644 index 0000000..c7bbc7e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/7.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/70.mp3 b/site/app/partialemergence/sounds/Water/Droplets/70.mp3 Binary files differnew file mode 100644 index 0000000..030af2d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/70.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/71.mp3 b/site/app/partialemergence/sounds/Water/Droplets/71.mp3 Binary files differnew file mode 100644 index 0000000..3962ac5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/71.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/72.mp3 b/site/app/partialemergence/sounds/Water/Droplets/72.mp3 Binary files differnew file mode 100644 index 0000000..32de894 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/72.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/73.mp3 b/site/app/partialemergence/sounds/Water/Droplets/73.mp3 Binary files differnew file mode 100644 index 0000000..5eba927 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/73.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/74.mp3 b/site/app/partialemergence/sounds/Water/Droplets/74.mp3 Binary files differnew file mode 100644 index 0000000..a7b4c5b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/74.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/75.mp3 b/site/app/partialemergence/sounds/Water/Droplets/75.mp3 Binary files differnew file mode 100644 index 0000000..66e872f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/75.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/76.mp3 b/site/app/partialemergence/sounds/Water/Droplets/76.mp3 Binary files differnew file mode 100644 index 0000000..03a23a0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/76.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/77.mp3 b/site/app/partialemergence/sounds/Water/Droplets/77.mp3 Binary files differnew file mode 100644 index 0000000..9332f16 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/77.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/78.mp3 b/site/app/partialemergence/sounds/Water/Droplets/78.mp3 Binary files differnew file mode 100644 index 0000000..2929daf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/78.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/79.mp3 b/site/app/partialemergence/sounds/Water/Droplets/79.mp3 Binary files differnew file mode 100644 index 0000000..037a475 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/79.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/8.mp3 b/site/app/partialemergence/sounds/Water/Droplets/8.mp3 Binary files differnew file mode 100644 index 0000000..82a9256 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/8.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/80.mp3 b/site/app/partialemergence/sounds/Water/Droplets/80.mp3 Binary files differnew file mode 100644 index 0000000..cde5d06 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/80.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/81.mp3 b/site/app/partialemergence/sounds/Water/Droplets/81.mp3 Binary files differnew file mode 100644 index 0000000..cc18b66 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/81.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/82.mp3 b/site/app/partialemergence/sounds/Water/Droplets/82.mp3 Binary files differnew file mode 100644 index 0000000..db4bf32 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/82.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/83.mp3 b/site/app/partialemergence/sounds/Water/Droplets/83.mp3 Binary files differnew file mode 100644 index 0000000..822ba20 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/83.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/84.mp3 b/site/app/partialemergence/sounds/Water/Droplets/84.mp3 Binary files differnew file mode 100644 index 0000000..4703da7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/84.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/85.mp3 b/site/app/partialemergence/sounds/Water/Droplets/85.mp3 Binary files differnew file mode 100644 index 0000000..13be1d5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/85.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/86.mp3 b/site/app/partialemergence/sounds/Water/Droplets/86.mp3 Binary files differnew file mode 100644 index 0000000..ac0541b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/86.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/87.mp3 b/site/app/partialemergence/sounds/Water/Droplets/87.mp3 Binary files differnew file mode 100644 index 0000000..af889fb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/87.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/88.mp3 b/site/app/partialemergence/sounds/Water/Droplets/88.mp3 Binary files differnew file mode 100644 index 0000000..533b36d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/88.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/89.mp3 b/site/app/partialemergence/sounds/Water/Droplets/89.mp3 Binary files differnew file mode 100644 index 0000000..5aaff8b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/89.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/9.mp3 b/site/app/partialemergence/sounds/Water/Droplets/9.mp3 Binary files differnew file mode 100644 index 0000000..6ac5333 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/9.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/90.mp3 b/site/app/partialemergence/sounds/Water/Droplets/90.mp3 Binary files differnew file mode 100644 index 0000000..3280d1f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/90.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/91.mp3 b/site/app/partialemergence/sounds/Water/Droplets/91.mp3 Binary files differnew file mode 100644 index 0000000..0a0b06f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/91.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/92.mp3 b/site/app/partialemergence/sounds/Water/Droplets/92.mp3 Binary files differnew file mode 100644 index 0000000..c5ea873 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/92.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/93.mp3 b/site/app/partialemergence/sounds/Water/Droplets/93.mp3 Binary files differnew file mode 100644 index 0000000..4370ac3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/93.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/94.mp3 b/site/app/partialemergence/sounds/Water/Droplets/94.mp3 Binary files differnew file mode 100644 index 0000000..f26ddc0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/94.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/95.mp3 b/site/app/partialemergence/sounds/Water/Droplets/95.mp3 Binary files differnew file mode 100644 index 0000000..319c29f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/95.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/96.mp3 b/site/app/partialemergence/sounds/Water/Droplets/96.mp3 Binary files differnew file mode 100644 index 0000000..ceb1bb2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/96.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/97.mp3 b/site/app/partialemergence/sounds/Water/Droplets/97.mp3 Binary files differnew file mode 100644 index 0000000..1fcccbd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/97.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/98.mp3 b/site/app/partialemergence/sounds/Water/Droplets/98.mp3 Binary files differnew file mode 100644 index 0000000..8220ed8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/98.mp3 diff --git a/site/app/partialemergence/sounds/Water/Droplets/99.mp3 b/site/app/partialemergence/sounds/Water/Droplets/99.mp3 Binary files differnew file mode 100644 index 0000000..d5b57cc --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Droplets/99.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/1.mp3 b/site/app/partialemergence/sounds/Water/Paddling/1.mp3 Binary files differnew file mode 100644 index 0000000..28d04c7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/1.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/10.mp3 b/site/app/partialemergence/sounds/Water/Paddling/10.mp3 Binary files differnew file mode 100644 index 0000000..55adb7a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/10.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/100.mp3 b/site/app/partialemergence/sounds/Water/Paddling/100.mp3 Binary files differnew file mode 100644 index 0000000..416ccdd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/100.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/11.mp3 b/site/app/partialemergence/sounds/Water/Paddling/11.mp3 Binary files differnew file mode 100644 index 0000000..d72454b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/11.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/12.mp3 b/site/app/partialemergence/sounds/Water/Paddling/12.mp3 Binary files differnew file mode 100644 index 0000000..5e4d459 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/12.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/13.mp3 b/site/app/partialemergence/sounds/Water/Paddling/13.mp3 Binary files differnew file mode 100644 index 0000000..3f27d52 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/13.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/14.mp3 b/site/app/partialemergence/sounds/Water/Paddling/14.mp3 Binary files differnew file mode 100644 index 0000000..a3cc7f1 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/14.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/15.mp3 b/site/app/partialemergence/sounds/Water/Paddling/15.mp3 Binary files differnew file mode 100644 index 0000000..180ca6c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/15.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/16.mp3 b/site/app/partialemergence/sounds/Water/Paddling/16.mp3 Binary files differnew file mode 100644 index 0000000..6e4b9da --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/16.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/17.mp3 b/site/app/partialemergence/sounds/Water/Paddling/17.mp3 Binary files differnew file mode 100644 index 0000000..5039fc9 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/17.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/18.mp3 b/site/app/partialemergence/sounds/Water/Paddling/18.mp3 Binary files differnew file mode 100644 index 0000000..d6e9268 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/18.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/19.mp3 b/site/app/partialemergence/sounds/Water/Paddling/19.mp3 Binary files differnew file mode 100644 index 0000000..1045713 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/19.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/2.mp3 b/site/app/partialemergence/sounds/Water/Paddling/2.mp3 Binary files differnew file mode 100644 index 0000000..36ce4df --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/2.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/20.mp3 b/site/app/partialemergence/sounds/Water/Paddling/20.mp3 Binary files differnew file mode 100644 index 0000000..c3d820f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/20.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/21.mp3 b/site/app/partialemergence/sounds/Water/Paddling/21.mp3 Binary files differnew file mode 100644 index 0000000..b826aae --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/21.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/22.mp3 b/site/app/partialemergence/sounds/Water/Paddling/22.mp3 Binary files differnew file mode 100644 index 0000000..e520f73 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/22.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/23.mp3 b/site/app/partialemergence/sounds/Water/Paddling/23.mp3 Binary files differnew file mode 100644 index 0000000..5b3d117 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/23.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/24.mp3 b/site/app/partialemergence/sounds/Water/Paddling/24.mp3 Binary files differnew file mode 100644 index 0000000..bbdf293 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/24.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/25.mp3 b/site/app/partialemergence/sounds/Water/Paddling/25.mp3 Binary files differnew file mode 100644 index 0000000..56085c7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/25.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/26.mp3 b/site/app/partialemergence/sounds/Water/Paddling/26.mp3 Binary files differnew file mode 100644 index 0000000..3772cf3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/26.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/27.mp3 b/site/app/partialemergence/sounds/Water/Paddling/27.mp3 Binary files differnew file mode 100644 index 0000000..ccf85f4 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/27.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/28.mp3 b/site/app/partialemergence/sounds/Water/Paddling/28.mp3 Binary files differnew file mode 100644 index 0000000..8400a0e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/28.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/29.mp3 b/site/app/partialemergence/sounds/Water/Paddling/29.mp3 Binary files differnew file mode 100644 index 0000000..9d723b8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/29.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/3.mp3 b/site/app/partialemergence/sounds/Water/Paddling/3.mp3 Binary files differnew file mode 100644 index 0000000..53b974b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/3.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/30.mp3 b/site/app/partialemergence/sounds/Water/Paddling/30.mp3 Binary files differnew file mode 100644 index 0000000..8550f5f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/30.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/31.mp3 b/site/app/partialemergence/sounds/Water/Paddling/31.mp3 Binary files differnew file mode 100644 index 0000000..24997a0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/31.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/32.mp3 b/site/app/partialemergence/sounds/Water/Paddling/32.mp3 Binary files differnew file mode 100644 index 0000000..c2e32f2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/32.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/33.mp3 b/site/app/partialemergence/sounds/Water/Paddling/33.mp3 Binary files differnew file mode 100644 index 0000000..aa12122 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/33.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/34.mp3 b/site/app/partialemergence/sounds/Water/Paddling/34.mp3 Binary files differnew file mode 100644 index 0000000..28a7690 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/34.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/35.mp3 b/site/app/partialemergence/sounds/Water/Paddling/35.mp3 Binary files differnew file mode 100644 index 0000000..080a529 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/35.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/36.mp3 b/site/app/partialemergence/sounds/Water/Paddling/36.mp3 Binary files differnew file mode 100644 index 0000000..26ec3ec --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/36.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/37.mp3 b/site/app/partialemergence/sounds/Water/Paddling/37.mp3 Binary files differnew file mode 100644 index 0000000..1389076 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/37.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/38.mp3 b/site/app/partialemergence/sounds/Water/Paddling/38.mp3 Binary files differnew file mode 100644 index 0000000..b949db3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/38.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/39.mp3 b/site/app/partialemergence/sounds/Water/Paddling/39.mp3 Binary files differnew file mode 100644 index 0000000..4ddf427 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/39.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/4.mp3 b/site/app/partialemergence/sounds/Water/Paddling/4.mp3 Binary files differnew file mode 100644 index 0000000..e21a6cb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/4.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/40.mp3 b/site/app/partialemergence/sounds/Water/Paddling/40.mp3 Binary files differnew file mode 100644 index 0000000..024f6b2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/40.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/41.mp3 b/site/app/partialemergence/sounds/Water/Paddling/41.mp3 Binary files differnew file mode 100644 index 0000000..51bf28c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/41.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/42.mp3 b/site/app/partialemergence/sounds/Water/Paddling/42.mp3 Binary files differnew file mode 100644 index 0000000..c3e21e7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/42.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/43.mp3 b/site/app/partialemergence/sounds/Water/Paddling/43.mp3 Binary files differnew file mode 100644 index 0000000..4054854 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/43.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/44.mp3 b/site/app/partialemergence/sounds/Water/Paddling/44.mp3 Binary files differnew file mode 100644 index 0000000..cf18049 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/44.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/45.mp3 b/site/app/partialemergence/sounds/Water/Paddling/45.mp3 Binary files differnew file mode 100644 index 0000000..1821806 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/45.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/46.mp3 b/site/app/partialemergence/sounds/Water/Paddling/46.mp3 Binary files differnew file mode 100644 index 0000000..26d7e1a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/46.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/47.mp3 b/site/app/partialemergence/sounds/Water/Paddling/47.mp3 Binary files differnew file mode 100644 index 0000000..c6bcf00 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/47.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/48.mp3 b/site/app/partialemergence/sounds/Water/Paddling/48.mp3 Binary files differnew file mode 100644 index 0000000..04a4238 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/48.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/49.mp3 b/site/app/partialemergence/sounds/Water/Paddling/49.mp3 Binary files differnew file mode 100644 index 0000000..64a6576 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/49.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/5.mp3 b/site/app/partialemergence/sounds/Water/Paddling/5.mp3 Binary files differnew file mode 100644 index 0000000..33b6ff8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/5.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/50.mp3 b/site/app/partialemergence/sounds/Water/Paddling/50.mp3 Binary files differnew file mode 100644 index 0000000..ec55316 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/50.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/51.mp3 b/site/app/partialemergence/sounds/Water/Paddling/51.mp3 Binary files differnew file mode 100644 index 0000000..bba47e3 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/51.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/52.mp3 b/site/app/partialemergence/sounds/Water/Paddling/52.mp3 Binary files differnew file mode 100644 index 0000000..55cdf38 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/52.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/53.mp3 b/site/app/partialemergence/sounds/Water/Paddling/53.mp3 Binary files differnew file mode 100644 index 0000000..f760889 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/53.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/54.mp3 b/site/app/partialemergence/sounds/Water/Paddling/54.mp3 Binary files differnew file mode 100644 index 0000000..0d11b66 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/54.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/55.mp3 b/site/app/partialemergence/sounds/Water/Paddling/55.mp3 Binary files differnew file mode 100644 index 0000000..764bd66 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/55.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/56.mp3 b/site/app/partialemergence/sounds/Water/Paddling/56.mp3 Binary files differnew file mode 100644 index 0000000..74eb527 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/56.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/57.mp3 b/site/app/partialemergence/sounds/Water/Paddling/57.mp3 Binary files differnew file mode 100644 index 0000000..01a8725 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/57.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/58.mp3 b/site/app/partialemergence/sounds/Water/Paddling/58.mp3 Binary files differnew file mode 100644 index 0000000..317de16 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/58.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/59.mp3 b/site/app/partialemergence/sounds/Water/Paddling/59.mp3 Binary files differnew file mode 100644 index 0000000..7fecdbb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/59.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/6.mp3 b/site/app/partialemergence/sounds/Water/Paddling/6.mp3 Binary files differnew file mode 100644 index 0000000..253db48 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/6.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/60.mp3 b/site/app/partialemergence/sounds/Water/Paddling/60.mp3 Binary files differnew file mode 100644 index 0000000..f7304a8 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/60.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/61.mp3 b/site/app/partialemergence/sounds/Water/Paddling/61.mp3 Binary files differnew file mode 100644 index 0000000..b0b3326 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/61.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/62.mp3 b/site/app/partialemergence/sounds/Water/Paddling/62.mp3 Binary files differnew file mode 100644 index 0000000..f74c2fe --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/62.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/63.mp3 b/site/app/partialemergence/sounds/Water/Paddling/63.mp3 Binary files differnew file mode 100644 index 0000000..e1177aa --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/63.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/64.mp3 b/site/app/partialemergence/sounds/Water/Paddling/64.mp3 Binary files differnew file mode 100644 index 0000000..87bd72b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/64.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/65.mp3 b/site/app/partialemergence/sounds/Water/Paddling/65.mp3 Binary files differnew file mode 100644 index 0000000..31af83f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/65.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/66.mp3 b/site/app/partialemergence/sounds/Water/Paddling/66.mp3 Binary files differnew file mode 100644 index 0000000..d8af6cf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/66.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/67.mp3 b/site/app/partialemergence/sounds/Water/Paddling/67.mp3 Binary files differnew file mode 100644 index 0000000..9787ff5 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/67.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/68.mp3 b/site/app/partialemergence/sounds/Water/Paddling/68.mp3 Binary files differnew file mode 100644 index 0000000..05c61f7 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/68.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/69.mp3 b/site/app/partialemergence/sounds/Water/Paddling/69.mp3 Binary files differnew file mode 100644 index 0000000..894fdcd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/69.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/7.mp3 b/site/app/partialemergence/sounds/Water/Paddling/7.mp3 Binary files differnew file mode 100644 index 0000000..ddc7fcf --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/7.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/70.mp3 b/site/app/partialemergence/sounds/Water/Paddling/70.mp3 Binary files differnew file mode 100644 index 0000000..14e4928 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/70.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/71.mp3 b/site/app/partialemergence/sounds/Water/Paddling/71.mp3 Binary files differnew file mode 100644 index 0000000..5bfd0b6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/71.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/72.mp3 b/site/app/partialemergence/sounds/Water/Paddling/72.mp3 Binary files differnew file mode 100644 index 0000000..60b2c56 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/72.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/73.mp3 b/site/app/partialemergence/sounds/Water/Paddling/73.mp3 Binary files differnew file mode 100644 index 0000000..715e77a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/73.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/74.mp3 b/site/app/partialemergence/sounds/Water/Paddling/74.mp3 Binary files differnew file mode 100644 index 0000000..389d12f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/74.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/75.mp3 b/site/app/partialemergence/sounds/Water/Paddling/75.mp3 Binary files differnew file mode 100644 index 0000000..e82ae66 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/75.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/76.mp3 b/site/app/partialemergence/sounds/Water/Paddling/76.mp3 Binary files differnew file mode 100644 index 0000000..726ebf2 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/76.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/77.mp3 b/site/app/partialemergence/sounds/Water/Paddling/77.mp3 Binary files differnew file mode 100644 index 0000000..bbda6cd --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/77.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/78.mp3 b/site/app/partialemergence/sounds/Water/Paddling/78.mp3 Binary files differnew file mode 100644 index 0000000..b9363fb --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/78.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/79.mp3 b/site/app/partialemergence/sounds/Water/Paddling/79.mp3 Binary files differnew file mode 100644 index 0000000..549f054 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/79.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/8.mp3 b/site/app/partialemergence/sounds/Water/Paddling/8.mp3 Binary files differnew file mode 100644 index 0000000..7656b93 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/8.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/80.mp3 b/site/app/partialemergence/sounds/Water/Paddling/80.mp3 Binary files differnew file mode 100644 index 0000000..4ac99ca --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/80.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/81.mp3 b/site/app/partialemergence/sounds/Water/Paddling/81.mp3 Binary files differnew file mode 100644 index 0000000..4e7d90f --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/81.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/82.mp3 b/site/app/partialemergence/sounds/Water/Paddling/82.mp3 Binary files differnew file mode 100644 index 0000000..c272d99 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/82.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/83.mp3 b/site/app/partialemergence/sounds/Water/Paddling/83.mp3 Binary files differnew file mode 100644 index 0000000..c487263 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/83.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/84.mp3 b/site/app/partialemergence/sounds/Water/Paddling/84.mp3 Binary files differnew file mode 100644 index 0000000..736c012 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/84.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/85.mp3 b/site/app/partialemergence/sounds/Water/Paddling/85.mp3 Binary files differnew file mode 100644 index 0000000..fb8af59 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/85.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/86.mp3 b/site/app/partialemergence/sounds/Water/Paddling/86.mp3 Binary files differnew file mode 100644 index 0000000..bb3749c --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/86.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/87.mp3 b/site/app/partialemergence/sounds/Water/Paddling/87.mp3 Binary files differnew file mode 100644 index 0000000..94b1830 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/87.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/88.mp3 b/site/app/partialemergence/sounds/Water/Paddling/88.mp3 Binary files differnew file mode 100644 index 0000000..adfa03a --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/88.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/89.mp3 b/site/app/partialemergence/sounds/Water/Paddling/89.mp3 Binary files differnew file mode 100644 index 0000000..d38aec0 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/89.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/9.mp3 b/site/app/partialemergence/sounds/Water/Paddling/9.mp3 Binary files differnew file mode 100644 index 0000000..e0dfc4b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/9.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/90.mp3 b/site/app/partialemergence/sounds/Water/Paddling/90.mp3 Binary files differnew file mode 100644 index 0000000..ba243e6 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/90.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/91.mp3 b/site/app/partialemergence/sounds/Water/Paddling/91.mp3 Binary files differnew file mode 100644 index 0000000..7ed13da --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/91.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/92.mp3 b/site/app/partialemergence/sounds/Water/Paddling/92.mp3 Binary files differnew file mode 100644 index 0000000..ed4c84e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/92.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/93.mp3 b/site/app/partialemergence/sounds/Water/Paddling/93.mp3 Binary files differnew file mode 100644 index 0000000..f6f1e02 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/93.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/94.mp3 b/site/app/partialemergence/sounds/Water/Paddling/94.mp3 Binary files differnew file mode 100644 index 0000000..b6525de --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/94.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/95.mp3 b/site/app/partialemergence/sounds/Water/Paddling/95.mp3 Binary files differnew file mode 100644 index 0000000..9955f67 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/95.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/96.mp3 b/site/app/partialemergence/sounds/Water/Paddling/96.mp3 Binary files differnew file mode 100644 index 0000000..f6a5b5e --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/96.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/97.mp3 b/site/app/partialemergence/sounds/Water/Paddling/97.mp3 Binary files differnew file mode 100644 index 0000000..b2eb357 --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/97.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/98.mp3 b/site/app/partialemergence/sounds/Water/Paddling/98.mp3 Binary files differnew file mode 100644 index 0000000..dcccd9b --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/98.mp3 diff --git a/site/app/partialemergence/sounds/Water/Paddling/99.mp3 b/site/app/partialemergence/sounds/Water/Paddling/99.mp3 Binary files differnew file mode 100644 index 0000000..a7e400d --- /dev/null +++ b/site/app/partialemergence/sounds/Water/Paddling/99.mp3 diff --git a/site/app/twigs/index.html b/site/app/twigs/index.html new file mode 100644 index 0000000..6251fe8 --- /dev/null +++ b/site/app/twigs/index.html @@ -0,0 +1,54 @@ +<html>
+ <head>
+ <title>twigs</title>
+ <link rel="stylesheet" href="../twirl/theme.css">
+ <link rel="stylesheet" href="../twirl/twirl.css">
+ <link rel="stylesheet" href="twigs.css">
+ <script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+ <script type="text/javascript" src="../base/base.js"></script>
+ <script type="text/javascript" src="../twirl/twirl.js"></script>
+ <script type="text/javascript" src="../twirl/appdata.js"></script>
+ <script type="text/javascript" src="../twirl/transform.js"></script>
+ <script type="text/javascript" src="twigs_ui.js"></script>
+ <script type="text/javascript" src="twigs.js"></script>
+ <script type="text/javascript">
+ $(twigs_startisolated);
+ </script>
+ </head>
+
+ <body>
+ <div id="twigs">
+ <div id="twigs_hidden_links">
+ <a id="twigs_contact" href="https://csound.1bpm.net/contact/?type=general&app=twigs" target="_blank">Contact</a>
+ <a id="twigs_reportbug" href="https://csound.1bpm.net/contact/?type=report_bug&app=twigs" target="_blank">Report bug</a>
+ <a id="twigs_documentation" href="documentation.html" target="_blank">Documentation</a>
+ </div>
+ <div id="twigs_menubar"></div>
+ <div id="twigs_main">
+ <div id="twigs_sidebar"></div>
+ <div id="twigs_options"></div>
+ <div id="twigs_editor">
+ <div id="twigs_editor_inner">
+ <div id="twigs_playhead"></div>
+ <div id="twigs_selection"></div>
+ </div>
+ <div id="twigs_editor_hscrollouter">
+ <div id="twigs_editor_hscrollinner"></div>
+ </div>
+ <div id="twigs_editor_vscrollouter">
+ <div id="twigs_editor_vscrollinner"></div>
+ </div>
+ <div id="twigs_editor_vzoom"></div>
+ <div id="twigs_editor_hzoom"></div>
+ </div>
+ </div>
+ </div>
+ <div id="twigs_start">
+ <div id="twigs_startinner">
+ <h1>twigs</h1>
+ <p>spectral transformer</p>
+ <div id="twigs_startbig">Press to begin</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/site/app/twigs/twigs.csd b/site/app/twigs/twigs.csd new file mode 100644 index 0000000..d86616d --- /dev/null +++ b/site/app/twigs/twigs.csd @@ -0,0 +1,18 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+#include "/twigs/twigs.udo"
+
+</CsInstruments>
+<CsScore>
+f0 z
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/twigs/twigs.css b/site/app/twigs/twigs.css new file mode 100644 index 0000000..9e73df3 --- /dev/null +++ b/site/app/twigs/twigs.css @@ -0,0 +1,167 @@ +body {
+ font-family: var(--fontFace);
+ color: var(--fgColor1);
+ user-select: none;
+ cursor: arrow;
+}
+
+#twigs_playhead {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ width: 1px;
+ background-color: var(--waveformPlayheadColor);
+ border: 1px solid var(--waveformPlayheadColor);
+ pointer-events: none;
+ z-index: 23;
+ display: none;
+}
+
+#twigs_main {
+ position: absolute;
+ top: 20px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+}
+
+#twigs_options {
+ position: absolute;
+ bottom: 0px;
+ left: 60px;
+ right: 0px;
+ height: 20%;
+ background-color: var(--bgColor1);
+}
+
+#twigs_editor {
+ position: absolute;
+ top: 0px;
+ bottom: 20%;
+ left: 60px;
+ right: 0px;
+}
+
+#twigs_editor_inner {
+ position: absolute;
+ top: 0px;
+ bottom: 20px;
+ left: 0px;
+ right: 20px;
+}
+
+#twigs_selection {
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ height: 0px;
+ width: 0px;
+ display: none;
+ background-color: var(--waveformSelectColor);
+ opacity: var(--waveformSelectOpacity);
+ z-index: 15;
+}
+
+#twigs_editor_vscrollouter {
+ position: absolute;
+ top: 0px;
+ bottom: 80px;
+ width: 20px;
+ right: 0px;
+ background-color: var(--waveformTimeBarBgColor);
+}
+
+#twigs_editor_vscrollinner {
+ position: absolute;
+ left: 4px;
+ right: 4px;
+ top: 0px;
+ bottom: 0px;
+ background-color: var(--waveformTimeBarFgColor);
+}
+
+#twigs_editor_vzoom {
+ position: absolute;
+ right: 0px;
+ bottom: 20px;
+ height: 60px;
+ width: 20px;
+ background-color: var(--bgColor3);
+}
+
+#twigs_editor_hzoom {
+ position: absolute;
+ background-color: var(--bgColor3);
+ right: 0px;
+ bottom: 0px;
+ width: 80px;
+ height: 20px;
+}
+
+#twigs_editor_hscrollouter {
+ position: absolute;
+ height: 20px;
+ bottom: 0px;
+ left: 0px;
+ right: 80px;
+ background-color: var(--waveformTimeBarBgColor);
+}
+
+#twigs_editor_hscrollinner {
+ position: absolute;
+ top: 4px;
+ bottom: 4px;
+ left: 0px;
+ right: 0px;
+ background-color: var(--waveformTimeBarFgColor);
+}
+
+#twigs_sidebar {
+ position: absolute;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ width: 60px;
+ background-color: var(--bgColor1);
+}
+
+#twigs_start {
+ z-index: 300;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: var(--bgColor2);
+ cursor: pointer;
+}
+
+#twigs_startinner {
+ z-index: 202;
+ text-align: centre;
+ margin: 0px;
+ position: absolute;
+ top: 20%;
+ left: 20%;
+ width: 60%;
+ height: 40%;
+}
+
+#twigs_startbig {
+ font-size: 48pt;
+}
+
+#twigs_menubar {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ right: 0px;
+ height: 20px;
+ z-index: 40;
+}
+
+#twigs_hidden_links {
+ display: none;
+}
\ No newline at end of file diff --git a/site/app/twigs/twigs.js b/site/app/twigs/twigs.js new file mode 100644 index 0000000..7567dd0 --- /dev/null +++ b/site/app/twigs/twigs.js @@ -0,0 +1,1165 @@ +var Twigs = function() {
+ var twigs = this;
+ twigs.version = 1;
+ twirl.init();
+ twigs.SELECTIONMODE = {
+ singleBin: 0,
+ dragBins: 1,
+ dragArea: 2,
+ lasso: 3,
+ binAppend: 4,
+ draw: 5,
+ move: -1,
+ transpose: -2
+ };
+ twigs.selectionMode = twigs.SELECTIONMODE.singleBin;
+ twigs.undoLevel = 0;
+ var elCanvas;
+ var elHitCanvas;
+ var elSelectCanvas;
+ var elGridCanvas;
+ var elSelection = $("#twigs_selection");
+ var elContainer;
+ var width;
+ var height;
+ var playing;
+ var loaded = {
+ name: null,
+ channels: null,
+ bins: null,
+ tables: null,
+ length: null,
+ binSelectionTable: null,
+ binTimeSelectionTable: null
+ };
+ var maxfreq = 22050;
+ var amplitudeScaling = 40;
+
+ var ctx;
+ var ctxHit;
+ var ctxSelect;
+ var ctxGrid;
+
+ var xsteps;
+ var xstep;
+ var tabstep;
+ var region = {frequency: [0, 1], time: [0, 1]};
+ var selection = {bins: {}};
+ var binColourHash = {};
+ var colIDs;
+ var onSave;
+ twigs.visible = false;
+ twigs.twine = null;
+
+ twigs.storage = localStorage.getItem("twigs");
+ if (twigs.storage) {
+ twigs.storage = JSON.parse(twigs.storage);
+ } else {
+ twigs.storage = {
+ graphType: 0,
+ maxundo: 2,
+ drawFrequencyGrid: 1,
+ drawTimeGrid: 1
+ };
+ }
+
+ this.saveStorage = function() {
+ localStorage.setItem("twigs", JSON.stringify(twigs.storage));
+ };
+
+ function absPosToDisplayPos(x) {
+ var pos = (x - region.time[0]) / (region.time[1] - region.time[0]);
+ return (pos >= 0 && pos <= 1) ? pos : null;
+ }
+
+ function displayPosToAbsPos(x) {
+ return ((region.time[1] - region.time[0]) * x) + region.time[0];
+ }
+
+ function pxToFreq(px, height) {
+ return ((px / height) * ((region.frequency[1] - region.frequency[0]) * maxfreq));
+ //return (((region.frequency[1] - region.frequency[0]) * maxfreq) / height) * px;
+ }
+
+ function pxToFrames(px, width) {
+ var frames = Math.round(loaded.length / loaded.bins);
+ console.log("move ", px, "wid", width);
+ return Math.round(((px / width) * (region.time[1] - region.time[0]) * frames));
+ //return Math.round((((region.time[1] - region.time[0]) * (loaded.length / loaded.bins)) / width) * px);
+ }
+
+ var playheadInterval;
+ function playPositionHandler(onComplete) {
+ function callback(ndata) {
+ if (ndata.status == 1) {
+ twigs.setPlaying(true);
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ playheadInterval = setInterval(async function(){
+ var val = await app.getControlChannel("twgs_playposratio");
+ if (val < 0 || val > 1) {
+ clearInterval(playheadInterval);
+ }
+ movePlayhead(val);
+ }, 50);
+ } else { // stopped for some reason
+ if (ndata.status == -1) {
+ twirl.prompt.show("Not enough processing power to play in realtime");
+ }
+ twigs.setPlaying(false);
+ app.removeCallback(ndata.cbid);
+ movePlayhead(0);
+ if (playheadInterval) clearInterval(playheadInterval);
+ if (onComplete) onComplete(ndata);
+ }
+ }
+ return app.createCallback(callback, true);
+ }
+
+ function movePlayhead(xratio) {
+ setTimeout(function() {
+ var p = $("#twigs_playhead");
+ var displayPos = absPosToDisplayPos(xratio);
+ if (!displayPos || displayPos <= 0 || displayPos >= 1) {
+ return p.hide();
+ }
+ var width = elContainer.width();
+ var left = Math.min(width * displayPos, width -1);
+ p.show().css({left: left + "px"});
+ }, twirl.latencyCorrection);
+ }
+
+ this.hasSelection = function() {
+ return (Object.keys(selection.bins) != 0);
+ }
+
+ this.selectionOperation = {
+ move: async function(freqshift, timeshiftframes) {
+ console.log("ts", timeshiftframes, "fs", freqshift);
+ console.log("move duration", (timeshiftframes / Math.round(loaded.length / loaded.bins)) * loaded.duration);
+ twirl.loading.show("Applying");
+ await setBinSelectionTable();
+ var cbid1 = app.createCallback(function(ndata1){
+ var cbid2 = app.createCallback(function(ndata2){
+ clearSelection();
+ globalCallbackHandler(ndata2);
+ });
+ app.insertScore("twgs_movement", [0, 1, cbid2, timeshiftframes]);
+ });
+ app.insertScore("twgs_freqshift", [0, 1, cbid1, freqshift, 1]);
+ },
+ shift: async function(freqshift) {
+ twirl.loading.show("Applying");
+ await setBinSelectionTable();
+ var cbid = app.createCallback(function(ndata){
+ clearSelection();
+ globalCallbackHandler(ndata);
+ });
+ app.insertScore("twgs_freqshift", [0, 1, cbid, freqshift]);
+
+ /*for (let b of selection.bins) {
+ for (var i = b; i < loaded.length; i += loaded.bins) {
+ var val = await app.getCsound().tableGet(loaded.tables[1], index);
+ val += freqshift;
+ val = Math.max(Math.min(val, maxfreq), 0);
+ await app.getCsound().tableSet(loaded.tables[1], index, val)
+ }
+ }
+ clearSelection();
+ twigs.redraw();
+ */
+ },
+ amplify: async function(factor) {
+ twirl.loading.show("Applying");
+ await setBinSelectionTable();
+ var cbid = app.createCallback(function(ndata){
+ globalCallbackHandler(ndata);
+ });
+ app.insertScore("twgs_amplify", [0, 1, cbid, factor]);
+ }
+ };
+
+ async function setBinSelectionTable() {
+ var length = await app.getCsound().tableLength(loaded.binSelectionTable);
+ var selectionData = [];
+ var timeData = [];
+ var region = [1, 0];
+ for (var i = 0; i < length; i++) {
+ if (selection.bins[i]) {
+ selectionData[i] = 1;
+ timeData[i] = selection.bins[i][0];
+ timeData[i + length] = selection.bins[i][1];
+ if (selection.bins[i][0] < region[0]) region[0] = selection.bins[i][0];
+ if (selection.bins[i][1] > region[1]) region[1] = selection.bins[i][1];
+ } else {
+ selectionData[i] = 0;
+ timeData[i] = -1;
+ timeData[i + length] = -1;
+ }
+ }
+ await app.getCsound().tableCopyIn(loaded.binSelectionTable, selectionData);
+ await app.getCsound().tableCopyIn(loaded.binTimeSelectionTable, timeData);
+ return region;
+ }
+
+
+ this.setSelectionMode = function(mode) {
+ twigs.selectionMode = mode;
+ if (mode >= 0) {
+ selection.bins = {};
+ clearSelection();
+ }
+ elSelection.hide();
+ };
+
+ this.setTimeRegion = function(start, end, noRedraw) {
+ region.time[0] = start;
+ region.time[1] = end;
+ var outerWidth = elScrollOuterH.width();
+ elScrollInnerH.css({
+ left: (start * outerWidth) + "px",
+ right: ((1 - end) * outerWidth) + "px"
+ });
+ if (!noRedraw) twigs.redraw();
+ };
+
+ this.setFrequencyRegion = function(start, end, noRedraw) {
+ region.frequency[0] = start;
+ region.frequency[1] = end;
+ var outerHeight = elScrollOuterV.height();
+ elScrollInnerV.css({
+ bottom: (start * outerHeight) + "px",
+ top: ((1 - end) * outerHeight) + "px"
+ });
+ if (!noRedraw) twigs.redraw();
+ };
+
+ function setScrollPositionV(displayTop, displayBottom, setRegion) {
+ if (displayTop >= 0 && displayBottom >= 0) {
+ elScrollInnerV.css({top: displayTop, bottom: displayBottom});
+ var h = elScrollOuterV.height();
+ region.frequency[0] = displayTop / h;
+ region.frequency[1] = 1 - (displayBottom / h);
+ }
+ }
+
+ function handleScrollOuterV(e) {
+ var increment = 20;
+ var apos = event.pageX - elScrollOuterV.offset().left;
+ var top = parseInt(elScrollInnerV.css("bottom"));
+ var bottom = parseInt(elScrollInnerV.css("bottom"));
+ var tbHeight = parseInt(elScrollInnerV.css("height"));
+ if (apos < top) {
+ top -= increment;
+ bottom += increment;
+ } else if (apos > top + tbHeight) {
+ top += increment;
+ bottom -= increment;
+ } else {
+ return;
+ }
+ setScrollPositionV(top, bottom);
+ twigs.redraw();
+ }
+
+ function handleScrollInnerV(e) {
+ var pageY = e.pageY;
+ var offset = elScrollOuterV.offset();
+ var cHeight = elScrollOuterV.height();
+ var tHeight = elScrollInnerV.height();
+ var sTop = pageY - offset.top - parseInt(elScrollInnerV.css("top"));
+
+ function handleDrag(e) {
+ var top = ((e.pageY - pageY) + (pageY - offset.top));
+ top = top - sTop;
+ var end = top + tHeight;
+ var bottom = cHeight - end;
+ setScrollPositionV(top, cHeight - end);
+ twigs.redraw(20, true);
+
+ }
+ function handleMouseUp(e) {
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp);
+ function ensureDraw() {
+ if (drawing) return setTimeout(ensureDraw, 20);
+ twigs.redraw();
+ }
+ ensureDraw();
+ }
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ }
+
+ function setScrollPositionH(displayLeft, displayRight) {
+ if (displayLeft >= 0 && displayRight >= 0) {
+ elScrollInnerH.css({left: displayLeft, right: displayRight});
+ var w = elScrollOuterH.width();
+ region.time[0] = displayLeft / w;
+ region.time[1] = 1 - (displayRight / w);
+ }
+ }
+
+ function handleScrollOuterH(e) {
+ var increment = 20;
+ var apos = event.pageX - elScrollOuterH.offset().left;
+ var left = parseInt(elScrollInnerH.css("left"));
+ var right = parseInt(elScrollInnerH.css("right"));
+ var tbWidth = parseInt(elScrollInnerH.css("width"));
+ if (apos < left) {
+ left -= increment;
+ right += increment;
+ } else if (apos > left + tbWidth) {
+ left += increment;
+ right -= increment;
+ } else {
+ return;
+ }
+ setScrollPositionH(left, right);
+ twigs.redraw();
+ }
+
+ function handleScrollInnerH(e) {
+ var pageX = e.pageX;
+ var offset = elScrollOuterH.offset();
+ var cWidth = elScrollOuterH.width();
+ var tbWidth = elScrollInnerH.width();
+ var sLeft = pageX - offset.left - parseInt(elScrollInnerH.css("left"));
+
+ function handleDrag(e) {
+ var left = ((e.pageX - pageX) + (pageX - offset.left));
+ left = left - sLeft;
+ var end = left + tbWidth;
+ var right = cWidth - end;
+ setScrollPositionH(left, cWidth - end);
+ twigs.redraw(20, true);
+
+ }
+ function handleMouseUp(e) {
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp);
+ function ensureDraw() {
+ if (drawing) return setTimeout(ensureDraw, 20);
+ twigs.redraw();
+ }
+ ensureDraw();
+ }
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ }
+
+ var elScrollOuterH = $("#twigs_editor_hscrollouter").click(handleScrollOuterH);
+ var elScrollInnerH = $("#twigs_editor_hscrollinner").click(handleScrollInnerH);
+ var elScrollOuterV = $("#twigs_editor_vscrollouter").click(handleScrollOuterV);
+ var elScrollInnerV = $("#twigs_editor_vscrollinner").click(handleScrollInnerV);
+
+
+
+ this.vzoomIn = function() {
+ twigs.setFrequencyRegion(region.frequency[0] * 1.1, region.frequency[1] * 0.9);
+ };
+
+ this.vzoomOut = function() {
+ twigs.setFrequencyRegion(region.frequency[0] * 0.9, region.frequency[1] * 1.1);
+ };
+
+ this.hzoomIn = function() {
+ twigs.setTimeRegion(region.time[0] * 1.1, region.time[1] * 0.9);
+ };
+
+ this.hzoomOut = function() {
+ twigs.setTimeRegion(region.time[0] * 0.9, region.time[1] * 1.1);
+ };
+
+ async function withBinPoints(bin, func) {
+ for (var x = 0, i = parseInt(bin); i < loaded.length; i += tabstep, x += xstep) {
+ await func(i, x)
+ }
+ }
+
+ function clearSelection() {
+ selection.bins = {};
+ ctxSelect.clearRect(0, 0, width, height);
+ }
+
+ async function drawSelection() {
+ var startFreq = region.frequency[0] * maxfreq;
+ var endFreq = region.frequency[1] * maxfreq;
+ var freqRange = endFreq - startFreq;
+ var height = elContainer.height();
+ var width = elContainer.width();
+ var freqTable = await app.getCsound().getTable(loaded.tables[1]);
+ ctxSelect.clearRect(0, 0, width, height);
+ ctxSelect.strokeStyle = "red";
+ ctxSelect.lineWidth = 2;
+
+ async function drawBin(bin, times) {
+ if (twigs.storage.graphType == 0) ctxSelect.beginPath();
+
+ var lastfreq = null;
+ await withBinPoints(bin, function(i, x){
+ var freq = freqTable[i];
+ var xRatio = x / width;
+ if (xRatio < absPosToDisplayPos(times[0]) || xRatio > absPosToDisplayPos(times[1])) return;
+
+ if (twigs.storage.graphType == 1) {
+ var yPos = ((freqRange - freq) / freqRange) * height;
+ ctxSelect.beginPath();
+ ctxSelect.moveTo(x, yPos);
+ ctxSelect.lineTo(x + xstep, yPos);
+ ctxSelect.stroke();
+ ctxSelect.closePath();
+ } else {
+ if (lastfreq) {
+ var yPos = [
+ ((freqRange - lastfreq) / freqRange) * height,
+ ((freqRange - freq) / freqRange) * height
+ ];
+ ctxSelect.moveTo(x - xstep, yPos[0]);
+ ctxSelect.lineTo(x, yPos[1]);
+ }
+ lastfreq = freq;
+ }
+ });
+ if (twigs.storage.graphType == 0) {
+ ctxSelect.stroke();
+ ctxSelect.closePath();
+ }
+ }
+ for (let b in selection.bins) {
+ await drawBin(b, selection.bins[b]);
+ }
+
+ }
+
+
+ function setup() {
+ elContainer = $("#twigs_editor_inner");
+ width = elContainer.width(); // deprecate it
+ height = elContainer.height();
+
+ var dragStart = [];
+ var dragLast = [];
+ var offset;
+
+ elHitCanvas = $("<canvas />").css({
+ position: "absolute", width: "100%", height: "100%"
+ }).attr("width", width)
+ .attr("height", height);
+ elCanvas = $("<canvas />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "z-index": 12})
+ .attr("width", width)
+ .attr("height", height)
+ .appendTo(elContainer);
+
+ function mouseMove(e){
+ if (dragStart.length == 0) {
+ return;
+ }
+ if (twigs.selectionMode == twigs.SELECTIONMODE.singleBin || twigs.selectionMode == twigs.SELECTIONMODE.binAppend) {
+ return;
+ }
+
+ var x = e.clientX - offset.left;
+ var y = e.clientY - offset.top;
+ if (twigs.selectionMode == twigs.SELECTIONMODE.lasso) {
+ //ctxSelect.moveTo(dragLast[0], dragLast[1]);
+ ctxSelect.lineTo(x, y);
+ dragLast[0] = x;
+ dragLast[1] = y;
+ ctxSelect.stroke();
+ return;
+ }
+
+ if (twigs.selectionMode == twigs.SELECTIONMODE.move) {
+ var xMovement = x - dragLast[0];
+ var yMovement = y - dragLast[1];
+ ctxSelect.globalCompositeOperation = "copy";
+ ctxSelect.drawImage(ctxSelect.canvas, xMovement, yMovement);
+ ctxSelect.globalCompositeOperation = "source-over";
+
+ dragLast[0] = x;
+ dragLast[1] = y;
+ return;
+ }
+
+ if (twigs.selectionMode == twigs.SELECTIONMODE.transpose) {
+ var xMovement = x - dragLast[0];
+ }
+
+ var x, cx, width;
+ if (twigs.selectionMode == twigs.SELECTIONMODE.dragBins) {
+ x = 0;
+ width = elContainer.width();
+ } else {
+ x = dragStart[0];
+ cx = e.clientX - offset.left
+ if (x > cx) {
+ width = x - cx;
+ x = cx;
+ } else {
+ width = cx - x;
+ }
+ }
+ var y = dragStart[1];
+ var cy = e.clientY - offset.top;
+ var height = cy - y;
+ elSelection.css({
+ left: x + "px", top: y + "px",
+ width: width + "px", height: height + "px"
+ }).show();
+ }
+
+ function mouseUp(e){
+ var x = e.clientX - offset.left;
+ var y = e.clientY - offset.top;
+ var xMovement = x - dragStart[0];
+ var yMovement = y - dragStart[1];
+ if (twigs.selectionMode < 0) {
+ twigs.selectionOperation.move(
+ pxToFreq(-yMovement, elContainer.height()),
+ pxToFrames(xMovement, elContainer.width())
+ );
+ //twigs.selectionOperation.shift(pxToFreq(-yMovement));
+ } else if (twigs.selectionMode == twigs.SELECTIONMODE.lasso) {
+ //ctxSelect.moveTo(dragLast[0], dragLast[1]);
+ ctxSelect.lineTo(dragStart[0], dragStart[1]);
+ ctxSelect.stroke();
+ ctxSelect.fillStyle = "rgb(255, 0, 0)";
+ ctxSelect.fill();
+ ctxSelect.closePath();
+ twirl.loading.show("Finding frequencies");
+ setTimeout(function(){
+ var width = elContainer.width();
+ var id = ctxSelect.getImageData(0, 0, width, elContainer.height());
+
+ var x = 0;
+ var y = 0;
+ var bins = {};
+ for (var i = 0; i < id.data.length; i += 4) {
+ if (id.data[i] == "255") {
+ var pixel = ctxHit.getImageData(x, y, 1, 1);
+ var colour = "rgb(" + pixel.data[0] + ","
+ + pixel.data[1] + ","
+ + pixel.data[2] + ")";
+ var bin = binColourHash[colour];
+ if (bin) {
+ if (bins[bin]) {
+ if (x < bins[bin][0]) bins[bin][0] = x;
+ if (x > bins[bin][1]) bins[bin][1] = x;
+ } else {
+ bins[bin] = [x, x];
+ }
+ }
+ }
+
+ x ++;
+ if (x >= width) {
+ x = 0;
+ y ++;
+ }
+ }
+ for (var b in bins) {
+ selection.bins[b] = [
+ displayPosToAbsPos(bins[b][0] / width),
+ displayPosToAbsPos(bins[b][1] / width)
+ ]
+ }
+ ctxSelect.clearRect(0, 0, width, height);
+ drawSelection();
+ twirl.loading.hide();
+ }, 10);
+
+ } else if (twigs.selectionMode == twigs.SELECTIONMODE.dragBins || twigs.selectionMode == twigs.SELECTIONMODE.dragArea) {
+ var selWidth = x - xMovement;
+ var time;
+ if (twigs.selectionMode == twigs.SELECTIONMODE.dragArea) {
+ var containerWidth = elContainer.width();
+ time = [
+ dragStart[0] / containerWidth,
+ x / containerWidth
+ ];
+ } else {
+ time = [0, 1];
+ }
+ var bins = [];
+ var pixels = ctxHit.getImageData(dragStart[0], dragStart[1], xMovement, yMovement); //x, y, xMovement, yMovement);
+ for (var i = 0; i < pixels.data.length; i += 4) {
+ var colour = "rgb(" + pixels.data[i] + ","
+ + pixels.data[i + 1] + ","
+ + pixels.data[i + 2] + ")";
+ var bin = binColourHash[colour];
+ if (bin && bins.indexOf(bin) < 0) {
+ bins.push(bin);
+ selection.bins[bin] = [
+ displayPosToAbsPos(time[0]),
+ displayPosToAbsPos(time[1])
+ ]
+ }
+ }
+ drawSelection();
+ }
+ elSelection.hide();
+ dragStart = [];
+ dragLast = [];
+ $("body").off("mouseup", mouseUp).off("mousemove", mouseMove);
+ }
+
+ elGridCanvas = $("<canvas />").css({
+ position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "z-index": 12
+ }).attr("width", width).attr("height", height).appendTo(elContainer);
+
+ elSelectCanvas = $("<canvas />").css({
+ position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "z-index": 13
+ }).attr("width", width) .attr("height", height).appendTo(elContainer).on("mousedown", function(e){
+ offset = $(this).offset();
+ var x = e.clientX - offset.left;
+ var y = e.clientY - offset.top;
+ dragStart = [x, y];
+ dragLast = [x, y];
+ if (twigs.selectionMode == twigs.SELECTIONMODE.singleBin || twigs.selectionMode == twigs.SELECTIONMODE.binAppend) {
+ const pixel = ctxHit.getImageData(x, y, 1, 1);
+ const colour = "rgb(" + pixel.data[0] + ","
+ + pixel.data[1] + ","
+ + pixel.data[2] + ")";
+ const bin = binColourHash[colour];
+ if (bin) {
+ var binTime = [
+ displayPosToAbsPos(0),
+ displayPosToAbsPos(1),
+ ]
+ if (twigs.selectionMode == twigs.SELECTIONMODE.binAppend) {
+ selection.bins[bin] = binTime;
+ } else {
+ clearSelection();
+ selection.bins[bin] = binTime;
+ }
+ drawSelection();
+ }
+ } else {
+ if (twigs.selectionMode == twigs.SELECTIONMODE.lasso) {
+ clearSelection();
+ ctxSelect.strokeStyle = "black";
+ ctxSelect.fillStyle = "rgb(10, 10, 10, 50)";
+ ctxSelect.lineWidth = 2;
+ ctxSelect.moveTo(dragStart[0], dragStart[1]);
+ ctxSelect.beginPath();
+ }
+ $("body").on("mouseup", mouseUp).on("mousemove", mouseMove);
+ }
+ });
+ ctx = elCanvas[0].getContext("2d");
+ ctxHit = elHitCanvas[0].getContext("2d", {willReadFrequently: true});
+ ctxSelect = elSelectCanvas[0].getContext("2d", {willReadFrequently: true});
+ ctxGrid = elGridCanvas[0].getContext("2d");
+ }
+
+
+
+ function getNextColour() {
+ if (colIDs[0] < 255) {
+ colIDs[0] += 5;
+ } else if (colIDs[1] < 255) {
+ colIDs[1] += 5;
+ } else {
+ colIDs[2] += 5;
+ }
+ return "rgb(" + colIDs.join(",") + ")";
+ }
+
+ this.setPlaying = function(state) {
+ playing = state;
+ };
+
+ this.undo = function() {
+ if (playing) return;
+ twirl.loading.show("Applying");
+ var cbid = app.createCallback(globalCallbackHandler);
+ app.insertScore("twgs_undo", [0, 1, cbid]);
+ };
+
+ this.play = async function(selectedOnly) {
+ if (playing) return;
+ if (!twigs.storage.resynthType) {
+ twigs.storage.resynthType = 0;
+ twigs.saveStorage();
+ }
+ errorState = "Playback error";
+ var region = [0, 1];
+ if (selectedOnly) {
+ region = await setBinSelectionTable();
+ }
+ app.insertScore("twgs_play", [
+ 0, 1, playPositionHandler(),
+ 0, ((selectedOnly) ? 1 : 0),
+ region[0], region[1],
+ twigs.storage.resynthType
+ ]);
+ };
+
+ this.increaseAmpScaling = function() {
+ amplitudeScaling += 20;
+ twigs.redraw();
+ };
+
+ this.decreaseAmpScaling = function() {
+ amplitudeScaling -= 20;
+ if (amplitudeScaling <= 0) amplitudeScaling = 20;
+ twigs.redraw();
+ };
+
+
+ function spectroColour(value) {
+ var min = 16711680
+ var max = 255
+ var colourNumber = parseInt(((max - min) * value) + min);
+ function toHex(n) {
+ n = n.toString(16) + '';
+ return n.length >= 2 ? n : new Array(2 - n.length + 1).join('0') + n;
+ }
+
+ var r = toHex(colourNumber % 256),
+ g = toHex(Math.floor(colourNumber / 256 ) % 256),
+ b = toHex(Math.floor(Math.floor(colourNumber / 256) / 256 ) % 256);
+ return '#' + r + g + b;
+ }
+
+ var drawing = false;
+ this.redraw = async function(efficiency, noLoadingPrompt) {
+ if (drawing) return;
+ drawing = true;
+ if (!efficiency) efficiency = 4;
+ if (!noLoadingPrompt) twirl.loading.show("Drawing");
+ if (twigs.storage.basicLines == null) twigs.storage.basicLines = 0;
+ var style = getComputedStyle(document.body);
+ var height = elContainer.height();
+ var width = elContainer.width();
+ [ctx, ctxSelect, ctxHit, ctxGrid].forEach(function(c){
+ c.clearRect(0, 0, width, height);
+ });
+ binColourHash = {};
+ colIDs = [0, 0, 0];
+
+ var startFreq = region.frequency[0] * maxfreq;
+ var endFreq = region.frequency[1] * maxfreq;
+ var freqRange = endFreq - startFreq;
+
+ var ampTableNum = loaded.tables[0];
+ var freqTableNum = loaded.tables[1];
+ var tableLength = await app.getCsound().tableLength(ampTableNum);
+ var ampTable = await app.getCsound().getTable(ampTableNum);
+ var freqTable = await app.getCsound().getTable(freqTableNum);
+
+ var totalFrames = tableLength / loaded.bins;
+ var startFrame = parseInt(region.time[0] * totalFrames);
+ var endFrame = parseInt(region.time[1] * totalFrames);
+ var frameRegion = endFrame - startFrame;
+ var startIndex = startFrame * loaded.bins;
+ var endIndex = endFrame * loaded.bins;
+ var indexStep = (frameRegion / width) * efficiency;
+ xstep = parseInt(Math.max(1, width / frameRegion) * efficiency);
+ tabstep = loaded.bins * Math.max(1, Math.round(indexStep));
+
+ if (!twigs.storage.basicLines) {
+ ctx.lineWidth = 2;
+ ctx.shadowBlur = 2;
+ } else {
+ ctx.lineWidth = 1;
+ ctx.shadowBlur = null;
+ ctx.shadowColor = null;
+ }
+
+ for (var b = 0; b < loaded.bins; b ++) {
+ var hitColour = getNextColour();
+ if (!binColourHash[hitColour]) {
+ binColourHash[hitColour] = b;
+ }
+
+ ctxHit.lineWidth = 4;
+ ctxHit.strokeStyle = hitColour;
+
+ if (twigs.storage.graphType == 0) ctxHit.beginPath();
+
+ var lastfreq = null;
+ for (var x = 0, i = b + startIndex; i < endIndex; i += tabstep, x += xstep) {
+ var freq = freqTable[i];
+
+ var colour;
+ if (twigs.storage.colourType == 1) {
+ colour = spectroColour(ampTable[i] * amplitudeScaling);
+ } else {
+ var cval = 255 - Math.round((ampTable[i] * amplitudeScaling) * 255);
+ cval = Math.min(Math.max(0, cval), 255);
+ colour = "rgb(" + cval + "," + cval + "," + cval + ")";
+ }
+
+ if (twigs.storage.graphType == 1) {
+ var yPos = ((freqRange - freq) / freqRange) * height;
+ ctx.beginPath();
+ ctx.moveTo(x, yPos);
+ ctx.lineTo(x + xstep, yPos);
+ ctx.strokeStyle = colour;
+ if (!twigs.storage.basicLines) ctx.shadowColor = colour;
+ ctx.stroke();
+ ctx.closePath();
+ ctxHit.beginPath();
+ ctxHit.moveTo(x, yPos);
+ ctxHit.lineTo(x + xstep, yPos);
+ ctxHit.stroke();
+ ctxHit.closePath();
+ } else if (twigs.storage.graphType == 0) {
+
+ if (lastfreq && lastfreq >= startFreq && lastfreq <= endFreq && freq >= startFreq && freq <= endFreq) {
+ var yPos = [
+ ((freqRange - lastfreq) / freqRange) * height,
+ ((freqRange - freq) / freqRange) * height
+ ];
+ ctx.beginPath();
+ ctx.moveTo(x - xstep, yPos[0]);
+ ctx.lineTo(x, yPos[1]);
+ ctx.strokeStyle = colour;
+ if (!twigs.storage.basicLines) ctx.shadowColor = colour;
+ ctx.stroke();
+ ctx.closePath();
+
+ ctxHit.moveTo(x - xstep, yPos[0]);
+ ctxHit.lineTo(x, yPos[1]);
+
+ }
+ lastfreq = freq;
+ }
+ }
+ if (twigs.storage.graphType == 0) {
+ ctxHit.stroke();
+ ctxHit.closePath();
+ }
+ }
+ /*
+ if (twigs.storage.drawFrequencyGrid) {
+ var lines = 10;
+ var ystep = height / lines;
+ var freqstep = (endFreq - startFreq) / lines;
+ ctxGrid.lineCap = "butt";
+ ctxGrid.lineWidth = 1;
+ for (var y = 0, freq = endFreq; y += ystep, freq -= freqstep; y < height) {
+ ctxGrid.strokeStyle = ctxGrid.fillStyle = "rgb(100, 0, 0, 40)"; //style.getPropertyValue("--waveformGridColor");
+ ctxGrid.beginPath();
+ ctxGrid.moveTo(0, y);
+ ctxGrid.lineTo(width, y);
+ ctxGrid.stroke();
+ ctxGrid.closePath();
+ //ctx.strokeStyle = ctx.fillStyle = style.getPropertyValue("--waveformGridTextColor");
+ ctxGrid.fillText(Math.round(freq), 0, y - 2);
+ }
+ }
+
+ if (twigs.storage.drawTimeGrid) {
+ var lines = 10;
+ var startTime = region.time[0] * loaded.duration;
+ var endTime = region.time[1] * loaded.duration;
+ var xstep = width / lines;
+ var timestep = (endTime - startTime) / lines;
+ ctxGrid.lineCap = "butt";
+ ctxGrid.lineWidth = 1;
+ for (var x = 0, time = startTime; x += xstep, time += timestep; x < width) {
+ if (x > width) break; // wtf??????? this is strangely happening
+ ctxGrid.strokeStyle = ctxGrid.fillStyle = "rgb(100, 0, 0, 40)"; //style.getPropertyValue("--waveformGridColor");
+ ctxGrid.beginPath();
+ ctxGrid.moveTo(x, 0);
+ ctxGrid.lineTo(x, height);
+ ctxGrid.stroke();
+ ctxGrid.closePath();
+ //ctx.strokeStyle = ctx.fillStyle = style.getPropertyValue("--waveformGridTextColor");
+ ctxGrid.fillText(Math.round(time * 1000) / 1000, x + 2, height - 2);
+ }
+ }
+ */
+
+ drawSelection();
+ if (!noLoadingPrompt) twirl.loading.hide();
+ drawing = false;
+ }
+
+ async function globalCallbackHandler(ndata) {
+ if (ndata.status && ndata.status <= 0) {
+ return self.errorHandler();
+ }
+
+ if (ndata.hasOwnProperty("undolevel")) {
+ twigs.undoLevel = ndata.undolevel;
+ }
+
+ if (ndata.channels) {
+ loaded.channels = ndata.channels;
+ }
+
+ var initialLoad = false;
+ if (ndata.bins) {
+ loaded.bins = ndata.bins;
+ initialLoad = true;
+ }
+
+ if (ndata.fftdecim) {
+ loaded.fftdecimation = ndata.fftdecim;
+ }
+
+ if (ndata.duration) {
+ loaded.duration = ndata.duration;
+ }
+
+ if (ndata.sr) {
+ maxfreq = ndata.sr / 2;
+ }
+
+ if (ndata.binseltab) {
+ loaded.binSelectionTable = ndata.binseltab;
+ }
+
+ if (ndata.bintimeseltab) {
+ loaded.binTimeSelectionTable = ndata.bintimeseltab;
+ }
+
+ if (ndata.tables) {
+ setTimeout(async function() {
+ loaded.tables = ndata.tables;
+ loaded.length = await app.getCsound().tableLength(loaded.tables[0]);
+ if (!twigs.storage.zoomOnLoad) twigs.storage.zoomOnLoad = 1;
+ if (initialLoad && twigs.storage.zoomOnLoad) {
+ twigs.setFrequencyRegion(0, 0.2, true);
+ twigs.setTimeRegion(0, 0.2);
+ } else {
+ twigs.redraw();
+ }
+ }, 10); // csound may not be ready
+ }
+ }
+
+ this.editInTwist = function() {
+ if (playing) return;
+ if (!twigs.storage.resynthType) {
+ twigs.storage.resynthType = 0;
+ twigs.saveStorage();
+ }
+ if (!window.twist) {
+ return twirl.prompt.show("twist is unavailable in this session");
+ }
+ twirl.loading.show("Processing");
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 3) {
+ return twirl.loading.show("Resynthesising");
+ }
+ twirl.loading.hide();
+ app.removeCallback(ndata.cbid);
+
+ twist.loadFileFromFtable(loaded.name, ndata.tables, function(ldata){
+ if (ldata.status > 0) {
+ self.setVisible(false);
+ twist.setVisible(true);
+ }
+ }, onSave);
+
+ }, true);
+ app.insertScore("twgs_resynth", [0, 1, cbid, "twgs_getbuffers", twigs.storage.resynthType]);
+ };
+
+ this.setVisible = function(state) {
+ twigs.visible = state;
+ var el = $("#twigs");
+ if (state) {
+ el.show();
+ } else {
+ el.hide();
+ }
+ };
+
+
+ function formatFileName(name) {
+ if (!name) name = waveformTabs[instanceIndex].text();
+ if (!name.toLowerCase().endsWith(".wav")) {
+ name += ".wav";
+ }
+
+ // HACK TODO: WASM can't overwrite files
+ name = name.substr(0, name.lastIndexOf(".")) + "." + saveNumber + name.substr(name.lastIndexOf("."));
+ saveNumber ++;
+ // END HACK
+ return name;
+ }
+
+ this.downloadFile = async function(path, name) {
+ if (!name) name = formatFileName(name);
+ var content = await app.readFile(path);
+ var blob = new Blob([content], {type: "audio/wav"});
+ var url = window.URL.createObjectURL(blob);
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a[0].click();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ app.unlinkFile(path);
+ }, 20000);
+ };
+
+ var saveNumber = 1;
+ this.saveFile = function(name, onComplete) {
+ if (!twigs.storage.resynthType) {
+ twigs.storage.resynthType = 0;
+ twigs.saveStorage();
+ }
+ if (playing) return;
+ if (onSave) {
+ twirl.loading.show("Processing");
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 3) {
+ return twirl.loading.show("Resynthesising");
+ }
+ twirl.loading.hide();
+ app.removeCallback(ndata.cbid);
+ onSave(ndata.tables);
+ }, true);
+ app.insertScore("twgs_resynth", [0, 1, cbid, "twgs_getbuffers", twigs.storage.resynthType]);
+ return;
+ }
+ if (!name) name = formatFileName(name);
+ var cbid = app.createCallback(async function(ndata){
+ if (ndata.status == 3) {
+ return twirl.loading.show("Resynthesising");
+ }
+ app.removeCallback(ndata.cbid);
+
+ twirl.loading.show("Saving");
+ app.insertScore("twgs_savefile", [0, 1, app.createCallback(async function(ldata){
+ if (onComplete) onComplete();
+ await self.downloadFile(ndata.path, ndata.path);
+ twirl.loading.hide();
+ }), name]);
+
+ }, true);
+ twist.loading.show("Processing");
+ app.insertScore("twgs_resynth", [0, 1, cbid, "twgs_resynth_response", twigs.storage.resynthType]);
+ };
+
+
+ this.loadFileFromFtable = function(name, tables, onComplete, onSaveFunc) {
+ errorState = "File loading error";
+ twigs.ui.showLoadFileFFTPrompt(function(fftSize, fftDecim){
+ twirl.loading.show("Loading file");
+
+ var cbid = app.createCallback(async function(ndata){
+ twirl.loading.hide();
+ if (ndata.status > 0) {
+ loaded.name = name;
+ await globalCallbackHandler(ndata);
+ onSave = onSaveFunc;
+ } else if (ndata.status == -1) {
+ twirl.prompt.show("File not valid");
+ } else if (ndata.status == -2) {
+ twirl.prompt.show("File too large");
+ } else {
+ twirl.prompt.show("File loading error");
+ }
+ if (onComplete) {
+ onComplete(ndata);
+ }
+ });
+ var call = [0, 1, cbid, fftSize, fftDecim];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twgs_loadftable", call);
+ });
+ };
+
+ async function handleFileDrop(e, obj) {
+ e.preventDefault();
+ if (!e.originalEvent.dataTransfer && !e.originalEvent.files) {
+ return;
+ }
+ if (e.originalEvent.dataTransfer.files.length == 0) {
+ return;
+ }
+ twirl.prompt.hide();
+ twirl.loading.show("Loading");
+ for (const item of e.originalEvent.dataTransfer.files) {
+ if (!twirl.audioTypes.includes(item.type)) {
+ return twirl.errorHandler("Unsupported file type");
+ }
+ if (item.size > twirl.maxFileSize) {
+ return twirl.errorHandler("File too large", twigs.ui.showLoadNewPrompt);
+ }
+ errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ await app.writeFile(item.name, buffer);
+
+ twigs.ui.showLoadFileFFTPrompt(function(fftSize, fftDecim){
+ twirl.loading.show("Loading file");
+ var cbid = app.createCallback(async function(ndata){
+ await app.unlinkFile(item.name);
+ if (ndata.status == -1) {
+ return twirl.errorHandler("File not valid", twigs.ui.showLoadNewPrompt);
+ } else if (ndata.status == -2) {
+ return twirl.errorHandler("File too large", twigs.ui.showLoadNewPrompt);
+ } else {
+ loaded.name = item.name;
+ await globalCallbackHandler(ndata);
+ onSave = false;
+ }
+ });
+ app.insertScore("twgs_loadfile", [0, 1, cbid, item.name, fftSize, fftDecim]);
+ });
+ }
+ }
+
+ this.bootAudio = function(twine) {
+ var channelDefaultItems = ["maxundo"];
+
+ for (var i of channelDefaultItems) {
+ if (twigs.storage.hasOwnProperty(i)) {
+ app.setControlChannel("twgs_" + i, twigs.storage[i]);
+ }
+ }
+ };
+
+ var booted = false;
+ this.boot = function(twine) {
+ if (booted) return;
+ booted = true;
+ setup();
+ twigs.ui = new TwigsUI(twigs);
+ if (!twine) {
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ }).on("drop", function(e) {
+ handleFileDrop(e, self);
+ });
+ } else {
+ twigs.twine = twine;
+ }
+ };
+
+};
+
+
+function twigs_startisolated() {
+ window.twigs = new Twigs();
+ twigs.setVisible(true);
+ window.app = new CSApplication({
+ csdUrl: "twigs.csd",
+ onPlay: function() {
+ twigs.bootAudio();
+ twirl.prompt.show("Drag a file here to begin", null, true);
+ twirl.loading.hide();
+ },
+ errorHandler: twirl.errorHandler
+ });
+ $("#twigs_start").click(function(){
+ $(this).hide();
+ twigs.boot();
+ twirl.loading.show("Preparing audio engine");
+ app.play(function(text){
+ twirl.loading.show(text);
+ });
+ });
+}
\ No newline at end of file diff --git a/site/app/twigs/twigs_ui.js b/site/app/twigs/twigs_ui.js new file mode 100644 index 0000000..1186dac --- /dev/null +++ b/site/app/twigs/twigs_ui.js @@ -0,0 +1,577 @@ +var twigsTopMenuData = [
+ {name: "File", contents: [
+ {name: "New", disableOnPlay: true, shortcut: {name: "Ctrl N", ctrlKey: true, key: "n"}, click: function(twigs) {
+ twigs.createNewInstance();
+ }},
+ {name: "Save", disableOnPlay: true, shortcut: {name: "Ctrl S", ctrlKey: true, key: "s"}, click: function(twigs) {
+ twigs.saveFile();
+ }},
+ {name: "Close", disableOnPlay: true, shortcut: {name: "Ctrl W", ctrlKey: true, key: "w"}, click: function(twigs) {
+ twigs.closeInstance();
+ }, condition: function(twist) {
+ return (!twist.twine);
+ }},
+ {name: "Edit in twist", click: function(twigs) {
+ twigs.editInTwist();
+ }, condition: function(twigs) {
+ return window.hasOwnProperty("Twist");
+ }}
+ ]},
+ {name: "Edit", contents: [
+ {name: "Undo", disableOnPlay: true, shortcut: {name: "Ctrl Z", ctrlKey: true, key: "z"}, click: function(twigs) {
+ twigs.undo();
+ }, condition: function(twigs) {
+ return (twigs.storage.maxundo > 0 && twigs.undoLevel > 0);
+ }}
+ ]},
+ {name: "View", contents: [
+ {name: "Contract channels", shortcut: {name: "C", key: "c"}, click: function(twigs) {
+ twigs.timeline.contractChannels();
+ }}
+ ]},
+ {name: "Action", contents: []},
+ {name: "Options", contents: [
+ {name: "Settings", click: function(twigs) {
+ twigs.ui.showSettings();
+ }}
+ ]},
+ {name: "Help", contents: [
+ {name: "Help", click: function(twigs){
+ $("#twigs_documentation")[0].click();
+ }},
+ {name: "Report bug", click: function(twist){
+ $("#twigs_reportbug")[0].click();
+ }},
+ {name: "Contact owner", click: function(twist){
+ $("#twigs_contact")[0].click();
+ }},
+ {name: "About", click: function(twigs) {
+ twigs.ui.showAbout();
+ }},
+ ]}
+];
+
+var TwigsUI = function(twigs) {
+ var ui = this;
+ var el = $("#twigs_sidebar");
+ var elEditor = $("#twigs_editor_inner");
+
+ ui.showLoadFileFFTPrompt = function(onComplete) {
+ var t = $("<table />");
+ var tb = $("<tbody />").appendTo(t);
+ var ksmps = 64;
+
+ var tr = $("<tr />").appendTo(tb);
+ $("<td />").text("FFT size").appendTo(tr);
+
+ var fftSize = $("<select />").change(function(){
+ updateDecimation();
+ });
+ $("<td />").appendTo(tr).append(fftSize);
+ for (let o of [256, 512, 1024, 2048]) {
+ $("<option />").val(o).text(o).appendTo(fftSize);
+ }
+
+ tr = $("<tr />").appendTo(tb);
+ $("<td />").text("FFT decimation").appendTo(tr);
+ var fftDecim = $("<select />");
+ $("<td />").appendTo(tr).append(fftDecim);
+
+ function updateDecimation() {
+ fftDecim.empty();
+ var max = fftSize.val() / 64;
+ var min = max / 2;
+ for (let o of [min, max]) {
+ $("<option />").val(o).text(o).appendTo(fftDecim);
+ }
+ }
+ twirl.prompt.show(t, function() {
+ onComplete(fftSize.val(), fftDecim.val());
+ });
+ fftSize.val(512);
+ updateDecimation();
+ };
+
+
+ function addActionMenu(menu, item) {
+ for (let i in twigsTopMenuData) {
+ if (twigsTopMenuData[i].name.toLowerCase() == menu.toLowerCase()) {
+ twigsTopMenuData[i].contents.push(item);
+ }
+ }
+ }
+
+ var zoomIcons = [
+ {
+ label: "Zoom in frequency",
+ icon: "zoomIn",
+ size: 20,
+ click: function() {
+ twigs.vzoomIn();
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_vzoom"
+ },
+ {
+ label: "Zoom out frequency",
+ icon: "zoomOut",
+ size: 20,
+ click: function() {
+ twigs.vzoomOut();
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_vzoom"
+ },
+ {
+ label: "Show all frequency",
+ icon: "showAll",
+ size: 20,
+ click: function() {
+ twigs.setFrequencyRegion(0, 1);
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_vzoom"
+ },
+ {
+ label: "Zoom in time",
+ icon: "zoomIn",
+ size: 20,
+ click: function() {
+ twigs.hzoomIn();
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_hzoom"
+ },
+ {
+ label: "Zoom out time",
+ icon: "zoomOut",
+ size: 20,
+ click: function() {
+ twigs.hzoomOut();
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_hzoom"
+ },
+ {
+ label: "Show all time",
+ icon: "showAll",
+ size: 20,
+ click: function() {
+ twigs.setTimeRegion(0, 1);
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_hzoom"
+ },
+ {
+ label: "Show all",
+ icon: "showAll",
+ size: 20,
+ click: function() {
+ twigs.setFrequencyRegion(0, 1, true);
+ twigs.setTimeRegion(0, 1);
+ },
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "view",
+ target: "#twigs_editor_hzoom"
+ }
+
+ ];
+
+
+ this.showAbout = function() {
+ var el = $("<div />");
+ var x = $("<div />").appendTo(el);
+ var string = "twigs";
+ var intervals = [];
+
+ function addChar(c) {
+ var elC = $("<h2 />").text(c).css("display", "inline-block").appendTo(x);
+ var rate = (Math.random() * 0.005) + 0.001;
+ var scale = 1;
+ var scaleDirection = false;
+ return setInterval(function(){
+ if (scaleDirection) {
+ if (scale < 1) {
+ scale += rate;
+ } else {
+ scaleDirection = false;
+ }
+ } else {
+ if (scale > 0.05) {
+ scale -= rate;
+ } else {
+ scaleDirection = true;
+ }
+ }
+ elC.css("transform", "scaleX(" + scale + ")");
+ }, (Math.random() * 10) + 8);
+ }
+ for (let c of string) {
+ intervals.push(addChar(c));
+ }
+
+ $("<p />").text("Version " + twigs.version.toFixed(1)).appendTo(el);
+ $("<p />").css("font-size", "12px").text("By Richard Knight 2024").appendTo(el);
+
+ twirl.prompt.show(el, function(){
+ for (let i of intervals) clearInterval(i);
+ });
+ };
+
+ this.showSettings = function() {
+ var settings = [
+ {
+ name: "Undo levels",
+ description: "Number of undo levels stored. Large numbers may affect memory usage",
+ min: 0, max: 32, step: 1, dfault: 2, storageKey: "maxundo",
+ onChange: function(val) {
+ app.setControlChannel("twgs_maxundo", val);
+ }
+ },
+ {
+ name: "Resynthesis type",
+ description: "Type of resynthesis to be used",
+ options: ["Overlap-add", "Additive"],
+ dfault: 0,
+ storageKey: "resynthType"
+ },
+ {
+ name: "Colour type",
+ description: "Type of colouration to use in graphing",
+ options: ["Monochrome", "Colour"],
+ dfault: 0,
+ storageKey: "colourType",
+ onChange: function() {
+ twigs.redraw();
+ }
+ },
+ {
+ name: "Graph type",
+ description: "Approach to graphing partials used",
+ options: ["Joined line", "Separate lines"],
+ dfault: 0,
+ storageKey: "graphType",
+ onChange: function() {
+ twigs.redraw();
+ }
+ },
+ {
+ name: "Basic lines",
+ description: "Show thin, basic lines in graphing",
+ bool: true,
+ dfault: 0,
+ storageKey: "basicLines",
+ onChange: function() {
+ twigs.redraw();
+ }
+ },
+ {
+ name: "Frequency gridlines",
+ description: "Draw the vertical frequency grid",
+ bool: true,
+ dfault: 1,
+ storageKey: "drawFrequencyGrid",
+ onChange: function() {
+ twigs.redraw();
+ }
+ },
+ {
+ name: "Time gridlines",
+ description: "Draw the horizontal time grid",
+ bool: true,
+ dfault: 1,
+ storageKey: "drawTimeGrid",
+ onChange: function() {
+ twigs.redraw();
+ }
+ },
+ {
+ name: "Zoom to start on load",
+ description: "Zoom to the start portion of time and frequency when loading a new file",
+ bool: true,
+ dfault: 1,
+ storageKey: "zoomOnLoad"
+ }
+ ];
+ twirl.showSettings(twigs, settings);
+ };
+
+ var icon_groups = {};
+
+ ui.setSelectionMode = function(mode, iconObj) {
+ for (let s of icon_groups.selection) s.setActive(false);
+ iconObj.setActive(true);
+ elEditor.css("cursor", iconObj.definition.cursor);
+ twigs.setSelectionMode(mode);
+ }
+
+ function setOptionsArea(el) {
+ var o = $("#twigs_options").empty();
+ if (el) o.append(el);
+ }
+
+ ui.icons = {};
+
+ var icons = [
+ [{
+ label: "Select single bin",
+ icon: "pointer",
+ shortcut: {name: "Q", key: "q"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "default",
+ bgColor: 1,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.singleBin, obj);
+ }
+ },
+ {
+ label: "Select area",
+ icon: "areaSelect",
+ shortcut: {name: "W", key: "w"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "crosshair",
+ bgColor: 1,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.dragArea, obj);
+ }
+ }],
+ [{
+ label: "Select bins",
+ icon: "verticalArrows",
+ shortcut: {name: "A", key: "a"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "vertical-text",
+ bgColor: 1,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.dragBins, obj);
+ }
+ },
+ {
+ label: "Free select",
+ icon: "lasso",
+ shortcut: {name: "S", key: "s"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "crosshair",
+ bgColor: 1,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.lasso, obj);
+ }
+ }],
+ [{
+ label: "Bin append select",
+ icon: "waves",
+ shortcut: {name: "Z", key: "z"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "copy",
+ bgColor: 1,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.binAppend, obj);
+ }
+ },
+ {
+ label: "Play selection",
+ icon: "ear",
+ shortcut: {name: "X", key: "x"},
+ menuAdd: "action",
+ bgColor: 2,
+ click: function(obj) {
+ twigs.play(true);
+ }
+ }],
+ [{
+ label: "Move",
+ icon: "move",
+ shortcut: {name: "E", key: "e"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "grab",
+ bgColor: 3,
+ clickOnInactive: true,
+ click: function(obj) {
+ ui.setSelectionMode(twigs.SELECTIONMODE.move, obj);
+ },
+ optionsArea: function() {
+ if (!twigs.storage.movementType) twigs.storage.movementType = 2;
+ if (!twigs.storage.interpolateVoid) twigs.storage.interpolateVoid = 1;
+ if (!twigs.storage.interpolateRatio) twigs.storage.interpolateRatio = 0;
+ var el = $("<div />");
+ var typeOptions = new twirl.transform.Transform({host: twigs, element: el, definition: {
+ name: "Movement",
+ instr: "twgs_movement",
+ parameters: [
+ {name: "Movement type", description: "Type of movement to apply", channel: "twgs_movementtype", absolutechannel: true, options: ["Copy", "Leave void", "Retain amp/freq in void", "Retain amp in void", "Retain freq in void"], automatable: false, dfault: twigs.storage.movementType, onChange: function(val){
+ twigs.storage.movementType = val;
+ twigs.saveStorage();
+ }},
+ {name: "Interpolate void", description: "Interpolate values in the void created by the movement", channel: "twgs_interpolatevoid", absolutechannel: true, min: 0, max: 1, step: 1, automatable: false, dfault: twigs.storage.interpolateVoid, onChange: function(val){
+ twigs.storage.interpolateVoid = val;
+ twigs.saveStorage();
+ }, conditions: [{channel: "twgs_movementtype", absolutechannel: true, operator: "ge", value: 2}]},
+ {name: "Interpolation ratio", description: "Ratio of interpolation to integrate with target position", channel: "twgs_interpolateratio", absolutechannel: true, min: 0, max: 0.45, automatable: false, dfault: twigs.storage.interpolateRatio, onChange: function(val){
+ twigs.storage.interpolateRatio = val;
+ twigs.saveStorage();
+ }}
+ ]
+ }});
+ return el;
+ }
+ },
+ {
+ label: "Transpose",
+ icon: "arrowsUpDown",
+ shortcut: {name: "R", key: "r"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "row-resize",
+ bgColor: 3,
+ clickOnInactive: true,
+ click: function(obj) {
+ setSelectionMode(twigs.SELECTIONMODE.transpose, obj);
+ }
+ }],
+ [{
+ label: "Amplify",
+ icon: "fileVolume",
+ shortcut: {name: "D", key: "d"},
+ menuAdd: "action",
+ bgColor: 3,
+ click: function(obj) {
+ if (!twigs.hasSelection) return;
+ var el = $("<div />");
+ $("<h4 />").text("Amplitude scale").appendTo(el);
+ var amp = $("<input />").attr("type", "range").attr("max", 10).attr("min", 0).attr("step", 0.000001).val(1).appendTo(el);
+ twirl.prompt.show(el, function(){
+ twigs.selectionOperation.amplify(amp.val());
+ });
+ }
+ },
+ {
+ label: "Draw",
+ icon: "pencil",
+ shortcut: {name: "F", key: "f"},
+ menuAdd: "action",
+ group: "selection",
+ cursor: "row-resize",
+ bgColor: 3,
+ clickOnInactive: true,
+ click: function(obj) {
+ setSelectionMode(twigs.SELECTIONMODE.draw, obj);
+ }
+ }],
+ [{
+ label: "Play",
+ icon: "play",
+ shortcut: {name: "Space", key: "space"},
+ menuAdd: "action",
+ bgColor: 2,
+ click: function(obj) {
+ twigs.play();
+ }
+ },
+ {
+ label: "Stop",
+ icon: "stop",
+ bgColor: 2,
+ click: function(obj) {
+ twigs.stop();
+ }
+ }],
+ [{
+ label: "Zoom in amplitude",
+ icon: "brightnessIncrease",
+ shortcut: {name: "C", key: "c"},
+ menuAdd: "action",
+ bgColor: 1,
+ click: function(obj) {
+ twigs.increaseAmpScaling();
+ }
+ },
+ {
+ label: "Zoom out amplitude",
+ icon: "brightnessDecrease",
+ shortcut: {name: "V", key: "v"},
+ menuAdd: "action",
+ bgColor: 1,
+ click: function(obj) {
+ twigs.decreaseAmpScaling();
+ }
+ }]
+ ];
+
+ function addIcon(def) {
+ let ops = {};
+ Object.assign(ops, def);
+ if (ops.shortcut) {
+ ops.label += " (" + ops.shortcut.name + ")";
+ }
+ ops.click = function(obj) {
+ def.click(obj);
+ if (def.optionsArea) {
+ setOptionsArea(def.optionsArea())
+ } else {
+ setOptionsArea();
+ }
+ }
+ let icon = twirl.createIcon(ops);
+ if (ops.menuAdd) {
+ let menuData = {
+ name: ops.label,
+ click: function() {
+ icon.el.click();
+ }
+ };
+ if (ops.shortcut) {
+ menuData.shortcut = ops.shortcut;
+ }
+ addActionMenu(ops.menuAdd, menuData);
+ }
+ return icon;
+ }
+
+ function create() {
+ for (let z of zoomIcons) {
+ var icon = addIcon(z);
+ $(z.target).append(icon.el);
+ }
+
+ var tb = $("<tbody />").appendTo($("<table />").appendTo(el));
+ var icol = 0;
+ var first;
+ for (let row of icons) {
+ var tr = $("<tr />").appendTo(tb);
+ for (let col of row) {
+ let icon = addIcon(col);
+ if (!first) first = icon;
+ if (col.group) {
+ if (!icon_groups[col.group]) icon_groups[col.group] = [];
+ icon_groups[col.group].push(icon);
+ }
+ var td = $("<td />").append(icon.el).appendTo(tr);
+ if (col.bgColor) {
+ td.css("background-color", "var(--bgColor" + col.bgColor + ")");
+ }
+ icons[col.key] = icon;
+ }
+ }
+ first.click();
+ }
+
+ create();
+ var topMenu = new twirl.TopMenu(twigs, twigsTopMenuData, $("#twigs_menubar"));
+};
\ No newline at end of file diff --git a/site/app/twine/_hOLD/clip.js b/site/app/twine/_hOLD/clip.js new file mode 100644 index 0000000..1c4cc48 --- /dev/null +++ b/site/app/twine/_hOLD/clip.js @@ -0,0 +1,499 @@ +var Clip = function(twine, data, parent) {
+ var clip = this;
+ var loaded = false;
+ var waveformClip;
+ var waveformEdit;
+ var datatable;
+ this.channel = null;
+ var minWidth = 10;
+
+ if (!data) {
+ var id = twine.getNewID();
+ var data = {
+ name: "Clip " + id,
+ channel: -1,
+ id: id,
+ clipindex: null,
+ playLength: 1,
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16),
+ position: 0,
+ // debugs:
+ duration: 1,
+ warp: false,
+ loop: false
+ };
+ } else {
+ loaded = true;
+ }
+ this.data = data;
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ clip.element.css("background-color", data.colour);
+ }
+ });
+
+ this.exportData = function() {
+ return data;
+ };
+
+ this.destroy = function(onComplete) {
+ var cbid = app.createCallback(function(ndata){
+ clip.element.remove();
+ clip.channel.removeClip(clip);
+ if (onComplete) {
+ onComplete(ndata);
+ }
+ });
+ app.insertScore("twine_removeclip", [0, 1, cbid, clip.data.clipindex]);
+ };
+
+ var dataMode = {
+ fnL: 0, fnR: 1, divisionsPerBeat: 2, duration: 3, beatsLength: 4, utilisedLength: 5,
+ warpMode: 6, pitch: 7, amp: 8, fftSize: 9, txtWinSize: 10, txtRandom: 11, txtOverlap: 12,
+ loop: 13, warp: 14, txtWinType: 15, // warp points are 16 + in table
+ position: -1, name: -2, channel: -3, clipindex: -4, playLength: -5
+ };
+
+
+ this.element = $("<div />").addClass("twine_clip").css({
+ "background-color": data.colour
+ }).click(function(e){
+ if (e.ctrlKey) {
+ twine.timeline.selectedClips.push(clip);
+ } else {
+ $(".twine_clip").css("outline", "none");
+ twine.timeline.selectedClips = [clip];
+ }
+console.log("ch", clip.data);
+ clip.element.css("outline", "1px dashed white");
+
+ var cui = twine.ui.clip;
+ cui.name.setValue(data.name);
+ cui.colour.setValue(data.colour);
+ cui.amp.setValue(data.amp);
+ cui.warp.setValue(data.warp);
+ cui.loop.setValue(data.loop);
+ cui.readType.setValue(data.warpMode);
+ cui.pitch.setValue(Math.round((Math.log(data.pitch) / Math.log(2)) * 12));
+ cui.fftSize.setValue(data.fftSize);
+ cui.winSize.setValue(data.txtWinSize);
+ cui.winRandom.setValue(data.txtRandom);
+ cui.winOverlap.setValue(data.txtOverlap);
+ cui.winType.setValue(data.txtWinType);
+
+ showEditWaveform($("#twine_clipdetailsright"));
+ twine.ui.showPane(twine.ui.pane.CLIP);
+ });
+ var elWaveClip = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px"}).appendTo(clip.element);
+ var elWaveText = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "font-size": "var(--fontSizeSmall)", color: "var(--fgColor1)"}).text(data.name).appendTo(clip.element);
+
+ var elResizeLeft = $("<div />").addClass("twine_clip_edge_left").appendTo(clip.element);
+ var elResizeRight = $("<div />").addClass("twine_clip_edge_right").appendTo(clip.element);
+ var elMove = $("<div />").addClass("twine_clip_centre").appendTo(clip.element);
+ var elWaveEdit = $("<div />").css({width: "100%", height: "100%", top: "0px", left: "0px"});
+
+ async function getDataFromTable(key) {
+ async function setFromKey(key) {
+ if (dataMode[key] < 0) return;
+ var value = await app.getCsound().tableGet(datatable, dataMode[key])
+ data[key] = value;
+ }
+
+ for (var k in dataMode) {
+ setFromKey(k);
+ }
+ }
+
+ function setClipAudioUnique(onComplete) {
+ var cbid = app.createCallback(async function(ndata){
+ await getDataFromTable();
+ if (onComplete) onComplete();
+ });
+ app.insertScore("twine_setclipaudiounique", [0, 1, cbid]);
+ }
+
+ function reloadAfterEdit(tables) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ datatable = ndata.datatable;
+ await getDataFromTable();
+ clip.redraw();
+ twine.setVisible(true);
+ twigs.setVisible(false);
+ twist.setVisible(false);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid, data.clipindex];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_clipreplacetables", call);
+ }
+
+ this.editInTwist = function(asUnique) {
+ if (!window.twist) return twirl.prompt.show("twist is unavailable in this session");
+ function edit() {
+ twist.boot(twine);
+ twist.bootAudio(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twist.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twist.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+ if (asUnique) {
+ setClipAudioUnique(edit);
+ } else {
+ edit();
+ }
+
+ };
+
+ this.editInTwigs = function(asUnique) {
+ if (!window.twigs) return twirl.prompt.show("twigs is unavailable in this session");
+ function edit() {
+ twigs.boot(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twigs.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twigs.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+ if (asUnique) {
+ setClipAudioUnique(edit);
+ } else {
+ edit();
+ }
+ };
+
+ this.setData = function(modeString, v, onComplete) {
+ data[modeString] = v;
+ if (dataMode[modeString] < 0) {
+ if (modeString == "name") {
+ elWaveText.text(data.name);
+ }
+ return;
+ }
+
+ function doSetData() {
+ if (!twirl.debug) app.getCsound().tableSet(datatable, dataMode[modeString], v);
+ }
+
+ doSetData();
+ if (onComplete) onComplete();
+ };
+
+ this.getPlaybackArgs = function(cbid, time) {
+ return [(time) ? time: 0, data.playLength, cbid, data.clipindex, data.playLength, clip.channel.getCsChannelName()];
+ };
+
+ this.play = function(onCallback) {
+ var cbid = app.createCallback(function(ndata) {
+ if (onCallback) onCallback(ndata);
+ }, true);
+ app.insertScore("ecp_playback_tst", clip.getPlaybackArgs(cbid));
+ }
+
+ async function getSourceTableData() {
+ var wavedata = [];
+ var tbL = await app.getTable(data.fnL);
+ wavedata.push(tbL);
+ if (data.hasOwnProperty("fnR") && data.fnR > 0) {
+ var tbR = await app.getTable(data.fnR);
+ wavedata.push(tbR);
+ }
+ return wavedata;
+ }
+
+ async function setClipWaveform(noRedraw) {
+ if (!waveformClip) {
+ waveformClip = new Waveform({
+ target: elWaveClip,
+ allowSelect: false,
+ showGrid: false,
+ bgColor: "rgb(255, 255, 255, 0)",
+ fgColor: "#000000"
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformClip.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ if (!noRedraw) waveformClip.redraw();
+ }
+ }
+
+ async function showEditWaveform(target) {
+ target.empty().append(elWaveEdit);
+ if (!waveformEdit) {
+ waveformEdit = new Waveform({
+ target: elWaveEdit,
+ allowSelect: true,
+ showGrid: true,
+ latencyCorrection: twirl.latencyCorrection // , markers:
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformEdit.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ waveformEdit.redraw();
+ }
+ }
+
+ this.setWarp = function(v) {
+ clip.setData("warp", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setLoop = function(v) {
+ clip.setData("loop", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setPitch = function(semitones) {
+ var pitchRatio = Math.pow(2, (semitones / 12));
+ clip.setData("pitch", pitchRatio);
+ if (data.warpMode == 0 && data.loop == 0 && data.warp == 0) {
+ data.playLength = data.duration / pitchRatio;
+ clip.setSize();
+ }
+ };
+
+ this.setWarpMode = function(v) {
+ var prevMode = data.warpMode;
+ clip.setData("warpMode", v);
+ if (prevMode == 0 && data.warpMode != 0 && !data.loop && !data.warp) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setSize = function(noWaveRedraw) {
+ var width = data.playLength * twine.timeline.pixelsPerBeat;
+ clip.element.css("width", width + "px");
+ setClipWaveform(noWaveRedraw);
+ }
+
+ this.redraw = function(noWaveRedraw) {
+ if (!loaded) return;
+ var b = twine.timeline.beatRegion;
+ clip.setSize(noWaveRedraw);
+ if ((data.position + data.playLength) < b[0] || data.position > b[1]) {
+ return clip.element.hide();
+ }
+
+ var css = {
+ height: clip.channel.height + "px",
+ left: (data.position - b[0]) * twine.timeline.pixelsPerBeat + "px"
+ };
+ if (data.position < b[0]) {
+ css.left = "0px";
+ css.width = (data.playLength - (b[0] - data.position)) * twine.timeline.pixelsPerBeat + "px";
+ }
+
+ clip.element.show().css(css);
+ };
+
+ this.clone = function() {
+ var newData = Object.assign({}, data);
+ newData.id = twine.getNewID();
+ var c = new Clip(twine, newData, clip);
+ clip.channel.addClip(c);
+ app.insertScore("twine_cloneclip", [0, 1, app.createCallback(function(ndata) {
+ datatable = ndata.datatable;
+ c.loadFromDataTable(ndata.datatable, ndata.clipindex);
+ }), clip.data.clipindex]);
+ };
+
+
+ async function loadData(ndata, name, colour, defaultLength) {
+ twirl.loading.show("Loading");
+ if (ndata.status == -1) {
+ return twirl.errorHandler("File not valid");
+ } else if (ndata.status == -2) {
+ return twirl.errorHandler("File too large");
+ }
+ datatable = ndata.data.datatable;
+ await getDataFromTable();
+ data.clipindex = ndata.data.clipindex;
+ if (name) {
+ data.name = name;
+ }
+ if (defaultLength) {
+ data.playLength = data.duration;
+ }
+ elWaveText.text(data.name);
+ if (!colour) colour = twine.randomColour();
+ data.colour = colour;
+ loaded = true;
+ clip.redraw();
+ };
+
+ this.loadFromDataTable = async function(newDatatable, clipindex) {
+ datatable = newDatatable;
+ await getDataFromTable();
+ data.clipindex = clipindex;
+ loaded = true;
+ clip.redraw();
+ };
+
+ this.loadFromFtables = function(name, tables, colour) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, name, colour);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_loadftables", call);
+ };
+
+ this.loadFromPath = function(path, colour) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, path, colour, true);
+ twirl.loading.hide();
+ });
+ app.insertScore("twine_loadpath", [0, 1, cbid, path]);
+ };
+
+ function getMaxClipWidth() {
+ var maxWidth = 9999;
+ if (!data.warp && !data.loop) {
+ maxWidth = data.duration * twine.timeline.pixelsPerBeat;
+ }
+ return maxWidth;
+ }
+
+ clip.movement = {
+ pos1: 0, pos2: 0, pos3: 0, pos4: 0, offset: 0, startX: 0, startY: 0, clipWidth: 0,
+ clipLeft: 0, clipTop: 0, lastLeft: 0, isCopying: false,
+ mouseDown: function(e, dragType) {
+ e.preventDefault();
+ twine.timeline.selectedClips.forEach(function(c){
+ c.movement.mouseDownInner(e, dragType);
+ });
+ },
+ mouseDownInner: function(e, dragType) {
+ e.preventDefault();
+ this.isCopying = false;
+ this.offset = clip.element.offset().left
+ this.clipWidth = parseFloat(clip.element.css("width"));
+ this.clipTop = parseFloat(clip.element.css("top"));
+ this.clipLeft = parseFloat(clip.element.css("left"));
+ this.startX = e.clientX - e.target.getBoundingClientRect().left;
+ this.startY = e.clientY - e.target.getBoundingClientRect().top;
+ this.pos3 = e.clientX;
+ this.pos4 = e.drag;
+ this.lastLeft = (this.pos3 - this.startX - clip.channel.offset.left);
+ $("html").on("mousemove", function(e){
+ clip.movement.doDrag(e, dragType);
+ }).on("mouseup", this.endDrag);
+ $("#container").css("cursor", "e-resize");
+ },
+ endDrag: function(e) {
+ e.preventDefault();
+ this.isCopying = false;
+ $("html").off("mouseup", this.endDrag).off("mousemove"); //, this.doDrag);
+ $("#container").css("cursor", "pointer");
+ },
+ doDrag: function(e, dragType) {
+ e.preventDefault();
+ twine.timeline.selectedClips.forEach(function(c){
+ c.movement.doDragInner(e, dragType);
+ });
+ },
+ doDragInner: function (e, dragType) {
+ e.preventDefault();
+ this.pos1 = this.pos3 - e.clientX;
+ this.pos2 = this.pos4 - e.clientY;
+ this.pos3 = e.clientX;
+ this.pos4 = e.clientY;
+
+ if (dragType == "right") {
+ var maxWidth = getMaxClipWidth();
+ var newWidth = (this.pos3 - this.startX - clip.channel.offset.left - this.clipLeft);
+ newWidth = twine.timeline.roundToGrid(newWidth);
+ if (newWidth > maxWidth) newWidth = maxWidth;
+ if (newWidth < minWidth) newWidth = minWidth;
+ data.playLength = newWidth / twine.timeline.pixelsPerBeat;
+ clip.element.css("width", newWidth + "px");
+
+ } else if (dragType == "left") {
+ var maxWidth = getMaxClipWidth();
+ var left = (this.pos3 - this.startX - clip.channel.offset.left);
+ left = twine.timeline.roundToGrid(left);
+ if (left < 0) left = 0;
+ var newWidth = (clipWidth - left) + this.clipLeft;
+ var cWidth, cLeft;
+ if (newWidth < minWidth) {
+ cWidth = minWidth, this.clipLeft + minWidth; //(minWidth - left) + clipLeft;
+ } else if (newWidth > maxWidth) {
+ cWidth = maxWidth, cLeft = this.lastLeft;
+ } else {
+ lastLeft = left;
+ cWidth = newWidth, cLeft = left;
+ }
+ clip.element.css({width: cWidth + "px", left: cLeft + "px"});
+
+ data.playLength = newWidth / twine.timeline.pixelsPerBeat;
+ data.position = Math.min(0, (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0]);
+
+ } else {
+ if (e.ctrlKey && !this.isCopying) {
+ this.isCopying = true;
+ clip.clone();
+ }
+
+ //var left = (this.pos3 - this.startX - clip.channel.offset.left);
+ var left = (this.pos3 - this.clipLeft - clip.channel.offset.left);
+ left = twine.timeline.roundToGrid(left);
+
+ //var top = (this.pos4 - this.startY - clip.channel.offset.top);
+ var top = (this.pos4 - this.clipTop - clip.channel.offset.top);
+ if (top > clip.channel.height) {
+ if (clip.channel.index + 1 < twine.timeline.channels.length) {
+ clip.channel.removeClip(clip);
+ twine.timeline.channels[clip.channel.index + 1].addClip(clip);
+ }
+ } else if (top < 0) {
+ if (clip.channel.index -1 >= 0) {
+ clip.channel.removeClip(clip);
+ twine.timeline.channels[clip.channel.index - 1].addClip(clip);
+ }
+ }
+ if (left < 0) left = 0;
+ //if (left > clip.channel.width - clipWidth) left = clip.channel.width - clipWidth;
+ if (left > clip.channel.width) left = clip.channel.width;
+ data.position = (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0];
+ clip.element.css("left", left + "px");
+ }
+ } // end doDragInner
+ };
+
+ elMove.mousedown(clip.movement.mouseDown);
+ elResizeRight.mousedown(function(e){
+ clip.movement.mouseDown(e, "right");
+ });
+ elResizeLeft.mousedown(function(e){
+ clip.movement.mouseDown(e, "left");
+ });
+
+};
\ No newline at end of file diff --git a/site/app/twine/_hOLD/index.html b/site/app/twine/_hOLD/index.html new file mode 100644 index 0000000..5e9e2b4 --- /dev/null +++ b/site/app/twine/_hOLD/index.html @@ -0,0 +1,863 @@ +<html>
+<head>
+<style type="text/css">
+
+body {
+ font-family: Arial, sans-serif;
+ font-size: 11pt;
+}
+
+#header {
+ position: absolute;
+ top: 0px;
+ height: 30px;
+ left: 0px;
+ width: 100%;
+ background-color: #545454;
+}
+
+#headertable {
+ height: 30px;
+}
+
+#clipdetails {
+ display: none;
+}
+
+
+#start {
+ z-index: 200;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #343434;
+}
+
+#start_centre {
+ z-index: 201;
+ position: relative;
+ height: 200px;
+}
+
+#start_invoke {
+ z-index: 202;
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 72pt;
+ cursor: pointer;
+}
+
+#main {
+ position: absolute;
+ top: 30px;
+ height: 100%;
+ left: 0px;
+ width: 100%;
+}
+
+#timeline {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 70%
+}
+
+.timelinetext {
+ font-size: 8pt;
+ opacity: 0.9;
+ position: absolute;
+ color: #121212;
+ top: 2px;
+}
+
+.timelinemarker {
+ width: 1px;
+ position: absolute;
+ background-color: #bdbdbd;
+ opacity: 0.9;
+ height: 100%;
+ top: 0px;
+ z-index: 50;
+}
+
+.smbut {
+ font-size: 8pt;
+ background-color: #b5b01d;
+ border: 1px solid black;
+}
+
+
+
+#details {
+ position: absolute;
+ left: 0px;
+ top: 70%;
+ width: 100%;
+ height: 30%;
+ background-color: #dcdcdc;
+}
+
+#clipdetailsleft {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 30%;
+ height: 100%;
+ background-color: #acacac;
+}
+
+#clipdetailsright {
+ position: absolute;
+ left: 30%;
+ top: 0px;
+ width: 70%;
+ height: 100%;
+ background-color: #cacaca;
+}
+
+.channel {
+ height: 30px;
+ width: 100%;
+ border-bottom: 1px solid #aaaaaa;
+ left: 0px;
+}
+
+.channeldetails {
+ position: absolute;
+ height: 30px;
+ left: 0px;
+ width: 10%;
+}
+
+.channelclips {
+ position: absolute;
+ height: 30px;
+ left: 10%;
+ width: 90%;
+ background-color: #cdcdcd;
+}
+
+.clip {
+ user-select: none;
+ position: absolute;
+ padding: 0px;
+ cursor: move;
+ z-index: 70;
+ width: 50px;
+ height: 30px;
+ color: #000000;
+ overflow: hidden;
+}
+</style>
+<script type="text/javascript" src="/code/jquery.js"></script>
+<script type="text/javascript" src="../base/base.js"></script>
+<script type="text/javascript" src="input-knobs.js"></script>
+<script type="text/javascript">
+
+window.app = new CSApplication(
+{
+ csdUrl: "timeline.csd",
+ files: ["test.mp3"],
+ csOptions: ["--omacro:ECP_NORECORDING=1"],
+ onPlay: function () {
+ $("#start").hide();
+ runTest();
+ }
+}
+);
+
+var clips = {};
+var channels = [];
+var maxID = 0;
+var chanHeight = 30;
+
+window.csseq = {};
+
+function getID() {
+ return maxID++;
+}
+
+
+var TimelineGrid = function(data) {
+ var self = this;
+
+ if (!data) {
+ var data = {
+ snapToGrid: true,
+ gridVisible: true,
+ timeSigMarker: 4,
+ resolution: null,
+ startBeat: 1,
+ endBeat: 16,
+ bpm: 120
+ };
+ }
+
+ this.getSaveData = function() {
+ return data;
+ };
+
+ function calcViewport() {
+ data.minLeft = (window.screen.width / 100) * 10;
+ var width = window.screen.width - data.minLeft;
+ var beats = data.endBeat - data.startBeat;
+ data.pixelsPerBeat = width / beats;
+ return {
+ minLeft: data.minLeft,
+ width: width,
+ beats: beats,
+ pixelsPerBeat: Math.round(data.pixelsPerBeat)
+ }
+ }
+
+ function draw() {
+ $(".timelinemarker").remove();
+ $(".timelinetext").remove();
+ if (!data.gridVisible) {
+ return;
+ }
+
+ var target = $("#timeline");
+ var geometry = calcViewport();
+
+ var beat = data.startBeat;
+
+ var width;
+ var fontWeight;
+ for (var x = geometry.minLeft; x < window.screen.width; x += geometry.pixelsPerBeat) {
+ if ((beat - 1) % data.timeSigMarker == 0) {
+ width = 2;
+ fontWeight = "bold";
+ } else {
+ width = 1;
+ fontWeight = "normal";
+ }
+ $("<div />").attr("class", "timelinemarker").appendTo(target).css("width", width).css("left", x);
+ $("<div />").attr("class", "timelinetext").appendTo(target).css("font-weight", fontWeight).css("left", x + 2).text(beat);
+ beat ++;
+ }
+ }
+
+ Object.defineProperty(this, "startBeat", {
+ get: function() { return data.startBeat; },
+ set: function(x) {
+ data.startBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "bpm", {
+ get: function() { return data.bpm; },
+ set: function(x) {
+ data.bpm = x;
+ app.insertScore("ecpweb_setbpm", [0, 1, data.bpm]);
+ }
+ });
+
+ Object.defineProperty(this, "endBeat", {
+ get: function() { return data.startBeat; },
+ set: function(x) {
+ data.startBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "minLeft", {
+ get: function() { return data.minLeft; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "pixelsPerBeat", {
+ get: function() { return data.pixelsPerBeat; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "snapToGrid", {
+ get: function() { return data.snapToGrid; },
+ set: function(x) {
+ data.snapToGrid = (x == 1);
+ }
+ });
+
+ Object.defineProperty(this, "gridVisible", {
+ get: function() { return data.gridVisible; },
+ set: function(x) {
+ data.gridVisible = (x == 1);
+ draw();
+ }
+ });
+
+
+
+ draw();
+};
+
+
+var Sequencer = function(data) {
+ var self = this;
+ var gridSnap = 0;
+ var timeScale = 1;
+
+ if (!data) {
+ var data = {
+ tempo: 120,
+ playing: false
+ };
+ }
+
+ this.userImportedFiles = [];
+
+ this.setTempo = function(v) {
+ insertScore("ecpweb_setglobal", [0, 1, 0, v]);
+ };
+
+ this.getSaveData = function() {
+ var sdata = {"sequencer": data, "channels": [], "clips": {}};
+ for (var x in channels) {
+ sdata.channels.push(channels[x].getSaveData());
+ }
+ for (var x in clips) {
+ sdata.clips[x] = clips[x].getSaveData();
+ }
+ return sdata;
+ };
+
+ this.loadSaveData = function(v) {
+ data = v.sequencer;
+ for (var x in v.channels) {
+ new Channel(v.channels[x]);
+ }
+ };
+
+ Object.defineProperty(this, "playing", {
+ get: function() { return data.playing; },
+ set: function(x) {
+ data.playing = x;
+ }
+ });
+};
+
+
+var Channel = function(data) {
+ var self = this;
+ channels.push(this);
+
+ if (!data) {
+ var index = channels.length;
+ var data = {
+ name: "Channel " + index,
+ index: index
+ };
+ } else {
+ var index = data.index;
+ }
+
+ var element = $("<div />").attr("id", "channel" + index).attr("class", "channel").appendTo("#timeline").append(
+ $("<div />").attr("id", "channeldetails" + index).attr("class", "channeldetails").text(data.name)
+ ).append(
+ $("<div />").attr("id", "channelclips" + index).attr("class", "channelclips")
+ );
+};
+
+var Clip = function(channel, data, parent) {
+ var self = this;
+ var loaded = false;
+ var hasTwin = (parent) ? true : false;
+ this.waveform = (parent) ? parent.waveform : null;
+
+ if (!data) {
+ var id = getID();
+ var data = {
+ name: "Clip " + id,
+ channel: channel,
+ id: id,
+ clipindex: null, // needed here?
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16),
+ position: 0,
+ };
+ }
+
+ clips[data.id] = this;
+ var element = $("<div />").attr("class", "clip").attr("id", "clip" + data.id).text(data.name).click(function() {
+ csseq.selectedClip = self;
+ $("#clipdetails").show();
+ $("#clip_name").val(data.name);
+ $("#clip_colour").val(data.colour);
+ $("#clipdetailsright").empty().append(self.waveform);
+
+ }).css("top", (channel * chanHeight) + "px").css("background-color", data.colour).mousedown(handle_mousedown)
+ .css("left", ((data.position * csseq.timeline.pixelsPerBeat)) + "px")
+ .appendTo($("#channelclips" + channel));
+ // resizable()
+
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ element.css("background-color", data.colour);
+ }
+ });
+
+
+// debug
+this.ddata = data;
+ var dataMode = {
+ divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+ // warp points are 16 + in table
+
+ position: -1,
+ name: -2,
+ soundPath: -3,
+ channel: -4
+ };
+
+ function getDataModeFromNum(v) {
+ for (var k in dataMode) {
+ if (dataMode[k] == v) {
+ return k;
+ }
+ }
+ }
+
+ for (let x in dataMode) {
+ Object.defineProperty(this, x, {
+ get: function() { return data[x] },
+ set: function(v) {
+ self.setData(x, v);
+ }
+ });
+ }
+
+ /*// v should become defunct
+ Object.defineProperty(this, "name", {
+ get: function() { return data.name; },
+ set: function(x) {
+ data.name = x;
+ element.text(data.name);
+
+ // self.setData("name", x);
+ }
+ });*/
+
+
+ /*
+ function getData() {
+ var cbid = app.createCallback(function(ndata) {
+ for (var x in ndata.data) {
+ data[x] = ndata.data[x];
+ }
+ });
+ app.insertScore("ecpweb_getdata", [0, 1, cbid, clipindex]);
+ }*/
+
+ this.setData = function(modeString, v) {
+ var cbid = app.createCallback(function(ndata) {
+ if (ndata.hasOwnProperty("clipindex")) {
+ data.clipindex = ndata.clipindex;
+ hasTwin = false;
+ }
+ data[modeString] = v;
+ if (modeString == "name") {
+ element.text(data.name);
+ }
+ });
+ app.insertScore("ecpweb_setdata",
+ [0, 1, cbid, data.id, dataMode[modeString], v, ((hasTwin) ? 1 : 0)]
+ ); // having ecp_cloneclip in if needed
+ }
+
+ this.play = function() {
+ var cbid = app.createCallback(function(ndata) {
+ console.log(ndata);
+ });
+ app.insertScore("ecpseq_playclip", [0, 1, cbid, data.id]);
+ }
+
+ this.loadTest = function() {
+ self.loadFromPath("test.mp3");
+ };
+
+ async function makeWaveform(tablenum) {
+ var width = 300;
+ var height = 150;
+ var tabledata = await app.getCsound().tableCopyOut(tablenum);
+ self.waveform = $("<canvas />", {"class": "waveform"}).width(width).height(height);
+ var ctx = self.waveform[0].getContext("2d");
+ var widthstep = tabledata.length / width;
+ var val;
+ ctx.fillStyle = "#88ff88";
+ //ctx.beginPath();
+ ctx.moveTo(0, height * 0.5);
+ for (var x = 0; x < tabledata.length; x++) {
+ val = (tabledata[x] + 1) * 0.5;
+ ctx.lineTo(x * widthstep, val * height);
+ }
+ //ctx.closePath();
+ ctx.stroke();
+ app.insertScore("ecpweb_tabdestroy", [0, 1, tablenum]);
+ }
+
+ function setSize() {
+ var beattime = 60 / csseq.timeline.bpm;
+ var width = (data.duration / beattime) * csseq.timeline.pixelsPerBeat;
+ element.css("width", width + "px");
+ }
+
+ this.loadFromPath = function(path, userImported) {
+ var cbid = app.createCallback(function(ndata) {
+ for (var x in ndata.data) {
+ var key = getDataModeFromNum(x);
+ data[key] = ndata.data[x];
+ if (key == "name") {
+ element.text(data.name);
+ }
+ }
+ data.soundPath = path;
+ makeWaveform(ndata.waveform).then(() => {
+ if (userImported) {
+ csseq.seq.userImportedFiles.push(path);
+ }
+ loaded = true;
+ setSize();
+ });
+
+ });
+ app.insertScore("ecpweb_loadsound", [0, 1, cbid, path, data.channel, data.position]);
+ };
+
+ this.clone = function() {
+ var newdata = Object.assign({}, data);
+ newdata.id = getID();
+ return new Clip(data.channel, newdata, self);
+ };
+
+ this.randomiseWarpPoints = function(mode) { // mode is -1, 0 or 1 I think..
+ if (!mode) mode = 0;
+ var cbid = app.createCallback(function(ndata) {
+ notify("OK");
+ });
+ app.insertScore("ecpweb_randomisewarppoints", [0, 1, cbid, mode]);
+ };
+
+
+ function handle_mousedown(e){
+ var originalPosition = data.position;
+ window.my_dragging = {};
+ my_dragging.pageX0 = e.pageX;
+ my_dragging.pageY0 = e.pageY;
+ my_dragging.elem = this;
+ my_dragging.offset0 = $(this).offset();
+ var isCopying = e.ctrlKey;
+
+ if (isCopying) { // && loaded
+ self.clone();
+ }
+
+ function handle_dragging(e){
+ var left = my_dragging.offset0.left + (e.pageX - my_dragging.pageX0);
+
+ var minLeft = (window.screen.width / 100) * 10;
+
+ //round
+ // left = Math.ceil(left / pixelsPerBeat) * pixelsPerBeat;
+
+ if (csseq.timeline.snapToGrid) {
+ left = (Math.ceil((left - minLeft) / csseq.timeline.pixelsPerBeat) * csseq.timeline.pixelsPerBeat) + minLeft;
+ }
+
+
+ if (left < minLeft) {
+ left = minLeft
+ }
+ data.position = csseq.timeline.startBeat + ((left - minLeft) / csseq.timeline.pixelsPerBeat);
+
+ var top = my_dragging.offset0.top + (e.pageY - my_dragging.pageY0);
+ top = Math.ceil(top / chanHeight) * chanHeight;
+ var maxTop = chanHeight * channels.length;
+ if (top > maxTop) {
+ top = maxTop;
+ } else if (top < 30) {
+ top = 30;
+ }
+
+
+ $(my_dragging.elem)
+ .offset({top: top, left: left});
+ }
+
+ function handle_mouseup(e){
+ $("body")
+ .off("mousemove", handle_dragging)
+ .off("mouseup", handle_mouseup);
+ if (data.position != originalPosition) {
+ self.setData("position", data.position);
+ }
+ }
+
+ $("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
+ }
+
+ /*
+ this.setLength = function(v) {
+ setData("length", v);
+ }; // now made generic above.
+ */
+};
+
+function runTest() {
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+}
+
+var ClipDetailPane = function() {
+ var self = this;
+};
+
+
+
+$(function() {
+ csseq.timeline = new TimelineGrid();
+ csseq.seq = new Sequencer();
+
+
+ $(".smbut").attr("value", 0).click(function(){
+ var val;
+ var col;
+ if ($(this).attr("value") == 0) {
+ val = 1;
+ col = "#f2e30c";
+ } else {
+ val = 0;
+ col = "#b5b01d";
+ }
+ $(this).attr("value", val).css("background-color", col);
+ });
+
+ $("#head_snap").click(function() {
+ csseq.timeline.snapToGrid = $(this).attr("value");
+ });
+
+ $("#head_showgrid").click(function() {
+ csseq.timeline.gridVisible = $(this).attr("value");
+ });
+
+ $("#head_play").click(function() {
+ var bt = $(this);
+ if (csseq.seq.playing) {
+ app.insertScore("ecpseq_stop");
+ } else {
+ var cbid = app.createCallback(function(data) {
+ var text, val, col;
+ if (data.state == "playing") {
+ csseq.seq.playing = true;
+ text = "Stop";
+ val = 1;
+ col = "#f2e30c";
+ } else if (data.state == "stopped") {
+ csseq.seq.playing = false;
+ text = "Play";
+ val = 0;
+ col = "#b5b01d";
+ app.removeCallback(data.cbid);
+ }
+ bt.text(text).attr("value", val).css("background-color", col);
+ }, true);
+ app.insertScore("ecpseq_play", [0, 36000, cbid, csseq.timeline.startBeat]);
+ }
+ });
+
+
+ $("#clip_colour").change(function(){
+ csseq.selectedClip.colour = $(this).val();
+ });
+
+
+ var clip_pitchLocked = false;
+ $("#clip_pitch").change(function(){
+ if (!clip_pitchLocked) {
+ var val = $(this).val();
+ csseq.selectedClip.pitch = Math.pow(2, (val / 12));
+ $("#clip_pitchtext").val(val);
+ }
+ });
+
+ /*
+
+ var onChangeID = {
+ clip_warp: "warp",
+ clip_loop: "loop",
+ clip_amp: "amp",
+ clip_readtype: "warpMode",
+ };
+
+ for (let el in onChangeID) {
+ let obj = $("#" + el);
+ let trg = onChangeID[el];
+ var func;
+ if (typeof(trg) == "string") {
+ func = () => {
+ csseq.selectedClip[trg] = $(this).val();
+ };
+ } else {
+ func = trg;
+ }
+ obj.change(func);
+ }
+
+ */
+
+
+ $("#clip_pitchtext").change(function(){
+ clip_pitchLocked = true;
+ $("#clip_pitch").val($(this).val());
+ clip_pitchLocked = false;
+ });
+
+ $("#clip_name").change(function(){
+ csseq.selectedClip.name = $(this).val(); // setdata?
+ });
+
+ $("#clip_amp").change(function(){
+ csseq.selectedClip.amp = $(this).val();
+ });
+
+ $("#clip_warp").click(function() {
+ csseq.selectedClip.warp = $(this).val();
+ });
+
+ $("#clip_loop").click(function() {
+ csseq.selectedClip.loop = $(this).val();
+ });
+
+ $("#clip_readtype").change(function() {
+ csseq.selectedClip.warpMode = $(this).val();
+ });
+
+ $("#start_invoke").click(function() {
+ app.play();
+ });
+
+ async function handleFileDrop(e) {
+ e.preventDefault();
+ for (const item of e.originalEvent.dataTransfer.files) {
+ //item.size;
+ //item.type "audio/mpeg";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ await app.getCsound().fs.writeFile(item.name, buffer);
+ var x = new Clip(1); // determine channel
+ x.loadFromPath(item.name, true);
+ }
+ }
+
+ $("#timeline").on("dragover", function(e) {
+ e.preventDefault();
+ //e.stopPropagation();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ //styling / clip view
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ //e.stopPropagation();
+ // remove styling / clip view
+ }).on("drop", function(e) {
+ handleFileDrop(e);
+ });
+
+});
+/*
+divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+*/
+</script>
+</head>
+<body>
+<div id="start">
+ <div id="start_centre">
+ <p id="start_invoke">Press to begin</p>
+ </div>
+</div>
+<div id="header">
+ <table id="headertable"><tbody><tr>
+ <td><button id="head_play" class="smbut">Play</button></td>
+ <td><button id="head_snap" class="smbut">Snap</button></td>
+ <td><button id="head_showgrid" class="smbut">Grid</button></td>
+ </tr></tbody></table>
+</div>
+<div id="main">
+ <div id="timeline"></div>
+ <div id="details">
+ <div id="clipdetails">
+ <div id="clipdetailsleft">
+ <table><tbody>
+ <tr>
+ <td><input type="color" id="clip_colour"></td>
+ <td><input type="text" id="clip_name"></td>
+ </tr>
+ <tr>
+ <td>Read type</td>
+ <td><select id="clip_readtype">
+ <option value="0">Repitch</option>
+ <option value="1">Grain</option>
+ <option value="2">FFTab</option>
+ <option value="3">FFT</option>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td><button id="clip_warp" class="smbut">Warp</button></td>
+ <td><button id="clip_loop" class="smbut">Loop</button></td>
+ </tr>
+ <tr>
+ <td>
+ <input id="clip_pitch" class="input-knob" type="range" data-src="image/knob70.png" data-sprites="100" style="width:64px; height: 64px; background-image: url('image/knob70.png'); background-size: 100%; background-position: 0px -3200px;" min="-24" max="24" step="1" value="0"/><br />
+ <input id="clip_pitchtext" type="number" min="-24" max="24" step="1" value="0" />
+ </td>
+ <td>
+ <input id="clip_amp" class="input-knob" type="range" data-src="image/knob70.png" data-sprites="100" style="width:64px; height: 64px; background-image: url('image/knob70.png'); background-size: 100%; background-position: 0px -3200px;" min="0" max="1" step="0.000001" value="1"/>
+ </td>
+ </tr>
+ </tbody></table>
+ </div>
+ <div id="clipdetailsright"></div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twine/_hOLD/index_old.html b/site/app/twine/_hOLD/index_old.html new file mode 100644 index 0000000..351e50b --- /dev/null +++ b/site/app/twine/_hOLD/index_old.html @@ -0,0 +1,102 @@ +<html>
+ <head>
+ <script type="text/javascript" src="/code/jquery.js"></script>
+ <script type="text/javascript" src="../base/base.js"></script>
+ <script type="text/javascript">
+ window.app = new CSApplication(
+ {
+ csdUrl: "timeline.csd",
+ files: ["test.mp3"],
+ onPlay: function () {
+ $("#start").hide();
+ runTest();
+ }
+ }
+ );
+
+ function toggle(target, channel, multiplier) {
+ var item = new Nexus.Toggle(target);
+ item.on("change", function(v) {
+ app.setControlChannel(channel, (v ? 1 : 0) * multiplier);
+ });
+ }
+
+ function slider(target, channel, multiplier) {
+ var item = new Nexus.Slider(target);
+ item.on("change", function(v) {
+ app.setControlChannel(channel, v * multiplier);
+ });
+ }
+
+ function dial(target, channel, multiplier) {
+ var item = new Nexus.Dial(target);
+ item.on("change", function(v) {
+ app.setControlChannel(channel, v * multiplier);
+ });
+ }
+
+ function makeRow(tbody, name, text, widgetType, multiplier) {
+ var row = $("<tr />");
+ for (var x = 0; x < 4; x++) {
+ var id = name + (x + 1);
+ var cell = $("<td />").appendTo(row);
+ var widget = $("<div />").attr("id", id).appendTo(cell);
+ var label = $("<div />").text(text).appendTo(cell);
+ }
+ tbody.append(row);
+ for (var x = 0; x < 4; x++) {
+ var id = name + (x + 1);
+ widgetType("#" + id, id, multiplier);
+ }
+ }
+
+ function makeMixer() {
+ var maxeq = 2;
+ var maxsend = 2;
+ var maxamp = 1.5;
+ var items = {
+ compmodel: ["Component model", toggle, 1],
+ lowcut: ["Low cut", toggle, 1],
+ eqhigh: ["EQ high", dial, maxeq],
+ eqmid: ["EQ mid", dial, maxeq],
+ eqlow: ["EQ low", dial, maxeq],
+ auxA: ["Aux 1", dial, maxsend],
+ preA: ["Aux 1 prefade", toggle, 1],
+ auxB: ["Aux 2", dial, maxsend],
+ preB: ["Aux 2 prefade", toggle, 1],
+ auxC: ["Aux 3", dial, maxsend],
+ preC: ["Aux 3 prefade", toggle, 1],
+ auxD: ["Aux 4", dial, maxsend],
+ preD: ["Aux 4 prefade", toggle, 1],
+ gain: ["Gain", dial, 1.5],
+ };
+ var tbl = $("<table />").appendTo($("#mixer"));
+ var tbody = $("<tbody />").appendTo(tbl);
+ for (var k in items) {
+ makeRow(tbody, k, items[k][0], items[k][1], items[k][2]);
+ }
+ }
+
+ $(function() {
+ $("#start").click(function() {
+ app.play();
+ });
+
+ $("#callback").click(function() {
+ var cbid = app.createCallback(function(data) {
+ $("#callback_response").text("Response from CBID " + data.cbid);
+ });
+
+ app.insertScore("cbtest", [0, 1, cbid]);
+ });
+ });
+ </script>
+ </head>
+ <body>
+ <button id="start">Start</button>
+ <!--<button id="callback">Callback test</button>
+ <div id="callback_response"></div>
+ -->
+ <div id="mixer"></div>
+ </body>
+</html>
\ No newline at end of file diff --git a/site/app/twine/_hOLD/index_workingold.html b/site/app/twine/_hOLD/index_workingold.html new file mode 100644 index 0000000..21812d7 --- /dev/null +++ b/site/app/twine/_hOLD/index_workingold.html @@ -0,0 +1,1251 @@ +<html>
+<head>
+<title>twine</title>
+<link rel="stylesheet" href="../base/theme.css">
+<link rel="stylesheet" href="../twirl/twirl.css">
+<style type="text/css">
+
+body {
+ font-family: var(--fontFace);
+ color: var(--fgColor1);
+ font-size: var(--fontSizeDefault);
+ user-select: none;
+ cursor: arrow;
+ font-size: 11pt;
+}
+
+#twine_menubar {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ right: 0px;
+ height: 20px;
+ z-index: 6;
+}
+
+.transparentinput {
+ font-size: var(--fontSizeSmall);
+ background-color: var(--bgColor3);
+ color: var(--fgColor2);
+ border: none;
+}
+
+.slider {
+ background: var(--bgColor3);
+ accent-color: var(--fgColor2);
+}
+
+#twine_header {
+ position: absolute;
+ top: 20px;
+ height: 30px;
+ left: 0px;
+ width: 100%;
+ background-color: var(--bgColor1);
+ overflow: none;
+}
+
+.drag_selection {
+ position: fixed;
+ background-color: #323232;
+ opacity: 0.5;
+ z-index: 101;
+}
+
+#twine_headertable {
+ height: 30px;
+}
+
+#twine_clipdetails {
+ display: none;
+}
+
+#twine_channeldetailslow {
+ display: none;
+}
+
+#loading {
+ opacity: 0.7;
+ background-color: #767676;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ display: none;
+ z-index: 666;
+}
+
+#loading_centre {
+ z-index: 667;
+ position: relative;
+ height: 200px;
+}
+
+#loading_text {
+ font-size: 24pt;
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 72pt;
+ text-align: center;
+}
+
+#start {
+ z-index: 200;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #343434;
+}
+
+#start_centre {
+ z-index: 201;
+ position: relative;
+ height: 200px;
+}
+
+#start_invoke {
+ z-index: 202;
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 72pt;
+ cursor: pointer;
+}
+
+#twine_main {
+ position: absolute;
+ top: 50px;
+ bottom: 0px;
+ left: 0px;
+ width: 100%;
+}
+
+#twine_timeline {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 70%;
+}
+
+#twine_timelineoverlay {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ opacity: 0.1;
+ background-color: #ffffff;
+}
+
+
+.timelinetext {
+ font-size: var(--fontSizeSmall);
+ opacity: 0.9;
+ position: absolute;
+ color: var(--fgColor3);
+ top: 2px;
+ z-index: 21;
+}
+
+.timelinemarker {
+ width: 1px;
+ position: absolute;
+ background-color: #bdbdbd;
+ opacity: 0.9;
+ height: 100%;
+ top: 0px;
+ z-index: 20;
+}
+
+.smbut {
+ font-size: 8pt;
+ background-color: var(--bgColor2);
+ color: var(--fgColor2);
+ border: 1px solid black;
+}
+
+.knoblabel {
+ font-size: 8pt;
+ text-align: center;
+}
+
+#twine_details {
+ position: absolute;
+ left: 0px;
+ bottom: 0px;
+ width: 100%;
+ height: 30%;
+ background-color: var(--bgColor1);
+}
+
+#twine_clipdetailsleft {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 30%;
+ height: 100%;
+ font-size: var(--fontSizeSmall);
+ background-color: var(--bgColor2);
+}
+
+#twine_clipdetailsright {
+ position: absolute;
+ left: 30%;
+ top: 0px;
+ width: 70%;
+ height: 100%;
+ background-color: var(--bgColor3);
+}
+
+.channel {
+ height: 30px;
+ width: 100%;
+ border-bottom: 1px solid #aaaaaa;
+ left: 0px;
+}
+
+.channeldetails {
+ user-select: none;
+ position: absolute;
+ height: 30px;
+ left: 0px;
+ width: 10%;
+}
+
+.channelclips {
+ position: absolute;
+ height: 30px;
+ left: 10%;
+ width: 90%;
+ background-color: var(--bgColor2);
+}
+
+.clip {
+ user-select: none;
+ position: absolute;
+ padding: 0px;
+ cursor: move;
+ z-index: 70;
+ width: 50px;
+ height: 30px;
+ background-color: #CC3333;
+ color: #000000;
+ overflow: hidden;
+}
+</style>
+<script type="text/javascript" src="/code/jquery.js"></script>
+<script type="text/javascript" src="../base/base.js"></script>
+<script type="text/javascript" src="../twirl/twirl.js"></script>
+<script type="text/javascript" src="../base/waveform.js"></script>
+<script type="text/javascript" src="ui-elements.js"></script>
+<script type="text/javascript" src="/code/input-knobs.js"></script>
+<script type="text/javascript">
+
+
+
+var clips = {};
+var channels = [];
+var maxID = 0;
+var chanHeight = 30;
+
+
+function getID() {
+ return maxID++;
+}
+
+
+
+function setupUI(twine) {
+ var ui = {};
+ ui.clip = {
+ audition: new PlayButton({
+ target: "twine_clip_audition",
+ change: function(v, obj) {
+ if (obj.state == true) {
+ twine.selectedClip.play(function(ndata) {
+ if (ndata.status == 0) {
+ obj.setValue(false);
+ app.removeCallback(ndata.cbid);
+ }
+ });
+ } else {
+ app.insertScore("ecpseq_stop");
+ }
+ }
+ }),
+ name: new TextInput({
+ target: "twine_clip_name",
+ change: function(val) {
+ twine.selectedClip.setData("name", val);
+ }
+ }),
+ colour: new ColourInput({
+ target: "twine_clip_colour",
+ change: function(val) {
+ twine.selectedClip.colour = val;
+ }
+ }),
+ warp: new StandardToggle({
+ label: "Warp",
+ target: "twine_clip_warp",
+ change: function(val) {
+ twine.selectedClip.setData("warp", val);
+ twine.selectedClip.setSize();
+ }
+ }),
+ loop: new StandardToggle({
+ label: "Loop",
+ target: "twine_clip_loop",
+ change: function(val) {
+ twine.selectedClip.setData("loop", val);
+ twine.selectedClip.setSize();
+ }
+ }),
+ readType: new ComboBox({
+ target: "twine_clip_readtype",
+ options: [
+ "Repitch", "Grain", "FFTab", "FFT"
+ ],
+ change: function(val) {
+ twine.selectedClip.setData("warpMode", val);
+ },
+ stateAlter: function(val) {
+ twine.ui.clip.fftSize.hide();
+ twine.ui.clip.winSize.hide();
+ twine.ui.clip.winRandom.hide();
+ twine.ui.clip.winOverlap.hide();
+ twine.ui.clip.winType.hide();
+ if (val == 1) {
+ twine.ui.clip.winSize.show();
+ twine.ui.clip.winRandom.show();
+ twine.ui.clip.winOverlap.show();
+ twine.ui.clip.winType.show();
+ } else if (val > 1) {
+ twine.ui.clip.fftSize.show();
+ }
+ }
+ }),
+ amp: new Slider({
+ label: "Gain",
+ valueLabel: true,
+ value: 1,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ changeOnInput: true,
+ change: function(val) {
+ twine.selectedClip.setData("amp", val);
+ }
+ }),
+ pitch: new Slider({
+ label: "Pitch",
+ valueLabel: true,
+ min: -12,
+ max: 12,
+ step: 1,
+ value: 0,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ changeOnInput: true,
+ change: function(val) {
+ var c = twine.selectedClip;
+ var pitch = Math.pow(2, (val / 12));
+ c.setData("pitch", pitch);
+ if (c.warpMode == 0 && c.loop == 0 && c.warp == 0) {
+ c.setSize();
+ }
+ }
+ }),
+ fftSize: new ComboBox({
+ label: "FFT Size",
+ asRow: true,
+ target: "twine_clipparamsbottom",
+ options: [
+ "256", "512", "1024", "2048"
+ ],
+ asValue: true,
+ change: function(val) {
+ twine.selectedClip.setData("fftSize", val);
+ }
+ }),
+ winSize: new Slider({
+ label: "Window size",
+ valueLabel: true,
+ min: 44,
+ max: 4410,
+ step: 1,
+ value: 4410,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: function(val) {
+ twine.selectedClip.setData("txtWinSize", val);
+ }
+ }),
+ winRandom: new Slider({
+ label: "Window random",
+ valueLabel: true,
+ min: 0,
+ max: 441,
+ step: 1,
+ value: 441,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: function(val) {
+ twine.selectedClip.setData("txtRandom", val);
+ }
+ }),
+ winOverlap: new Slider({
+ label: "Window overlap",
+ valueLabel: true,
+ min: 0,
+ max: 16,
+ step: 1,
+ value: 4,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: function(val) {
+ twine.selectedClip.setData("txtOverlap", val);
+ }
+ }),
+ winType: new ComboBox({
+ label: "Window type",
+ asRow: true,
+ target: "twine_clipparamsbottom",
+ options: [
+ "Hanning", "Hamming", "Half sine"
+ ],
+ change: function(val) {
+ twine.selectedClip.setData("txtWinType", val);
+ }
+ })
+ };
+
+ ui.head = {
+ play: new PlayButton({
+ target: "twine_head_play",
+ fontsize: "14pt",
+ change: function(v, obj) {
+ if (obj.state == true) {
+ twine.play();
+ } else {
+ twine.stop();
+ obj.setValue(false);
+ }
+ }
+ }),
+ snap: new StandardToggle({
+ label: "Snap",
+ target: "twine_head_snap",
+ change: function(val) {
+ twine.timeline.snapToGrid = val;
+ }
+ }),
+ grid: new StandardToggle({
+ label: "Grid",
+ target: "twine_head_showgrid",
+ change: function(val) {
+ twine.timeline.gridVisible = val;
+ }
+ })
+ };
+ return ui;
+} // end setupUI
+
+
+var TimelineGrid = function(twine, data) {
+ var self = this;
+
+ if (!data) {
+ var data = {
+ snapToGrid: true,
+ gridVisible: true,
+ timeSigMarker: 4,
+ resolution: null,
+ startBeat: 0,
+ endBeat: 16,
+ bpm: 120
+ };
+ }
+
+ this.getSaveData = function() {
+ return data;
+ };
+
+ function calcViewport() {
+ data.minLeft = (window.screen.width / 100) * 10;
+ var width = window.screen.width - data.minLeft;
+ var beats = data.endBeat - data.startBeat;
+ data.pixelsPerBeat = width / beats;
+ return {
+ minLeft: data.minLeft,
+ width: width,
+ beats: beats,
+ pixelsPerBeat: Math.round(data.pixelsPerBeat)
+ }
+ }
+
+ function draw() {
+ $(".timelinemarker").remove();
+ $(".timelinetext").remove();
+ if (!data.gridVisible) {
+ return;
+ }
+
+ var target = $("#twine_timeline");
+ var geometry = calcViewport();
+
+ var beat = data.startBeat;
+
+ var width;
+ var fontWeight;
+ for (var x = geometry.minLeft; x < window.screen.width; x += geometry.pixelsPerBeat) {
+ if ((beat - 1) % data.timeSigMarker == 0) {
+ width = 2;
+ fontWeight = "bold";
+ } else {
+ width = 1;
+ fontWeight = "normal";
+ }
+ $("<div />").attr("class", "timelinemarker").appendTo(target).css("width", width).css("left", x);
+ $("<div />").attr("class", "timelinetext").appendTo(target).css("font-weight", fontWeight).css("left", x + 2).text(beat);
+ beat ++;
+ }
+ }
+
+ Object.defineProperty(this, "startBeat", {
+ get: function() { return data.startBeat; },
+ set: function(x) {
+ data.startBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "bpm", {
+ get: function() { return data.bpm; },
+ set: function(x) {
+ data.bpm = x;
+ app.insertScore("ecpweb_setbpm", [0, 1, data.bpm]);
+ }
+ });
+
+ Object.defineProperty(this, "endBeat", {
+ get: function() { return data.endBeat; },
+ set: function(x) {
+ data.endBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "minLeft", {
+ get: function() { return data.minLeft; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "pixelsPerBeat", {
+ get: function() { return data.pixelsPerBeat; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "snapToGrid", {
+ get: function() { return data.snapToGrid; },
+ set: function(x) {
+ data.snapToGrid = (x == 1);
+ }
+ });
+
+ Object.defineProperty(this, "gridVisible", {
+ get: function() { return data.gridVisible; },
+ set: function(x) {
+ data.gridVisible = (x == 1);
+ draw();
+ }
+ });
+
+ var dragHandleTime;
+ function handleMousedown(e) {
+ dragHandleTime = {};
+ dragHandleTime.pageX0 = e.pageX;
+ dragHandleTime.pageY0 = e.pageY;
+ dragHandleTime.elem = this;
+ dragHandleTime.offset0 = $(this).offset();
+ dragHandleTime.selection = $("<div />").addClass("drag_selection").css("left", e.pageX).css("top", e.pageY).appendTo($("#twine_timeline"));
+
+ function handleDrag(e) {
+ var left = dragHandleTime.offset0.left + (e.pageX - dragHandleTime.pageX0);
+ var minLeft = (window.screen.width / 100) * 10;
+
+ if (twine.timeline.snapToGrid) {
+ left = (Math.floor((left - minLeft) / twine.timeline.pixelsPerBeat) * twine.timeline.pixelsPerBeat) + minLeft;
+ }
+
+ if (left < minLeft) {
+ left = minLeft
+ }
+
+ var top = dragHandleTime.offset0.top + (e.pageY - dragHandleTime.pageY0);
+ top = Math.floor(top / chanHeight) * chanHeight;
+ var maxTop = chanHeight * channels.length;
+ if (top > maxTop) {
+ top = maxTop;
+ } else if (top < 30) {
+ top = 30;
+ }
+
+ $(dragHandleTime.elem)
+ .css("height", top - dragHandleTime.pageY0)
+ .css("width", left - dragHandleTime.pageX0);
+
+ }
+
+ function handleMouseUp(e) {
+ $("body")
+ .off("mousemove", handleDrag)
+ .off("mouseup", handleMouseUp);
+ dragHandleTime.selection.remove();
+ }
+
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ }
+ //$("#twine_timeline").mousedown(handleMousedown); // selection area
+ draw();
+};
+
+
+var Sequencer = function(twine, data) {
+ var self = this;
+ var gridSnap = 0;
+ var timeScale = 1;
+
+ if (!data) {
+ var data = {
+ tempo: 120,
+ playing: false
+ };
+ }
+
+ this.userImportedFiles = [];
+
+ this.setTempo = function(v) {
+ insertScore("ecpweb_setglobal", [0, 1, 0, v]);
+ };
+
+ this.getSaveData = function() {
+ var sdata = {"sequencer": data, "channels": [], "clips": {}};
+ for (var x in channels) {
+ sdata.channels.push(channels[x].getSaveData());
+ }
+ for (var x in clips) {
+ sdata.clips[x] = clips[x].getSaveData();
+ }
+ return sdata;
+ };
+
+ this.loadSaveData = function(v) {
+ data = v.sequencer;
+ for (var x in v.channels) {
+ new Channel(v.channels[x]);
+ }
+ };
+
+ Object.defineProperty(this, "playing", {
+ get: function() { return data.playing; },
+ set: function(x) {
+ data.playing = x;
+ }
+ });
+};
+
+
+var Channel = function(data) {
+ var self = this;
+ channels.push(this);
+
+ if (!data) {
+ var index = channels.length;
+ var data = {
+ name: "Channel " + index,
+ index: index
+ };
+ } else {
+ var index = data.index;
+ }
+
+ function channelClick() {
+ $("#twine_clipdetails").hide();
+ $("#twine_channeldetailslow").show();
+
+ }
+
+ var element = $("<div />").attr("id", "twine_channel" + index).attr("class", "channel").appendTo("#twine_timeline").append(
+ $("<div />").attr("id", "twine_channeldetails" + index).attr("class", "channeldetails").text(data.name).click(channelClick)
+ ).append(
+ $("<div />").attr("id", "twine_channelclips" + index).attr("class", "channelclips")
+ );
+};
+
+var Clip = function(channel, data, parent) {
+ var self = this;
+ var loaded = false;
+ var hasTwin = (parent) ? true : false;
+ var waveformClip;
+ var waveformEdit;
+ var datatable;
+
+ if (!data) {
+ var id = getID();
+ var data = {
+ name: "Clip " + id,
+ channel: channel,
+ id: id,
+ clipindex: null,
+ playLength: 1,
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16),
+ position: 0,
+ };
+ }
+
+ clips[data.id] = this;
+ var elWaveEdit = $("<div />").css({width: "100%", height: "100%", top: "0px", left: "0px"});
+
+ var element = $("<div />").attr("class", "clip").attr("id", "clip" + data.id).click(function() {
+ twine.selectedClip = self;
+
+ $("#twine_channeldetailslow").hide();
+ $("#twine_clipdetails").show();
+ var cui = twine.ui.clip;
+ cui.name.setValue(data.name);
+ cui.colour.setValue(data.colour);
+ cui.amp.setValue(data.amp);
+ cui.warp.setValue(data.warp);
+ cui.loop.setValue(data.loop);
+ cui.readType.setValue(data.warpMode);
+ cui.pitch.setValue(Math.round((Math.log(data.pitch) / Math.log(2)) * 12));
+ cui.fftSize.setValue(data.fftSize);
+ cui.winSize.setValue(data.txtWinSize);
+ cui.winRandom.setValue(data.txtRandom);
+ cui.winOverlap.setValue(data.txtOverlap);
+ cui.winType.setValue(data.txtWinType);
+
+ showEditWaveform($("#twine_clipdetailsright"));
+
+ }).css("top", (channel * chanHeight) + "px").css("background-color", data.colour).mousedown(handle_mousedown)
+ .css("left", ((data.position * twine.timeline.pixelsPerBeat)) + "px")
+ .appendTo($("#twine_channelclips" + channel));
+
+ this.el = element;
+ // resizable()
+ var elWaveClip = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px"}).appendTo(element);
+ var elWaveText = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "font-size": "var(--fontSizeSmall)", color: "var(--fgColor1)"}).text(data.name).appendTo(element);
+
+
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ element.css("background-color", data.colour);
+ }
+ });
+
+ Object.defineProperty(this, "position", {
+ get: function() { return data.position; },
+ set: function(x) {
+ self.setData("position", x);
+ }
+ });
+
+
+// debug
+this.ddata = data;
+ var dataMode = {
+ fnL: 0,
+ fnR: 1,
+ divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+ // warp points are 16 + in table
+
+ position: -1,
+ name: -2,
+ soundPath: -3,
+ channel: -4,
+ clipindex: -5,
+ playLength: -6
+ };
+
+ async function getDataFromTable(key) {
+ async function setFromKey(key) {
+ if (dataMode[key] < 0) return;
+ var value = await app.getCsound().tableGet(datatable, dataMode[key])
+ data[key] = value;
+ }
+
+ for (var k in dataMode) {
+ setFromKey(k);
+ }
+ }
+
+ async function getMarkers() {
+
+ }
+
+
+ this.setData = function(modeString, v, onComplete) {
+ if (dataMode[modeString] < 0) {
+ data[modeString] = v;
+ if (modeString == "name") {
+ elWaveText.text(data.name);
+ }
+ return;
+ }
+
+ function doSetData() {
+ app.getCsound().tableSet(datatable, dataMode[modeString], v);
+ data[modeString] = v;
+ }
+
+ if (hasTwin) {
+ app.insertScore("ecpweb_cloneclip", [0, 1, app.createCallback(function(ndata) {
+ hasTwin = false;
+ data.clipindex = ndata.clipindex;
+ datatable = ndata.datatable;
+ doSetData();
+ if (onComplete) onComplete();
+ })]);
+ } else {
+ doSetData();
+ if (onComplete) onComplete();
+ }
+ }
+
+ this.getPlaybackArgs = function(cbid, time) {
+ return [(time) ? time: 0, 1, cbid, data.clipindex, "mxchan" + (data.channel - 1)];
+ };
+
+ this.play = function(onCallback) {
+ var cbid = app.createCallback(function(ndata) {
+ if (onCallback) onCallback(ndata);
+ }, true);
+ app.insertScore("ecp_playback", self.getPlaybackArgs(cbid));
+ }
+
+ this.loadTest = function() {
+ self.loadFromPath("test.mp3");
+ };
+
+
+ async function getSourceTables() {
+ var wavedata = [];
+ var tbL = await app.getTable(data.fnL);
+ wavedata.push(tbL);
+ if (data.hasOwnProperty("fnR") && data.fnR > 0) {
+ var tbR = await app.getTable(data.fnR);
+ wavedata.push(tbR);
+ }
+ return wavedata;
+ }
+
+ async function setClipWaveform() {
+ if (!waveformClip) {
+ waveformClip = new Waveform({
+ target: elWaveClip,
+ allowSelect: false,
+ showGrid: false,
+ bgColor: "rgb(255, 255, 255, 0)",
+ fgColor: "#000000"
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTables();
+ waveformClip.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ waveformClip.redraw();
+ }
+ }
+
+ async function showEditWaveform(target) {
+ target.empty().append(elWaveEdit);
+ if (!waveformEdit) {
+ waveformEdit = new Waveform({
+ target: elWaveEdit,
+ allowSelect: true,
+ showGrid: true,
+ latencyCorrection: twirl.latencyCorrection // , markers:
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTables();
+ waveformEdit.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ waveformEdit.redraw();
+ }
+ }
+
+ this.setSize = function() {
+ var beattime = 60 / twine.timeline.bpm;
+ var beatLength;
+ if (data.loop == 0 && data.warp == 0) {
+ if (data.warpMode == 0) {
+ beatLength = data.duration / data.pitch;
+ } else {
+ beatLength = data.duration;
+ }
+ } else {
+ beatLength = data.playLength;
+ }
+ var width = (beatLength / beattime) * twine.timeline.pixelsPerBeat;
+ element.css("width", width + "px");
+ setClipWaveform();
+ }
+
+ this.redraw = function() {
+ self.setSize();
+ };
+
+ this.loadFromPath = function(path, userImported) {
+ var cbid = app.createCallback(async function(ndata) {
+ //await app.unlinkFile(path);
+ if (ndata.status == -1) {
+ return self.errorHandler("File not valid");
+ } else if (ndata.status == -2) {
+ return self.errorHandler("File too large");
+ }
+ datatable = ndata.data.datatable;
+ await getDataFromTable();
+ data.clipindex = ndata.data.clipindex;
+ data.channel = ndata.data.channel;
+ data.name = ndata.data.name;
+ elWaveText.text(data.name);
+ data.soundPath = path;
+
+ if (userImported) {
+ twine.seq.userImportedFiles.push(path);
+ }
+ loaded = true;
+ twirl.loading.hide();
+ self.setSize();
+ });
+ app.insertScore("ecpweb_loadsound", [0, 1, cbid, path, data.channel, data.position]);
+ };
+
+ this.clone = function() {
+ var newdata = Object.assign({}, data);
+ newdata.id = getID();
+ return new Clip(data.channel, newdata, self);
+ };
+
+ this.randomiseWarpPoints = function(mode) { // mode is -1, 0 or 1 I think..
+ if (!mode) mode = 0;
+ var cbid = app.createCallback(function(ndata) {
+ notify("OK");
+ });
+ app.insertScore("ecpweb_randomisewarppoints", [0, 1, cbid, mode]);
+ };
+
+ var dragHandleClip;
+ function handle_mousedown(e){
+ var originalPosition = data.position;
+ dragHandleClip = {};
+ dragHandleClip.pageX0 = e.pageX;
+ dragHandleClip.pageY0 = e.pageY;
+ dragHandleClip.elem = this;
+ dragHandleClip.offset0 = $(this).offset();
+ var isCopying = e.ctrlKey;
+
+ if (isCopying) { // && loaded
+ self.clone();
+ }
+
+ function handle_dragging(e){
+ var left = dragHandleClip.offset0.left + (e.pageX - dragHandleClip.pageX0);
+ var minLeft = (window.screen.width / 100) * 10;
+
+ //round
+ // left = Math.ceil(left / pixelsPerBeat) * pixelsPerBeat;
+
+ if (twine.timeline.snapToGrid) {
+ left = (Math.ceil((left - minLeft) / twine.timeline.pixelsPerBeat) * twine.timeline.pixelsPerBeat) + minLeft;
+ }
+
+
+ if (left < minLeft) {
+ left = minLeft
+ }
+ data.position = twine.timeline.startBeat + ((left - minLeft) / twine.timeline.pixelsPerBeat);
+
+ var header = 50;
+ var top = dragHandleClip.offset0.top + (e.pageY - dragHandleClip.pageY0);
+ top = (Math.ceil(top / chanHeight) * chanHeight) + header;
+ var maxTop = (chanHeight * channels.length) + header;
+
+ if (top > maxTop) {
+ top = maxTop;
+ } else if (top < 30) {
+ top = 30;
+ }
+
+
+ $(dragHandleClip.elem).offset({top: top, left: left});
+ }
+
+ function handle_mouseup(e){
+ $("body")
+ .off("mousemove", handle_dragging)
+ .off("mouseup", handle_mouseup);
+ if (data.position != originalPosition) {
+ self.setData("position", data.position);
+ }
+ }
+
+ $("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
+ }
+
+ if (parent) {
+ self.redraw();
+ }
+};
+
+function runTest() {
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+ new Channel();
+}
+
+var topMenuData = [
+ {name: "File", contents: [
+ {name: "New", disableOnPlay: true, shortcut: {name: "Ctrl N", ctrlKey: true, key: "n"}, click: function(twine) {
+ twine.createNewInstance();
+ }},
+ {name: "Save", disableOnPlay: true, shortcut: {name: "Ctrl S", ctrlKey: true, key: "s"}, click: function(twine) {
+ twine.saveFile();
+ }},
+ {name: "Close", disableOnPlay: true, shortcut: {name: "Ctrl W", ctrlKey: true, key: "w"}, click: function(twine) {
+ twine.closeInstance();
+ }},
+ ]},
+ {name: "Help", contents: [
+ {name: "Help", click: function(twine){
+ $("#twist_documentation")[0].click();
+ }},
+ {name: "About", click: function(twine) {
+ twine.ui.showAbout();
+ }},
+ ]}
+];
+
+
+var Twine = function() {
+ twirl.init();
+ var twine = this;
+ var playing = false;
+ this.onPlays = [];
+ this.selectedClip = null;
+ this.clipUpdates = true;
+ this.timeline = new TimelineGrid(twine);
+ this.seq = new Sequencer(twine);
+ this.topMenu = new twirl.TopMenu(twine, topMenuData, $("#twine_menubar"));
+ this.ui = setupUI(twine);
+
+ twine.ui.head.grid.setValue(1, true);
+ twine.ui.head.snap.setValue(1, true);
+
+ this.setPlaying = function(state) {
+ playing = state;
+ };
+
+ this.play = function() {
+ if (playing) return;
+ twine.setPlaying(true);
+ var time;
+ var reltime;
+ var maxtime = 0;
+ var beatTime = 60 / twine.timeline.bpm;
+ for (var c in clips) {
+ time = clips[c].position;
+ if (time >= twine.timeline.startBeat && time <= twine.timeline.endBeat) {
+ reltime = time - twine.timeline.startBeat;
+ if (reltime + clips[c].duration > maxtime) {
+ maxtime = reltime + clips[c].duration;
+ }
+ app.insertScore("ecp_playback", clips[c].getPlaybackArgs(-1, reltime * beatTime));
+ }
+ }
+ var cbid = app.createCallback(function() {
+ twine.setPlaying(false);
+ });
+ app.insertScore("ecpweb_playbackwatchdog", [0, maxtime, cbid]);
+ };
+
+ this.stop = function() {
+ if (!playing) return;
+ app.insertScore("ecpweb_stopplayback");
+ };
+
+ async function handleFileDrop(e) {
+ e.preventDefault();
+ twirl.loading.show();
+ for (const item of e.originalEvent.dataTransfer.files) {
+ if (!twirl.audioTypes.includes(item.type)) {
+ return self.errorHandler("Unsupported file type", self.ui.showLoadNewPrompt);
+ }
+ if (item.size > twirl.maxFileSize) {
+ return self.errorHandler("File too large", self.ui.showLoadNewPrompt);
+ }
+
+ errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ await app.getCsound().fs.writeFile(item.name, buffer);
+ var x = new Clip(1); // determine channel
+ x.loadFromPath(item.name, true);
+ twirl.loading.hide();
+ }
+ }
+
+ var tempclip = null;
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+
+ if (!tempclip) {
+ tempclip = $("<div />").addClass("clip").text("New Clip");
+ $("#twine_timelineoverlay").show().append(tempclip);
+ }
+
+ tempclip.css("top", e.pageY + "px").css("left", e.pageX + "px");
+
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ $("#twine_timelineoverlay").hide();
+ if (tempclip) tempclip.remove();
+ }).on("drop", function(e) {
+ $("#twine_timelineoverlay").hide();
+ if (tempclip) tempclip.remove();
+ handleFileDrop(e);
+ });
+};
+
+
+$(function() {
+ window.twine = new Twine();
+
+ window.app = new CSApplication({
+ csdUrl: "twine.csd",
+ files: ["test.mp3"],
+ csOptions: ["--omacro:ECP_NORECORDING=1"],
+ onPlay: function () {
+ runTest();
+ twirl.loading.hide();
+ },
+ errorHandler: twirl.errorHandler,
+ ioReceivers: {percent: twirl.loading.setPercent}
+ });
+
+ $("#start_invoke").click(function() {
+ $("#start").hide();
+ twirl.loading.show();
+ app.play(function(text){
+ twirl.loading.show(text);
+ });
+ });
+
+
+
+
+
+});
+/*
+divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+*/
+</script>
+</head>
+<body>
+<div id="start">
+ <div id="start_centre">
+ <p id="start_invoke">Press to begin</p>
+ </div>
+</div>
+
+<div id="twine_header">
+ <table id="twine_headertable"><tbody><tr>
+ <td id="twine_head_play"></td>
+ <td id="twine_head_snap"></td>
+ <td id="twine_head_showgrid"></td>
+ </tr></tbody></table>
+</div>
+<div id="twine_menubar"></div>
+<div id="twine_main">
+ <div id="twine_timeline"></div>
+ <div id="twine_timelineoverlay"></div>
+ <div id="twine_details">
+ <div id="twine_channeldetailslow"></div>
+ <div id="twine_clipdetails">
+ <div id="twine_clipdetailsleft">
+ <table><tbody>
+ <tr>
+ <td id="twine_clip_audition"></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td id="twine_clip_colour"></td>
+ <td id="twine_clip_name"></td>
+ <td></td>
+ <td></td>
+ </tr>
+ </tbody></table>
+ <table><tbody>
+ <tr>
+ <td>Read type</td>
+ <td id="twine_clip_readtype"></td>
+ <td id="twine_clip_warp"></td>
+ <td id="twine_clip_loop"></td>
+ </tr>
+ </tbody></table>
+ <table><tbody id="twine_clipparamsbottom">
+ </tbody></table>
+ </div>
+ <div id="twine_clipdetailsright"></div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twine/_hOLD/timeline.csd b/site/app/twine/_hOLD/timeline.csd new file mode 100644 index 0000000..72e03ae --- /dev/null +++ b/site/app/twine/_hOLD/timeline.csd @@ -0,0 +1,154 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+#include "/scss/elasticlip_sequencer.udo"
+;#include "/scss/mixer/base.udo"
+#include "/interop.udo"
+#include "/bussing.udo"
+#include "/table_tools.udo"
+
+opcode ecpweb_getdata, S, iii
+ ichannel, iclipindex, itime xin
+ Sname = gSecp_clipnames[iclipindex]
+ Sresponse = sprintf("{\"-1\":%f,\"-2\":\"%s\",\"-4\":%d", itime, Sname, ichannel)
+
+ index = 2
+ while (index < giecp_controlitemnum) do
+ ival = tab_i(index, giecp_fnclips[iclipindex])
+ Sformat = strcat(",\"%d\":%", (frac(ival) == 0) ? "d" : "f")
+ Sresponse = strcat(Sresponse, sprintf(Sformat, index, ival))
+ index += 1
+ od
+ Sresponse = strcat(Sresponse, "}")
+ xout Sresponse
+endop
+
+opcode ecpweb_getdata, S, i
+ iseqindex xin
+ ichannel, iclipindex, itime ecpseq_get iseqindex
+ Sresponse ecpweb_getdata ichannel, iclipindex, itime
+ xout Sresponse
+endop
+
+instr ecpweb_getdata
+ icbid = p4
+ iseqindex = p5
+endin
+
+instr ecpweb_tabdestroy
+ ifn = p4
+ tab_destroy ifn
+ turnoff
+endin
+
+instr ecpweb_setbpm
+ ibpm = p4
+ gkseq_tempo init ibpm
+ turnoff
+endin
+
+instr ecpweb_loadsound
+ icbid = p4
+ Spath = strget(p5)
+ ichannel = p6
+ itime = p7
+ iforcemono = p8
+
+ iclipindex ecp_loadsound Spath, 4, iforcemono ;beats contentious, analyse and also set warp mode
+ iseqindex ecpseq_getnewindex
+
+ ecpseq_set iseqindex, ichannel, iclipindex, itime
+ Sdata ecpweb_getdata ichannel, iclipindex, itime
+
+ ifnwave ecp_getwaveform iclipindex
+
+ Sresponse = sprintf("{\"cbid\":%d,\"data\":%s,\"waveform\":%d}", icbid, Sdata, ifnwave)
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+
+instr ecpweb_copyclip
+ icbid = p4
+ iseqindex = p5
+ ichannel = p6
+ itime = p7
+
+ i_, iclipindex, i_ ecpseq_get iseqindex
+
+ iseqindex ecpseq_getnewindex
+ ecpseq_set iseqindex, ichannel, iclipindex, itime
+ Sresponse = sprintf("{\"cbid\":%d}", icbid)
+ io_sendstring("callback", Sresponse)
+endin
+
+
+instr ecpweb_setdata
+ icbid = p4
+ iseqindex = p5
+ idataindex = p6
+ ;p7 is value
+ ihastwin = p8
+
+ Sresponse = sprintf("{\"cbid\":%d", icbid)
+ iapplyupdate = 0
+ ichannel, iclipindex, itime ecpseq_get iseqindex
+
+ if (ihastwin == 1 && idataindex != -1) then
+ iclipindex ecp_cloneclip iclipindex
+ Sresponse = strcat(Sresponse, sprintf(",\"clipindex\":%d", iclipindex)) ; needed?
+ endif
+
+ if (idataindex < 0) then
+ if (idataindex == -2) then ;name
+ Sname = strget(p7)
+ ecp_set_name iclipindex, Sname
+ Sresponse = strcat(Sresponse, sprintf(",\"name\":\"%s\"", Sname))
+ elseif (idataindex == -1) then ;position
+ itime = p7
+ iapplyupdate = 1
+ elseif (idataindex == -4) then ;channel
+ ichannel = p7
+ iapplyupdate = 1
+ endif
+
+ elseif (idataindex >= 2) then
+ ivalue = p7
+ tabw_i ivalue, idataindex, giecp_fnclips[iclipindex]
+ endif
+
+ if (iapplyupdate == 1) then
+ ecpseq_set iseqindex, ichannel, iclipindex, itime
+ endif
+
+ io_sendstring("callback", strcat(Sresponse, "}"))
+ turnoff
+endin
+
+instr boot
+ schedule("mx_boot", 0, 1)
+
+ aL0, aR0 bus_read "mxchan0"
+ aL1, aR1 bus_read "mxchan1"
+ aL2, aR2 bus_read "mxchan2"
+ aL3, aR3 bus_read "mxchan3"
+
+ aoutL = aL0 + aL1 + aL2 + aL3
+ aoutR = aR0 + aR1 + aR2 + aR3
+ outs aoutL, aoutR
+endin
+
+</CsInstruments>
+<CsScore>
+i"boot" 0 36000
+f0 z
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/twine/_hOLD/timeline_base.html b/site/app/twine/_hOLD/timeline_base.html new file mode 100644 index 0000000..fc460bd --- /dev/null +++ b/site/app/twine/_hOLD/timeline_base.html @@ -0,0 +1,633 @@ +<html>
+<head>
+<style type="text/css">
+
+body {
+ font-family: Arial, sans-serif;
+ font-size: 11pt;
+}
+
+#header {
+ position: absolute;
+ top: 0px;
+ height: 30px;
+ left: 0px;
+ width: 100%;
+ background-color: #545454;
+}
+
+#headertable {
+ height: 30px;
+}
+
+#clipdetails {
+ display: none;
+}
+
+
+#main {
+ position: absolute;
+ top: 30px;
+ height: 100%;
+ left: 0px;
+ width: 100%;
+}
+
+#timeline {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 70%
+}
+
+.timelinetext {
+ font-size: 8pt;
+ opacity: 0.9;
+ position: absolute;
+ color: #121212;
+ top: 2px;
+}
+
+.timelinemarker {
+ width: 1px;
+ position: absolute;
+ background-color: #bdbdbd;
+ opacity: 0.9;
+ height: 100%;
+ top: 0px;
+ z-index: 50;
+}
+
+.smbut {
+ font-size: 8pt;
+ background-color: #b5b01d;
+ border: 1px solid black;
+}
+
+
+
+#details {
+ position: absolute;
+ left: 0px;
+ top: 70%;
+ width: 100%;
+ height: 30%;
+ background-color: #dcdcdc;
+}
+
+#clipdetailsleft {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 30%;
+ height: 100%;
+ background-color: #acacac;
+}
+
+#clipdetailsright {
+ position: absolute;
+ left: 30%;
+ top: 0px;
+ width: 70%;
+ height: 100%;
+ background-color: #cacaca;
+}
+
+.channel {
+ height: 30px;
+ width: 100%;
+ border-bottom: 1px solid #aaaaaa;
+ left: 0px;
+}
+
+.channeldetails {
+ position: absolute;
+ height: 30px;
+ left: 0px;
+ width: 10%;
+}
+
+.channelclips {
+ position: absolute;
+ height: 30px;
+ left: 10%;
+ width: 90%;
+ background-color: #cdcdcd;
+}
+
+.clip {
+ user-select: none;
+ position: absolute;
+ padding: 0px;
+ cursor: move;
+ z-index: 70;
+ width: 100px;
+ height: 30px;
+ color: #000000;
+ overflow: hidden;
+}
+</style>
+<script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+<script type="text/javascript">
+
+var clips = {};
+var channels = [];
+var maxID = 0;
+var chanHeight = 30;
+
+window.csseq = {};
+
+function getID() {
+ return maxID++;
+}
+
+var TimelineGrid = function(data) {
+ var self = this;
+
+ if (!data) {
+ var data = {
+ snapToGrid: true,
+ gridVisible: true,
+ timeSigMarker: 4,
+ resolution: null,
+ startBeat: 1,
+ endBeat: 16,
+ bpm: null
+ };
+ }
+
+ this.getSaveData = function() {
+ return data;
+ };
+
+ function calcViewport() {
+ data.minLeft = (window.screen.width / 100) * 10;
+ var width = window.screen.width - data.minLeft;
+ var beats = data.endBeat - data.startBeat;
+ data.pixelsPerBeat = width / beats;
+ return {
+ minLeft: data.minLeft,
+ width: width,
+ beats: beats,
+ pixelsPerBeat: Math.round(data.pixelsPerBeat)
+ }
+ }
+
+ function draw() {
+ $(".timelinemarker").remove();
+ $(".timelinetext").remove();
+ if (!data.gridVisible) {
+ return;
+ }
+
+ var target = $("#timeline");
+ var geometry = calcViewport();
+
+ var beat = data.startBeat;
+
+ var width;
+ var fontWeight;
+ for (var x = geometry.minLeft; x < window.screen.width; x += geometry.pixelsPerBeat) {
+ if ((beat - 1) % data.timeSigMarker == 0) {
+ width = 2;
+ fontWeight = "bold";
+ } else {
+ width = 1;
+ fontWeight = "normal";
+ }
+ $("<div />").attr("class", "timelinemarker").appendTo(target).css("width", width).css("left", x);
+ $("<div />").attr("class", "timelinetext").appendTo(target).css("font-weight", fontWeight).css("left", x + 2).text(beat);
+ beat ++;
+ }
+ }
+
+ Object.defineProperty(this, "startBeat", {
+ get: function() { return data.startBeat; },
+ set: function(x) {
+ data.startBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "endBeat", {
+ get: function() { return data.startBeat; },
+ set: function(x) {
+ data.startBeat = x;
+ draw();
+ }
+ });
+
+ Object.defineProperty(this, "minLeft", {
+ get: function() { return data.minLeft; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "pixelsPerBeat", {
+ get: function() { return data.pixelsPerBeat; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "snapToGrid", {
+ get: function() { return data.snapToGrid; },
+ set: function(x) {
+ data.snapToGrid = (x == 1);
+ }
+ });
+
+ Object.defineProperty(this, "gridVisible", {
+ get: function() { return data.gridVisible; },
+ set: function(x) {
+ data.gridVisible = (x == 1);
+ draw();
+ }
+ });
+
+
+
+ draw();
+};
+
+
+var Sequencer = function(data) {
+ var self = this;
+ var gridSnap = 0;
+ var timeScale = 1;
+
+ if (!data) {
+ var data = {
+ tempo: 120,
+ playing: false
+ };
+ }
+
+ this.setTempo = function(v) {
+ insertScore("ecpweb_setglobal", [0, 1, 0, v]);
+ };
+
+ this.getSaveData = function() {
+ var sdata = {"sequencer": data, "channels": [], "clips": {}};
+ for (var x in channels) {
+ sdata.channels.push(channels[x].getSaveData());
+ }
+ for (var x in clips) {
+ sdata.clips[x] = clips[x].getSaveData();
+ }
+ return sdata;
+ };
+
+ this.loadSaveData = function(v) {
+ data = v.sequencer;
+ for (var x in v.channels) {
+ new Channel(v.channels[x]);
+ }
+ };
+
+ Object.defineProperty(this, "playing", {
+ get: function() { return data.playing; },
+ set: function(x) {
+ data.playing = x;
+ }
+ });
+};
+
+
+var Channel = function(data) {
+ var self = this;
+ channels.push(this);
+
+ if (!data) {
+ var index = channels.length;
+ var data = {
+ name: "Channel " + index,
+ index: index
+ };
+ } else {
+ var index = data.index;
+ }
+
+ var element = $("<div />").attr("id", "channel" + index).attr("class", "channel").appendTo("#timeline").append(
+ $("<div />").attr("id", "channeldetails" + index).attr("class", "channeldetails").text(data.name)
+ ).append(
+ $("<div />").attr("id", "channelclips" + index).attr("class", "channelclips")
+ );
+};
+
+var Clip = function(channel, data, parent) {
+ var self = this;
+ var loaded = false;
+
+ if (!data) {
+ var id = getID();
+ var data = {
+ name: "Clip " + id,
+ channel: channel,
+ id: id,
+ clipindex: null,
+ beatTime: 0,
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16)
+ };
+ } else {
+ var id = data.id;
+ }
+ clips[id] = this;
+ var element = $("<div />").attr("class", "clip").attr("id", "clip" + id).text(data.name).click(function() {
+ csseq.selectedClip = self;
+ $("#clipdetails").show();
+ $("#clip_name").val(data.name);
+ $("#clip_colour").val(data.colour);
+
+ }).css("top", (channel * chanHeight) + "px").css("background-color", data.colour).mousedown(handle_mousedown)
+ .css("left", ((data.beatTime * csseq.timeline.pixelsPerBeat)) + "px")
+ .appendTo($("#channelclips" + channel));
+ // resizable()
+
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ element.css("background-color", data.colour);
+ }
+ });
+
+ var dataMode = {
+ divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+ // warp points are 16 + in table
+
+ position: -1,
+ name: -2,
+ soundPath: -3,
+ channel: -4
+ }
+
+ for (let x in dataMode) {
+ Object.defineProperty(this, x, {
+ get: function() { return data[x] },
+ set: function(v) {
+ self.setData(x, v);
+ }
+ });
+ }
+
+ /*// v should become defunct
+ Object.defineProperty(this, "name", {
+ get: function() { return data.name; },
+ set: function(x) {
+ data.name = x;
+ element.text(data.name);
+
+ // self.setData("name", x);
+ }
+ });*/
+
+
+ /*
+ function getData() {
+ var cbid = app.createCallback(function(ndata) {
+ for (var x in ndata.data) {
+ data[x] = ndata.data[x];
+ }
+ });
+ app.insertScore("ecpweb_getdata", [0, 1, cbid, clipindex]);
+ }*/
+
+ this.setData = function(modeString, v) {
+ var cbid = app.createCallback(function(ndata) {
+ if (ndata.hasOwnProperty("clipindex")) {
+ data.clipindex = ndata.clipindex;
+ }
+ data[modeString] = v;
+ if (modeString == "name") {
+ element.text(data.name);
+ }
+ });
+ app.insertScore("ecpweb_setdata", [0, 1, cbid, id, dataMode[modeString], v, (parent ? 1 : 0)]); // having ecp_cloneclip in if needed
+ }
+
+ this.loadTest = function() {
+ self.loadFromPath("test.mp3");
+ };
+
+ this.loadFromPath = function(path) {
+ var cbid = app.createCallback(function(ndata) {
+ for (var x in ndata.data) {
+ data[x] = ndata.data[x];
+ }
+ data.soundPath = path;
+ loaded = true;
+ });
+ app.insertScore("ecpweb_loadsound", [0, 1, cbid, path]);
+ };
+
+ this.clone = function() {
+ var newdata = Object.assign({}, data);
+ data.id = getID();
+ return new Clip(data.channel, newdata, self);
+ };
+
+ this.randomiseWarpPoints = function(mode) { // mode is -1, 0 or 1 I think..
+ if (!mode) mode = 0;
+ var cbid = app.createCallback(function(ndata) {
+ notify("OK");
+ });
+ app.insertScore("ecpweb_randomisewarppoints", [0, 1, cbid, mode]);
+ };
+
+
+ function handle_mousedown(e){
+
+ window.my_dragging = {};
+ my_dragging.pageX0 = e.pageX;
+ my_dragging.pageY0 = e.pageY;
+ my_dragging.elem = this;
+ my_dragging.offset0 = $(this).offset();
+ var isCopying = e.ctrlKey;
+
+ if (isCopying) { // && loaded
+ self.clone();
+ }
+
+ function handle_dragging(e){
+ var left = my_dragging.offset0.left + (e.pageX - my_dragging.pageX0);
+
+ var minLeft = (window.screen.width / 100) * 10;
+
+ //round
+ // left = Math.ceil(left / pixelsPerBeat) * pixelsPerBeat;
+
+ if (csseq.timeline.snapToGrid) {
+ left = (Math.ceil((left - minLeft) / csseq.timeline.pixelsPerBeat) * csseq.timeline.pixelsPerBeat) + minLeft;
+ }
+
+
+ if (left < minLeft) {
+ left = minLeft
+ }
+ data.beatTime = csseq.timeline.startBeat + ((left - minLeft) / csseq.timeline.pixelsPerBeat);
+
+ var top = my_dragging.offset0.top + (e.pageY - my_dragging.pageY0);
+ top = Math.ceil(top / chanHeight) * chanHeight;
+ var maxTop = chanHeight * channels.length;
+ if (top > maxTop) {
+ top = maxTop;
+ } else if (top < 30) {
+ top = 30;
+ }
+
+
+ $(my_dragging.elem)
+ .offset({top: top, left: left});
+ }
+
+ function handle_mouseup(e){
+ $("body")
+ .off("mousemove", handle_dragging)
+ .off("mouseup", handle_mouseup);
+ }
+
+ $("body").on("mouseup", handle_mouseup).on("mousemove", handle_dragging);
+ }
+
+ /*
+ this.setLength = function(v) {
+ setData("length", v);
+ }; // now made generic above.
+ */
+};
+
+
+
+
+$(function() {
+ csseq.timeline = new TimelineGrid();
+ csseq.seq = new Sequencer();
+
+
+ $(".smbut").attr("value", 0).click(function(){
+ var val;
+ var col;
+ if ($(this).attr("value") == 0) {
+ val = 1;
+ col = "#f2e30c";
+ } else {
+ val = 0;
+ col = "#b5b01d";
+ }
+ $(this).attr("value", val).css("background-color", col);
+ });
+
+ $("#head_snap").click(function() {
+ csseq.timeline.snapToGrid = $(this).attr("value");
+ });
+
+ $("#head_showgrid").click(function() {
+ csseq.timeline.gridVisible = $(this).attr("value");
+ });
+
+ $("#head_play").click(function() {
+ if (csseq.seq.playing) {
+ app.insertScore("ecpseq_stop");
+ } else {
+ var cbid = app.createCallback(function(data) {
+ if (data.state == "playing") {
+ csseq.seq.playing = true;
+ $(this).text("Stop");
+ } else if (data.state == "stopped") {
+ csseq.seq.playing = false;
+ $(this).text("Play");
+ app.removeCallback(data.cbid);
+ }
+ }, true);
+ app.insertScore("ecpseq_play", [0, 36000, cbid, csseq.timeline.startBeat]);
+ }
+ });
+
+ new Channel();
+ new Channel();
+ new Channel();
+ new Clip(0);
+ new Clip(1);
+ new Clip(2);
+
+
+ $("#clip_colour").change(function(){
+ csseq.selectedClip.colour = $(this).val();
+ });
+
+ $("#clip_name").change(function(){
+ csseq.selectedClip.name = $(this).val();
+ });
+
+});
+/*
+divisionsPerBeat: 2,
+ duration: 3,
+ beatsLength: 4,
+ utilisedLength: 5,
+ warpMode: 6,
+ pitch: 7,
+ amp: 8,
+ fftSize: 9,
+ txtWinSize: 10,
+ txtRandom: 11,
+ txtOverlap: 12,
+ loop: 13,
+ warp: 14,
+ txtWinType: 15,
+*/
+</script>
+</head>
+<body>
+<div id="header">
+ <table id="headertable"><tbody><tr>
+ <td><button id="play" class="smbut">Play</button></td>
+ <td><button id="head_snap" class="smbut">Snap</button></td>
+ <td><button id="head_showgrid" class="smbut">Grid</button></td>
+ </tr></tbody></table>
+</div>
+<div id="main">
+ <div id="timeline"></div>
+ <div id="details">
+ <div id="clipdetails">
+ <div id="clipdetailsleft">
+ <table><tbody>
+ <tr>
+ <td><input type="color" id="clip_colour"></td><td><input type="text" id="clip_name"></td>
+ </tr>
+ <tr>
+ <td>Read type</td>
+ <td><select id="clip_readtype">
+ <option value="0">Repitch</option>
+ <option value="1">Grain</option>
+ <option value="2">FFT</option>
+ <option value="3">FFTab</option>
+ </select>
+ </td>
+ </tr>
+ <tr><td><button id="clip_warp" class="smbut">Warp</button></td><td><button class="smbut">Loop</button></td></tr>
+ <tr><td>
+ <x-knob divisions="12" min="-12" max="12">
+ </td><td></td></tr>
+ </tbody></table>
+ </div>
+ <div id="clipdetailsright">
+
+ </div>
+ </div>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twine/channel.js b/site/app/twine/channel.js new file mode 100644 index 0000000..18f1b3a --- /dev/null +++ b/site/app/twine/channel.js @@ -0,0 +1,499 @@ +var Insert = function(channel, options) {
+ var insert = this;
+};
+
+
+var Channel = function(timeline, index) {
+ var channel = this;
+ this.clips = {};
+ this.width = null;
+ this.offset = null;
+ var heights = [25, 100];
+ this.height = heights[0];
+ this.index = index;
+ this.name = "Channel " + (index + 1);
+ var elChannel = $("<div />").addClass("twine_channel").css({
+ height: channel.height + "px"
+ }).appendTo(timeline.element);
+ this.inserts = [];
+ var splines = {};
+
+ var heightState = 0;
+ var elChannelControl = $("<div />").addClass("twine_channelcontrol").text(channel.name).appendTo(elChannel).dblclick(function(){
+ heightState = 1 - heightState;
+ channel.setHeight(heights[heightState]);
+ }).click(function(){
+ channel.showDetails();
+ }).on("contextmenu", function(e){
+ return twirl.contextMenu.show(e, [
+ {name: "Rename", click: function(){
+ var el = $("<div />");
+ $("<h4 />").text("Rename channel").appendTo(el);
+ var ti = $("<input />").val(channel.name).appendTo(el);
+ twirl.prompt.show(el, function(){
+ channel.setName(ti.val());
+ });
+ }}
+ ]);
+ });
+
+ var elChannelClips = $("<div />").addClass("twine_channelclips").appendTo(elChannel).mousedown(twine.timeline.dragSelection);
+
+ var elChannelSpline = $("<div />").css({
+ position: "absolute",
+ width: "100%",
+ height: "75%",
+ left: "0px",
+ top: "25%",
+ "z-index": 31,
+ opacity: 0.57,
+ "background-color": "var(--bgColor1)",
+ display: "none"
+ }).appendTo(elChannelClips);
+
+
+ channel.defaultChannels = {
+ amp: "twine_camp" + channel.index,
+ pan: "twine_cpan" + channel.index,
+ mute: "twine_cmute" + channel.index,
+ solo: twine.mixer.soloChannel
+ };
+
+
+ this.setName = function(name) {
+ channel.name = name;
+ elChannelControl.text(channel.name);
+ };
+
+ this.exportData = async function() {
+ var saveData = {
+ clips: [],
+ inserts: [],
+ name: channel.name,
+ amp: (await app.getControlChannel(channel.defaultChannels.amp)),
+ pan: (await app.getControlChannel(channel.defaultChannels.pan))
+ };
+
+ for (var ins in channel.inserts) {
+
+ }
+ for (var i in channel.clips) {
+ if (channel.clips[i]) {
+ saveData.clips.push(await channel.clips[i].exportData());
+ }
+ }
+ return saveData;
+ };
+
+ this.remove = function(noredraw) {
+ elChannel.remove();
+ console.log("remove channel");
+ for (let c in channel.clips) {
+ if (channel.clips[c]) channel.clips[c].destroy();
+ }
+ for (let c in timeline.channels) {
+ if (timeline.channels[c] == channel) {
+ timeline.channels.splice(c, 1);
+ }
+ }
+ if (!noredraw) timeline.drawGrid();
+ };
+
+ this.importData = async function(loadData, ftMap) {
+ await app.setControlChannel(channel.defaultChannels.amp, loadData.amp);
+ await app.setControlChannel(channel.defaultChannels.pan, loadData.pan);
+ channel.setName(loadData.name);
+ for (var i in channel.clips) {
+ channel.clips[i].remove();
+ delete channel.clips[i];
+ }
+
+ for (let cl of loadData.clips) {
+ if (cl.table[0]) {
+ cl.table[0] = ftMap[cl.table[0]];
+ }
+ if (cl.table[1]) {
+ cl.table[1] = ftMap[cl.table[1]];
+ }
+ var c = new Clip(twine);
+ c.importData(cl);
+ channel.addClip(c);
+ }
+ };
+
+ this.addClip = function(clip) {
+ channel.clips[clip.data.id] = clip;
+ clip.channel = channel;
+ elChannelClips.append(clip.element);
+ clip.redraw();
+ };
+
+ this.removeClip = function(clip) {
+ //clip.element.detach();
+ //clip.channel = null;
+ channel.clips[clip.data.id] = null;
+ //delete channel.clips[clip.data.id];
+ };
+
+ this.changeBeatEnd = function(original, newBeatEnd, noredraw) {
+ var ratio = original / newBeatEnd;
+ for (let s in splines) {
+ splines[s].spline.resize(ratio, noredraw);
+ }
+ };
+
+
+ this.getCsChannelName = function() {
+ return "mxchan" + channel.index;
+ };
+
+ var elAddInsert;
+ var elInsertsArea;
+ var insertID = 0;
+ function removeInsert(id, noCompile) {
+ var index;
+ for (let ci in channel.inserts) {
+ if (channel.inserts[ci].id == id) {
+ index = ci;
+ break;
+ }
+ }
+ if (index == null) return;
+ var i = channel.inserts[index];
+ i.element.remove();
+ i.transform.remove();
+ channel.inserts.splice(index, 1);
+ refreshInserts();
+ if (!noCompile) channel.compileInstr();
+ }
+
+
+ async function createDefaultSplines() {
+ var splineColour = getComputedStyle(document.body).getPropertyValue("--fgColor2");
+ var ampVal, panVal;
+ if (twine.offline) {
+ ampVal = 1;
+ panVal = 0;
+ } else {
+ ampVal = await app.getControlChannel(channel.defaultChannels.amp);
+ panVal = await app.getControlChannel(channel.defaultChannels.pan);
+ }
+ var def = [
+ {name: "default_amp", dfault: 1, constraints: [0, 2, ampVal, 0.00001], channel: channel.defaultChannels.amp},
+ {name: "default_pan", dfault: 0, constraints: [-1, 1, panVal, 0.00001], channel: channel.defaultChannels.pan}
+ ];
+
+ for (let d of def) {
+ splines[d.name] = {
+ element: $("<div />").addClass("twca" + channel.index).addClass("twine_spline").attr("id", "twca" + channel.index + d.name).hide().appendTo(elChannelSpline),
+ show: function() {
+ $(".twca" + channel.index).hide();
+ splines[d.name].element.show();
+ splines[d.name].spline.redraw();
+ },
+ hide: function() {
+ splines[d.name].element.hide();
+ },
+ channel: d.channel
+ };
+ }
+ for (let d of def) {
+ splines[d.name].spline = new SplineEdit(
+ splines[d.name].element, splineColour,
+ twine.timeline.getTotalBeatDuration,
+ d.constraints, d.name
+ )
+ }
+ }
+
+
+ function addInsert(definition, noCompile) {
+ var container = $("<div />").addClass("twine_channeldetails_insert").appendTo(elInsertsArea);
+ container.css("left", (channel.inserts.length * 500) + "px");
+ var id = insertID ++;
+ var uniqueID = parseInt(channel.index.toString() + id.toString());
+ var t = new twirl.transform.Transform({
+ uniqueID: uniqueID,
+ element: container,
+ definition: definition,
+ splineElement: elChannelSpline,
+ getRegionFunc: function() {
+ return [0, 1];
+ },
+ getDurationFunc: timeline.getTotalBeatDuration,
+ onClose: function() {
+ removeInsert(id);
+ },
+ onAutomationClick: function(state) {
+ if (state && channel.height == heights[0]) {
+ channel.expand(); // TODO: set selected thing in dropdown
+ }
+ },
+ unmanagedAutomation: true,
+ unmanagedModulation: true,
+ host: twine
+ });
+ channel.inserts.push({
+ transform: t,
+ element: container,
+ id: id
+ });
+
+ for (let i in t.parameters) {
+ let paramID = (channel.inserts.length - 1) + "_" + i;
+ let tp = t.parameters[i];
+ splines[paramID] = {
+ element: $("<div />").addClass("twca" + channel.index).addClass("twine_spline").attr("id", "twca" + channel.index + paramID).hide().appendTo(elChannelSpline),
+ show: function() {
+ $(".twca" + channel.index).hide();
+ splines[paramID].element.show();
+ splines[paramID].spline.redraw();
+ },
+ hide: function() {
+ splines[paramID].element.hide();
+ },
+ channel: tp.sendChannel
+ };
+ tp.createAutomationSpline(splines[paramID].element);
+ splines[paramID].spline = tp.automation;
+ }
+ refreshAutomationSelectors();
+ if (!noCompile) channel.compileInstr();
+ }
+
+ this.hasOverlap = function(clip, proposedBeat, proposedLength) {
+ if (!proposedBeat) proposedBeat = clip.data.position;
+ if (!proposedLength) proposedLength = clip.data.playLength;
+ var clipEnd;
+ var proposedEnd;
+ for (var i in channel.clips) {
+ var c = channel.clips[i];
+ if (c && c != clip) {
+ clipEnd = c.data.position + c.data.playLength;
+ proposedEnd = proposedBeat + proposedLength;
+ if ((proposedBeat < clipEnd && proposedEnd > c.data.position) || (c.data.position > proposedBeat && clipEnd < proposedEnd)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ function refreshInserts() {
+ elInsertsArea.empty();
+ for (let i in channel.inserts) {
+ var el = channel.inserts[i].element;
+ el.css("left", (i * 500) + "px");
+ elInsertsArea.append(el);
+ }
+ }
+
+ this.showDetails = function() {
+ if (!elAddInsert) {
+ elAddInsert = $("<div />").addClass("twine_channeldetails_insertnew");
+ elInsertsArea = $("<div />").addClass("twine_channeldetails_inserts");
+ var data = {};
+ for (var c of twirl.appdata.transforms) {
+ var catName = c.name;
+ for (var t of c.contents) {
+ if (t.twine) {
+ if (!data[c.name]) {
+ data[c.name] = {
+ name: c.name,
+ description: c.description,
+ contents: []
+ };
+ }
+ data[c.name].contents.push(t);
+ }
+ }
+ }
+ var ttv = new twirl.transform.TreeView({
+ element: elAddInsert,
+ items: Object.values(data),
+ click: addInsert
+ });
+ }
+ if (twine.timeline.selectedChannel != channel) {
+ twine.timeline.selectedChannel = channel;
+ $(".twine_channelcontrol").css("background-color", "var(--bgColor2)");
+ elChannelControl.css("background-color", "var(--bgColor1)");
+ $("#twine_channeldetails").append(elAddInsert).append(elInsertsArea).show();
+ }
+ twine.ui.showPane(twine.ui.pane.CHANNEL);
+ };
+
+ this.compileInstr = async function() {
+ if (twine.offline) return;
+ var instrName = "twine_channel" + channel.index;
+ var instr = "instr " + instrName + "\n"
+ + "aL, aR bus_read \"" + channel.getCsChannelName() + "\"\n";
+ for (let i of channel.inserts) {
+ instr += "chnset aL, \"twstfeedL\"\n"
+ + "chnset aR, \"twstfeedR\"\n"
+ + "aoutL, aoutR subinstr \"" + i.transform.instr + "\", " + i.transform.uniqueID + "\n"
+ + "aL, aR twst_setapplymode chnget:i(\"applymode" + i.transform.uniqueID + "\"), aL, aR, aoutL, aoutR\n"
+ }
+ instr += "kamp chnget \"" + channel.defaultChannels.amp + "\"\n" +
+ "kpan chnget \"" + channel.defaultChannels.pan + "\"\n" +
+ "kmute chnget \"" + channel.defaultChannels.mute + "\"\n" +
+ "ksolo chnget \"" + channel.defaultChannels.solo + "\"\n" +
+ "kaudible = (1 - kmute) * ((ksolo == -1 || ksolo == " + channel.index + ") ? 1 : 0)\n" +
+ "aL *= kamp * (1 - kpan) * kaudible\naR *= kamp * kpan * kaudible\n"
+ instr += "bus_mix \"twine_master\", aL, aR\n";
+ instr += "endin";
+ await app.compileOrc(instr);
+ };
+
+ this.automationChanged = function() {
+ var changed = false;
+ for (let i in splines) {
+ if (splines[i].spline && splines[i].spline.changed) {
+ console.log("automation changed");
+ return true;
+ }
+ }
+ return changed;
+ };
+
+ this.getAutomationData = function(start, end) {
+ var data = [];
+ for (let i in splines) {
+ var linsegData = splines[i].spline.getLinsegData(start, end, true);
+ if (linsegData) {
+ data.push("chnset linseg:k(" + linsegData + "), \"" + splines[i].channel + "\"");
+ }
+ }
+ return data;
+ };
+
+ this.refreshOffset = function() {
+ channel.offset = elChannelClips.offset();
+ };
+
+ this.redraw = function(noClipWaveRedraw) {
+ channel.width = parseFloat(elChannelClips.css("width"));
+ channel.refreshOffset();
+ refreshAutomationSelectors();
+ for (let c in channel.clips) {
+ if (channel.clips[c]) channel.clips[c].redraw(noClipWaveRedraw);
+ }
+
+ if (channel.height > heights[0]) {
+ for (var d in splines) {
+ console.log(splines[d]);
+ splines[d].spline.setRange(timeline.data.regionStart, timeline.data.regionEnd);
+ }
+ }
+ };
+
+ this.showAutomation = function(groupIndex, nameIndex) {
+ elAutomationSelectGroup.val(groupIndex).change();
+ elAutomationSelector.val(nameIndex).change();
+ };
+
+ var elAutomationSelectGroup;
+ var elAutomationSelector;
+ function refreshAutomationSelectors() {
+ if (channel.height <= heights[0]) {
+ if (elAutomationSelectGroup && elAutomationSelector) {
+ elAutomationSelectGroup.hide();
+ elAutomationSelector.hide();
+ }
+ return;
+ }
+
+ var valGroup = (elAutomationSelectGroup) ? elAutomationSelectGroup.val() : 0;
+ var valItem = (elAutomationSelector) ? elAutomationSelector.val() : 0;
+
+ var items = [
+ {name: "Mixer", items: [
+ {name: "Gain", onselect: function(){
+ splines.default_amp.show();
+ }},
+ {name: "Pan", onselect: function(){
+ splines.default_pan.show();
+ }}
+ ]}
+ ];
+
+ for (let i in channel.inserts) {
+ let ci = channel.inserts[i];
+ var obj = {name: ci.transform.name, items: []};
+ items.push(obj);
+ for (let it in ci.transform.parameters)
+ obj.items.push({
+ name: ci.transform.parameters[it].definition.name,
+ onselect: function() {
+ splines[i + "_" + it].show();
+ }
+ });
+ }
+
+ if (!elAutomationSelectGroup && !elAutomationSelector) {
+ var el = $("<div />").addClass("twine_automationselectors").appendTo(elChannelControl);
+ elAutomationSelectGroup = $("<select />").addClass("twine_automationselect").appendTo(el).on("change", changeAutomationGroup);
+ el.append("<br />");
+ elAutomationSelector = $("<select />").addClass("twine_automationselect").appendTo(el).on("change", changeAutomationItem);
+
+ for (let i in items) {
+ $("<option />").val(i).text(items[i].name).appendTo(elAutomationSelectGroup);
+ }
+ }
+
+ elAutomationSelectGroup.show();
+ elAutomationSelector.show();
+
+ function changeAutomationGroup() {
+ var val = $(this).val();
+ elAutomationSelector.empty();
+ for (let si in items[val].items) {
+ $("<option />").val(si).text(items[val].items[si].name).appendTo(elAutomationSelector);
+ }
+ elAutomationSelector.val(0).change();
+ }
+
+ function changeAutomationItem() {
+ var groupVal = elAutomationSelectGroup.val();
+ var val = $(this).val();
+ items[groupVal].items[val].onselect();
+ }
+
+ elAutomationSelectGroup.val(valGroup).change();
+ elAutomationSelector.val(valItem).change();
+ }
+
+ this.setHeight = function(h) {
+ if (h < heights[0]) h = heights[0];
+ channel.height = h;
+ elChannel.css("height", channel.height + "px");
+ if (h == heights[0]) {
+ elChannelSpline.hide();
+ } else {
+ elChannelSpline.show();
+ for (let i of channel.inserts) {
+ i.transform.redraw(timeline.data.regionStart, timeline.data.regionEnd);
+ }
+ }
+ channel.redraw();
+ };
+
+ this.expand = function() {
+ channel.setHeight(heights[1]);
+ };
+
+ this.contract = function() {
+ channel.setHeight(heights[0]);
+ };
+
+ (async function boot() {
+ channel.redraw();
+ if (!twine.offline) {
+ await app.setControlChannel(channel.defaultChannels.amp, 0.8);
+ await app.setControlChannel(channel.defaultChannels.pan, 0.5);
+ await app.setControlChannel(channel.defaultChannels.mute, 0);
+ await channel.compileInstr();
+ }
+ await createDefaultSplines();
+ })();
+};
\ No newline at end of file diff --git a/site/app/twine/clip.js b/site/app/twine/clip.js new file mode 100644 index 0000000..4705d95 --- /dev/null +++ b/site/app/twine/clip.js @@ -0,0 +1,769 @@ +var Clip = function(twine, data, parent) {
+ var clip = this;
+ var loaded = false;
+ var waveformClip;
+ var waveformEdit;
+ var datatable;
+ this.channel = null;
+ var minWidth = 10;
+ this.types = {AUDIO: 0, SCRIPT: 1};
+
+
+ if (!data) {
+ var id = twine.getNewID();
+ var data = {
+ name: "Clip " + id,
+ type: (parent) ? parent.type : null,
+ id: id,
+ clipindex: null,
+ playLength: 1,
+ pitch: 1,
+ colour: "#" + (Math.random() * 0xFFFFFF << 0).toString(16),
+ position: 0,
+ // debugs:
+ duration: 1,
+ warp: 0,
+ loop: 0,
+ script: ""
+ };
+ } else {
+ data.id = twine.getNewID();
+ loaded = true;
+ }
+
+ this.data = data;
+ Object.defineProperty(this, "colour", {
+ get: function() { return data.colour; },
+ set: function(x) {
+ data.colour = x;
+ clip.element.css("background-color", data.colour);
+ }
+ });
+
+ Object.defineProperty(this, "isAudio", {
+ get: function() { return (clip.data.type == clip.types.AUDIO); },
+ set: function(x) {}
+ });
+
+ twine.undo.add("add clip", function(){
+ clip.destroy();
+ twine.timeline.redraw();
+ });
+
+ this.exportData = async function() {
+ // tablecopyout messes first few values. so loop...
+ var len = await app.getCsound().tableLength(datatable);
+ var items = [];
+ for (var i = 0; i < len; i ++) {
+ items.push(await app.getCsound().tableGet(datatable, i));
+ }
+ var local = {};
+ for (var d in dataMode) {
+ if (dataMode[d] < 0) {
+ local[d] = data[d];
+ }
+ }
+ return {table: items, local: local};
+ };
+
+ this.importData = async function(loadData) {
+
+ if (datatable && clip.data.clipindex) {
+ await app.insertScoreAsync("twine_removeclip", [clip.data.clipindex]);
+ }
+ datatable = await twine.timeline.copyNewTableIn(loadData.table);
+ var ndata = await app.insertScoreAsync("twine_importclip", [datatable]);
+ for (var d in loadData.local) {
+ data[d] = loadData.local[d];
+ }
+ data.clipindex = ndata.data.clipindex;
+ await getDataFromTable();
+ console.log("import", loadData, data);
+ loaded = true;
+ clip.redraw(); // race here?
+ };
+
+ this.destroy = function(onComplete) {
+ function done() {
+ clip.element.remove();
+ clip.channel.removeClip(clip);
+ if (onComplete) {
+ onComplete();
+ }
+ }
+ if (clip.isAudio) {
+ app.insertScore("twine_removeclip", [0, 1, app.createCallback(done), clip.data.clipindex]);
+ } else {
+ done();
+ }
+ };
+
+ var dataMode = {
+ fnL: 0, fnR: 1, divisionsPerBeat: 2, duration: 3, beatsLength: 4, utilisedLength: 5,
+ warpMode: 6, pitch: 7, amp: 8, fftSize: 9, txtWinSize: 10, txtRandom: 11, txtOverlap: 12,
+ loop: 13, warp: 14, txtWinType: 15, utilisedStart: 16, phaseLock: 17, sr: 18,
+ // warp points are after this+ in table
+ position: -1, name: -2, clipindex: -3, playLength: -4, type: -5
+ };
+
+
+ this.element = $("<div />").addClass("twine_clip").css({
+ "background-color": data.colour
+ }).on("contextmenu", function(e){
+ return twirl.contextMenu.show(e, [
+ {name: "Delete", click: function(){
+ clip.destroy();
+ }},
+ {name: "Audition", click: function(){
+ clip.play();
+ }}
+ ]);
+ }).click(function(e){
+ if (e.ctrlKey) {
+ twine.timeline.selectedClips.push(clip);
+ } else {
+ $(".twine_clip").css("outline", "none");
+ twine.timeline.selectedClips = [clip];
+ }
+ var uiType;
+ var cui = twine.ui.clip;
+ clip.markSelected();
+ if (clip.isAudio) {
+ uiType = twine.ui.pane.CLIPAUDIO;
+ var items = [
+ "name", "colour", "amp", "warp", "warpMode", "pitch",
+ "fftSize", "txtWinSize", "txtRandom", "txtOverlap",
+ "txtWinType", "phaseLock"
+ // , "loop"
+ ];
+ for (let i of items) {
+ cui[i].setValue(data[i]);
+ }
+ showEditWaveform($("#twine_clipdetailsrightaudio"));
+ } else {
+ uiType = twine.ui.pane.CLIPSCRIPT;
+ cui.scriptEdit.setValue(data.script);
+ }
+ twine.ui.showPane(uiType);
+ });
+
+ var elWaveClip = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px"}).appendTo(clip.element);
+ var elWaveText = $("<div />").css({position: "absolute", width: "100%", height: "100%", top: "0px", left: "0px", "font-size": "var(--fontSizeSmall)", color: "var(--fgColor1)"}).text(data.name).appendTo(clip.element);
+
+ var elResizeLeft = $("<div />").addClass("twine_clip_edge_left").appendTo(clip.element);
+ var elResizeRight = $("<div />").addClass("twine_clip_edge_right").appendTo(clip.element);
+ var elMove = $("<div />").addClass("twine_clip_centre").appendTo(clip.element);
+ var elWaveEdit = $("<div />").css({width: "100%", height: "100%", top: "0px", left: "0px"});
+
+ async function getDataFromTable() {
+ if (!clip.isAudio) return;
+ async function setFromKey(key) {
+ if (dataMode[key] < 0) return;
+ var value = await app.getCsound().tableGet(datatable, dataMode[key])
+ data[key] = value;
+ }
+
+ for (var k in dataMode) {
+ await setFromKey(k);
+ }
+ }
+
+ function setClipAudioUnique(onComplete) {
+ if (!clip.isAudio) return onComplete();
+ twirl.loading.show();
+ var cbid = app.createCallback(async function(ndata){
+ await getDataFromTable();
+ twirl.loading.hide();
+ if (onComplete) onComplete();
+ });
+ app.insertScore("twine_setclipaudiounique", [0, 1, cbid]);
+ }
+
+ function getScriptInstrName() {
+ return "twinescript" + id;
+ }
+
+ this.setScript = function(script, onready) {
+ var originalScript = clip.data.script;
+ if (script) {
+ clip.data.script = script;
+ }
+ var instr = "instr " + getScriptInstrName() + "\n" +
+ "iduration = p5\nichannel = p6\n" +
+ clip.data.script + "\nendin";
+ app.compileOrc(instr).then(function(status){
+ if (status >= 0 && onready) { // errors will be caught by app and shown
+ twine.undo.add("set script", function(){
+ clip.data.script = originalScript;
+ if (twine.timeline.selectedClip == clip) {
+ cui.scriptEdit.setValue(data.script);
+ }
+ });
+ onready();
+ }
+ });
+ };
+
+ this.initScript = function() {
+ data.warp = 1;
+ data.duration = 1;
+ clip.data.playLength = 4;
+ clip.data.type = clip.types.SCRIPT;
+ clip.data.script = "; your Csound instrument here";
+ loaded = true;
+ };
+
+ function reloadAfterEdit(tables) {
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ datatable = ndata.datatable;
+ await getDataFromTable();
+ clip.redraw();
+ twine.setVisible(true);
+ twigs.setVisible(false);
+ twist.setVisible(false);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid, data.clipindex];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_clipreplacetables", call);
+ }
+
+ this.editInTwist = function(asUnique) {
+ if (!window.twist) return twirl.prompt.show("twist is unavailable in this session");
+ function edit() {
+ twist.boot(twine);
+ twist.bootAudio(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twist.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twist.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+
+ function checksr() { // twist uses tfi transforms that may require sample sr to be running sr..
+ if (twine.sr != data.sr) {
+ twirl.loading.show();
+ var cbid = app.createCallback(async function(ndata){
+ await getDataFromTable();
+ twirl.loading.hide();
+ edit();
+ });
+ app.insertScore("twine_convertsr", [0, 1, cbid, data.clipindex, twine.sr]);
+ } else {
+ edit();
+ }
+ }
+ if (asUnique) {
+ setClipAudioUnique(checksr);
+ } else {
+ checksr();
+ }
+
+ };
+
+ this.editInTwigs = function(asUnique) {
+ if (!window.twigs) return twirl.prompt.show("twigs is unavailable in this session");
+ function edit() {
+ twigs.boot(twine);
+ var tables = [data.fnL];
+ if (data.fnR) tables.push(data.fnR);
+ twigs.loadFileFromFtable(data.name, tables, function(ndata){
+ if (ndata.status > 0) {
+ twine.setVisible(false);
+ twigs.setVisible(true);
+ }
+ }, reloadAfterEdit);
+ }
+ if (asUnique) {
+ setClipAudioUnique(edit);
+ } else {
+ edit();
+ }
+ };
+
+ this.setData = function(modeString, v, onComplete) {
+ data[modeString] = v;
+ if (dataMode[modeString] < 0) {
+ if (modeString == "name") {
+ elWaveText.text(data.name);
+ setClipWaveform();
+ }
+ return;
+ }
+
+ if (!twine.offline || !clip.isAudio) app.getCsound().tableSet(datatable, dataMode[modeString], v);
+
+ if (onComplete) onComplete();
+ };
+
+ var playbackcbid;
+ this.play = function(onCallback) {
+ var instr;
+ var args;
+ var channel = clip.channel.getCsChannelName();
+ var cbid = app.createCallback(function(ndata) {
+ if (ndata.status == 0) {
+ app.removeCallback(ndata.cbid);
+ playbackcbid = null;
+ } else {
+ playbackcbid = ndata.cbid;
+ }
+ if (onCallback) {
+ onCallback(ndata);
+ }
+ }, true);
+ if (clip.isAudio) {
+ instr = "ecp_playaudition";
+ args = [0, data.playLength, cbid, data.clipindex, data.playLength, channel];
+ } else {
+ instr = getScriptInstrName();
+ args = [0, data.playLength, cbid, data.playLength, channel];
+ }
+ app.insertScore(instr, args);
+ };
+
+ this.stop = function(onCallback) {
+ if (!playbackcbid) return;
+ app.insertScore("ecp_stopaudition", [0, 1, playbackcbid]);
+ };
+
+ async function getSourceTableData() {
+ if (!clip.isAudio) return;
+ var wavedata = [];
+ var tbL = await app.getTable(data.fnL);
+ wavedata.push(tbL);
+ if (data.hasOwnProperty("fnR") && data.fnR > 0) {
+ var tbR = await app.getTable(data.fnR);
+ wavedata.push(tbR);
+ }
+ return wavedata;
+ }
+
+ async function setClipWaveform(noRedraw) {
+ if (twine.offline || !clip.isAudio || !twine.storage.showClipWaveforms) return;
+ if (!waveformClip) {
+ waveformClip = new Waveform({
+ target: elWaveClip,
+ allowSelect: false,
+ showGrid: false,
+ bgColor: "rgb(255, 255, 255, 0)",
+ fgColor: "#000000"
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformClip.setData(sourceTables, data.duration);
+ }, 100);
+ } else if (!noRedraw) {
+ console.log("redraw wave");
+ waveformClip.redraw();
+ }
+ }
+
+ async function showEditWaveform(target) {
+ if (twine.offline || !clip.isAudio) return;
+ target.empty().append(elWaveEdit);
+ if (!waveformEdit) {
+ waveformEdit = new Waveform({
+ target: elWaveEdit,
+ allowSelect: true,
+ showGrid: true,
+ latencyCorrection: twirl.latencyCorrection // , markers:
+ });
+ setTimeout(async function(){
+ var sourceTables = await getSourceTableData();
+ waveformEdit.setData(sourceTables, data.duration);
+ }, 100);
+ } else {
+ waveformEdit.redraw();
+ }
+ }
+
+ this.setWarp = function(v) {
+ clip.setData("warp", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setLoop = function(v) {
+ clip.setData("loop", v);
+ if (!data.warp && !data.loop && data.playLength > data.duration) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setPitch = function(semitones) {
+ var pitchRatio = Math.pow(2, (semitones / 12));
+ clip.setData("pitch", semitones);
+ if (data.warpMode == 0 && data.loop == 0 && data.warp == 0) {
+ data.playLength = data.duration / pitchRatio;
+ clip.setSize();
+ }
+ };
+
+ this.setWarpMode = function(v) {
+ var prevMode = data.warpMode;
+ clip.setData("warpMode", v);
+ if (prevMode == 0 && data.warpMode != 0 && !data.loop && !data.warp) {
+ data.playLength = data.duration;
+ clip.setSize();
+ }
+ };
+
+ this.setSize = function(noWaveRedraw) {
+ var width = data.playLength * twine.timeline.pixelsPerBeat;
+ clip.element.css("width", width + "px");
+ setClipWaveform(noWaveRedraw);
+ }
+
+ this.redraw = function(noWaveRedraw) {
+ if (!loaded) return;
+ var b = twine.timeline.beatRegion;
+ clip.setSize(noWaveRedraw);
+ var endPos = data.position + data.playLength;
+ if (endPos < b[0] || data.position > b[1]) {
+ return clip.element.hide();
+ }
+
+ var css = {
+ height: clip.channel.height + "px",
+ left: (data.position - b[0]) * twine.timeline.pixelsPerBeat + "px"
+ };
+ elWaveText.text(data.name);
+ clip.element.show().css(css);
+ if (endPos > twine.timeline.beatRegion[1] - 8) {
+ var extension = endPos + 8;
+ twine.timeline.extend(twine.timeline.beatRegion[1] + extension);
+ }
+ };
+
+ this.clone = async function() {
+ var newData = Object.assign({}, data);
+ newData.id = twine.getNewID();
+ var c = new Clip(twine, newData, clip);
+ clip.channel.addClip(c);
+ if (!twine.offline && clip.isAudio) {
+ var ndata = await app.insertScoreAsync("twine_cloneclip", [clip.data.clipindex]);
+ await c.loadFromDataTable(ndata.datatable, ndata.clipindex);
+
+ } else {
+ loaded = true;
+ c.setScript();
+ c.redraw();
+ }
+ return c;
+ };
+
+
+ async function loadData(ndata, name, colour, defaultLength) {
+ twirl.loading.show("Loading");
+ if (ndata.status == -1) {
+ return twirl.errorHandler("File not valid");
+ } else if (ndata.status == -2) {
+ return twirl.errorHandler("File too large");
+ }
+ datatable = ndata.data.datatable;
+ await getDataFromTable();
+ data.clipindex = ndata.data.clipindex;
+ if (name) {
+ data.name = name;
+ }
+ setTimeout(function(){
+ if (defaultLength) {
+ data.playLength = data.duration / (60 / twine.timeline.data.bpm);
+ console.log("deflength", data.playLength);
+ }
+ if (!colour) colour = twine.randomColour();
+ data.colour = colour;
+ loaded = true;
+ clip.redraw();
+ }, 50); // csound race
+ };
+
+ this.loadFromDataTable = async function(newDatatable, clipindex) {
+ datatable = newDatatable;
+ await getDataFromTable();
+ data.clipindex = clipindex;
+ clip.data.type = clip.types.AUDIO;
+ loaded = true;
+ setTimeout(clip.redraw, 20);
+ //clip.redraw();
+ };
+
+ this.loadFromFtables = function(name, tables, colour) {
+ clip.data.type = clip.types.AUDIO;
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, name, colour);
+ twirl.loading.hide();
+ });
+ var call = [0, 1, cbid];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twine_loadftables", call);
+ };
+
+ this.loadFromPath = function(path, colour) {
+ clip.data.type = clip.types.AUDIO;
+ if (twine.offline) {
+ loaded = true;
+ clip.redraw();
+ return;
+ }
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, path, colour, true);
+ twirl.loading.hide();
+ });
+ app.insertScore("twine_loadpath", [0, 1, cbid, path]);
+ };
+
+ this.createSilence = function(stereo, duration, name, colour) {
+ clip.data.type = clip.types.AUDIO;
+ twirl.loading.show("Creating");
+ var cbid = app.createCallback(async function(ndata){
+ await loadData(ndata, name, colour);
+ twirl.loading.hide();
+ });
+ app.insertScore("twine_createblankclip", [0, 1, cbid, stereo, duration]);
+ };
+
+ function getMaxClipWidth() {
+ var maxWidth = 9999;
+ if (!data.warp && !data.loop) {
+ maxWidth = data.duration * twine.timeline.pixelsPerBeat;
+ }
+ return maxWidth;
+ }
+
+ this.markSelected = function (unselected) {
+ if (unselected) {
+ clip.element.css("outline", "none");
+ } else {
+ clip.element.css("outline", "1px dashed white");
+ }
+ };
+
+ clip.movement = {
+ startX: 0, startY: 0, startXabs: 0, startYabs: 0, clipWidth: 0,
+ clipLeft: 0, clipTop: 0, lastLeft: 0, isCopying: false, lastYabs: 0, extendHold: false, doClipRedraw: false, originalClipData: null, mouseMoveInnerFunc: null, clonedClips: null, masterClip: null, moved: false, channel: null,
+ mouseDown: function(e, dragType) {
+ e.preventDefault();
+ e.stopPropagation();
+ var cm = clip.movement;
+ cm.moved = false;
+ cm.originalClipData = [];
+ cm.clonedClips = [];
+ cm.mouseMoveInnerFunc = function(e) {
+ clip.movement.doDragInner(e, dragType);
+ };
+ for (let c of twine.timeline.selectedClips) {
+ cm.originalClipData.push({
+ clip: c,
+ position: c.data.position,
+ playLength: c.data.playLength
+ });
+ c.movement.mouseDownInner(e, dragType);
+ }
+ $("html").on("mouseup", cm.endDragMaster);
+ },
+ mouseDownInner: function(e, dragType) {
+ var cm = clip.movement;
+ $("html").on("mousemove", cm.mouseMoveInnerFunc).on("mouseup", cm.endDrag);
+ cm.masterClip = clip; // for cloning
+ cm.channel = clip.channel;
+ cm.originalPlaylength = data.playlength;
+ cm.originalPosition = data.position;
+ cm.isCopying = false;
+ cm.clipWidth = parseFloat(clip.element.css("width"));
+ cm.clipTop = parseFloat(clip.element.css("top"));
+ cm.clipLeft = parseFloat(clip.element.css("left"));
+ cm.startXabs = e.clientX;
+ cm.startYabs = e.clientY;
+ cm.startX = cm.startXabs - e.target.getBoundingClientRect().left;
+ cm.startY = cm.startYabs - e.target.getBoundingClientRect().top;
+ cm.lastLeft = (e.clientX - cm.startX - clip.channel.offset.left);
+ cm.lastYabs = cm.startYabs;
+ //$("#container").css("cursor", "e-resize");
+ },
+ endDragMaster: function(e) {
+ var cm = clip.movement;
+ $("html").off("mouseup", cm.endDragMaster);
+ if (!cm.moved) return;
+ var clipData = [...cm.originalClipData];
+ var clonedClips = [...cm.clonedClips];
+ console.log("add move undo");
+ twine.undo.add("move/resize clip", function(){
+ clipData.forEach(function(d){
+ d.clip.data.position = d.position;
+ d.clip.data.playLength = d.playLength;
+ d.clip.redraw();
+ });
+ clonedClips.forEach(function(c){
+ c.destroy();
+ });
+ });
+ },
+ endDrag: function(e) {
+ e.preventDefault();
+ var cm = clip.movement;
+ cm.isCopying = false;
+ $("html").off("mouseup", cm.endDrag).off("mousemove", cm.mouseMoveInnerFunc);
+ $("#container").css("cursor", "pointer");
+ if (cm.doClipRedraw) {
+ setClipWaveform();
+ }
+ },
+ doDrag: function(e, dragType) {
+ e.preventDefault();
+ //$("html").off("mouseup", this.initialMouseUp);
+ twine.timeline.selectedClips.forEach(function(c){
+ c.movement.doDragInner(e, dragType);
+ });
+ },
+ setExtendHold: function() {
+ var cm = clip.movement;
+ cm.extendHold = true;
+ setTimeout(function() {
+ cm.extendHold = false;
+ }, 250);
+ },
+ doDragInner: async function (e, dragType) {
+ var cm = clip.movement;
+ if (dragType == "right") {
+ var maxWidth = getMaxClipWidth();
+ var xMovement = e.clientX - cm.startXabs;
+ var newWidth = xMovement + cm.clipWidth;
+ newWidth = twine.timeline.roundToGrid(newWidth);
+ if (newWidth > maxWidth) newWidth = maxWidth;
+ if (newWidth < minWidth) newWidth = minWidth;
+ if (newWidth != parseFloat(clip.element.css("width"))) {
+ cm.moved = true;
+ cm.doClipRedraw = true;
+ }
+ var playLength = newWidth / twine.timeline.pixelsPerBeat;
+ if (!cm.masterClip.channel.hasOverlap(cm.masterClip, null, playLength)) {
+ data.playLength = playLength;
+ clip.element.css("width", newWidth + "px");
+ }
+ } else if (dragType == "left") {
+ var maxWidth = getMaxClipWidth();
+ var xMovement = e.clientX - cm.startXabs;
+ var left = cm.clipLeft + xMovement;
+ //var left = (e.clientX - cm.startX - clip.channel.offset.left);
+ left = twine.timeline.roundToGrid(left);
+ if (left < 0) left = 0;
+ var newWidth = (cm.clipWidth - left) + cm.clipLeft;
+ var cWidth, cLeft;
+ if (newWidth < minWidth) {
+ cWidth = minWidth, cm.clipLeft + minWidth; //(minWidth - left) + clipLeft;
+ } else if (newWidth > maxWidth) {
+ cWidth = maxWidth, cLeft = cm.lastLeft;
+ } else {
+ lastLeft = left;
+ cWidth = newWidth, cLeft = left;
+ }
+ if (cWidth != parseFloat(clip.element.css("width"))) {
+ cm.moved = true;
+ cm.doClipRedraw = true;
+ }
+ var position = Math.min(0, (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0]);
+ var playLength = newWidth / twine.timeline.pixelsPerBeat;
+ if (!cm.masterClip.channel.hasOverlap(cm.masterClip, position, playLength)) {
+ data.position = position;
+ data.playLength = playLength
+ clip.element.css({width: cWidth + "px", left: cLeft + "px"});
+ }
+ } else {
+ if (cm.extendHold) return;
+ if (e.ctrlKey && !cm.isCopying) {
+ cm.isCopying = true;
+ cm.masterClip = await clip.clone();
+ }
+ var xMovement = e.clientX - cm.startXabs;
+ var left = xMovement + cm.clipLeft;
+ left = twine.timeline.roundToGrid(left);
+
+ var yMovement = e.clientY - cm.lastYabs;
+ var top = (e.clientY - cm.lastYabs) + cm.clipTop;
+ //console.log(top);
+ var ttop = (e.clientY - cm.startY) + cm.clipTop;
+ var tshift = ttop / cm.channel.height; //cm.masterClip.channel.height;
+ tshift = (tshift > 0) ? Math.floor(tshift) : Math.ceil(tshift);
+ console.log(tshift);
+
+ var channelShift = top / cm.masterClip.channel.height;
+ channelShift = (channelShift > 0) ? Math.floor(channelShift) : Math.ceil(channelShift);
+
+ if (channelShift != 0 || left != parseFloat(clip.element.css("left"))) {
+ cm.moved = true;
+ }
+ if (channelShift != 0) {
+ cm.lastYabs = e.clientY;
+ var newChannel = cm.masterClip.channel.index + channelShift;
+ if (newChannel < twine.timeline.channels.length && newChannel >= 0) {
+ if (!twine.timeline.channels[newChannel].hasOverlap(cm.masterClip)) {
+ cm.masterClip.channel.removeClip(cm.masterClip);
+ twine.timeline.channels[newChannel].addClip(cm.masterClip);
+ }
+ }
+ }
+
+ var doRedraw = false;
+ var extension = cm.masterClip.data.playLength + 8;
+ var newBeats;
+ var d = twine.timeline.data;
+ if (left < 0) {
+ cm.setExtendHold();
+ extension = -extension;
+ left = 0;
+ newBeats = twine.timeline.beatRegion[1];
+ doRedraw = true;
+ }
+
+ var position = (left / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0];
+
+ if (!cm.masterClip.channel.hasOverlap(cm.masterClip, position)) {
+ data.position = position;
+ cm.masterClip.element.css("left", left + "px");
+ }
+
+ if (left + cm.clipWidth > cm.masterClip.channel.width) {
+ cm.setExtendHold();
+ doRedraw = true;
+ newBeats = twine.timeline.beatRegion[1] + extension;
+ twine.timeline.extend(newBeats, true);
+ }
+
+ if (doRedraw) {
+ var extensionRatio = (extension / newBeats);
+ var newStart = d.regionStart + ((d.regionEnd - d.regionStart) * (extensionRatio));
+ var newEnd = d.regionEnd + extensionRatio;
+ newStart = Math.max(0, newStart);
+ newEnd = Math.max(0, newEnd);
+ twine.timeline.setRegion(newStart, newEnd, true);
+ }
+ } // move type
+ } // end doDragInner
+ };
+
+ elMove.mousedown(function(e){
+ clip.movement.mouseDown(e, "mid");
+ });
+ elResizeRight.mousedown(function(e){
+ clip.movement.mouseDown(e, "right");
+ });
+ elResizeLeft.mousedown(function(e){
+ clip.movement.mouseDown(e, "left");
+ });
+
+};
\ No newline at end of file diff --git a/site/app/twine/flac fucking.js b/site/app/twine/flac fucking.js new file mode 100644 index 0000000..dcac896 --- /dev/null +++ b/site/app/twine/flac fucking.js @@ -0,0 +1,65 @@ +var encoded = [];
+var encodedLength = 0;
+
+function encWriteCallback(buffer, bytes, samples, currentFrame) {
+encoded.push(buffer);
+encodedLength += bytes;
+}
+
+var source = await app.getCsound().getTable(113);
+var encoder = Flac.create_libflac_encoder(48000, 1, 16, 5, source.length, false);
+var init = Flac.init_encoder_stream(encoder, encWriteCallback, null, false, 0);
+var response = Flac.FLAC__stream_encoder_process(encoder, source, source.length);
+Flac.FLAC__stream_encoder_finish(encoder);
+Flac.FLAC__stream_encoder_delete(encoder);
+
+let merged = new Uint8Array(encodedLength);
+let offset = 0;
+encoded.forEach(item => {
+merged.set(item, offset);
+offset += item.length;
+});
+encoded = merged;
+
+
+//var encodedArr = new Uint8Array(encoded);
+var size = encoded.length;
+var decoded = [];
+var currentDataOffset = 0;
+function decReadCallback(bufferSize) {
+var end = currentDataOffset == size ? -1 : Math.min(currentDataOffset + bufferSize, size);
+var _buffer;
+var bytesRead;
+if (end !== -1) {
+//_buffer = encodedArr.subarray(currentDataOffset, end);
+_buffer = encoded.slice(currentDataOffset, end);
+bytesRead = end - currentDataOffset;
+currentDataOffset = end;
+} else {
+bytesRead = 0;
+}
+return {buffer: _buffer, readDataLength: bytesRead, error: false};
+}
+
+function decWriteCallback(buffer, _frameHdr) {
+decoded.push(buffer);
+}
+
+function decErrorCallback(err, errMsg) {
+console.log(err, errMsg);
+}
+
+var decoder = Flac.create_libflac_decoder(false);
+var init = Flac.init_decoder_stream(decoder, decReadCallback, decWriteCallback, decErrorCallback, null, false);
+Flac.setOptions(decoder, {analyseSubframes: false, analyseResiduals: false, enableRawStreamMetadata: false});
+var response = Flac.FLAC__stream_decoder_process_until_end_of_stream(decoder);
+
+/*
+var state = 0;
+var response = true;
+while (state <= 3 && response != false) {
+response &= Flac.FLAC__stream_decoder_process_single(decoder);
+state = Flac.FLAC__stream_decoder_get_state(decoder);
+}
+*/
+Flac.FLAC__stream_decoder_finish(decoder);
\ No newline at end of file diff --git a/site/app/twine/index.html b/site/app/twine/index.html new file mode 100644 index 0000000..1a8f4f9 --- /dev/null +++ b/site/app/twine/index.html @@ -0,0 +1,209 @@ +<html>
+<head>
+<title>twine</title>
+<link rel="stylesheet" href="../twirl/theme.css">
+<link rel="stylesheet" href="../twirl/twirl.css">
+<link rel="stylesheet" href="../twigs/twigs.css">
+<link rel="stylesheet" href="../twist/twist.css">
+<link rel="stylesheet" href="twine.css">
+<script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+<script type="text/javascript" src="https://apps.csound.1bpm.net/code/d3.v7.min.js"></script>
+<script type="text/javascript" src="https://apps.csound.1bpm.net/code/input-knobs.js"></script>
+<!--<script type="text/javascript" src="libflac.min.js"></script>-->
+<script type="text/javascript" src="../base/base.js"></script>
+<script type="text/javascript" src="../base/controls.js"></script>
+<script type="text/javascript" src="../twirl/twirl.js"></script>
+<script type="text/javascript" src="../twirl/appdata.js"></script>
+<script type="text/javascript" src="../twirl/transform.js"></script>
+<script type="text/javascript" src="../twirl/stdui.js"></script>
+<script type="text/javascript" src="../base/waveform.js"></script>
+<script type="text/javascript" src="../base/spline-edit.js"></script>
+<script type="text/javascript" src="../base/analyser.js"></script>
+<script type="text/javascript" src="../twist/twist_ui.js"></script>
+<script type="text/javascript" src="../twist/twist.js"></script>
+<script type="text/javascript" src="../twigs/twigs_ui.js"></script>
+<script type="text/javascript" src="../twigs/twigs.js"></script>
+<script type="text/javascript" src="twine_ui.js"></script>
+<script type="text/javascript" src="timeline.js"></script>
+<script type="text/javascript" src="channel.js"></script>
+<script type="text/javascript" src="clip.js"></script>
+<script type="text/javascript" src="mixer.js"></script>
+<script type="text/javascript" src="twine.js"></script>
+<script type="text/javascript">
+ $(twine_start);
+</script>
+</head>
+<body>
+<div id="twine">
+ <div id="twine_header">
+ <table id="twine_headertable"><tbody><tr>
+ <td id="twine_head_play"></td>
+ <td id="twine_head_snap"></td>
+ <td id="twine_head_showgrid"></td>
+ <td id="twine_head_name"></td>
+ </tr></tbody></table>
+ </div>
+ <div id="twine_menubar"></div>
+ <div id="twine_main">
+ <div id="twine_timeline"></div>
+ <div id="twine_details">
+ <div id="twine_mixer"></div>
+ <div id="twine_channeldetails"></div>
+ <div id="twine_clipdetails">
+ <div id="twine_clipdetailsaudio">
+ <div class="twine_clipdetailsleft">
+ <table><tbody>
+ <tr>
+ <td id="twine_clip_audition"></td>
+ <td></td>
+ <td></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td id="twine_clip_colour"></td>
+ <td id="twine_clip_name"></td>
+ <td id="twine_clip_edittwist"></td>
+ <td id="twine_clip_edittwigs"></td>
+ </tr>
+ </tbody></table>
+ <table><tbody>
+ <tr>
+ <td>Read type</td>
+ <td id="twine_clip_warpmode"></td>
+ <td id="twine_clip_warp"></td>
+ <td id="twine_clip_loop"></td>
+ </tr>
+ </tbody></table>
+ <table><tbody id="twine_clipparamsbottom">
+ </tbody></table>
+ </div>
+ <div id="twine_clipdetailsrightaudio" class="twine_clipdetailsright"></div>
+ </div>
+ <div id="twine_clipdetailsscript">
+ <div class="twine_clipdetailsleft">
+ <table><tbody>
+ <tr>
+ <td id="twine_clip_scriptaudition"></td>
+ </tr>
+ <tr>
+ <td id="twine_clip_scriptapply"></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="twine_clip_scriptedit" class="twine_clipdetailsright">
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+
+
+<div id="twigs">
+ <div id="twigs_hidden_links">
+ <a id="twigs_contact" href="https://csound.1bpm.net/contact/?type=general&app=twigs" target="_blank">Contact</a>
+ <a id="twigs_reportbug" href="https://csound.1bpm.net/contact/?type=report_bug&app=twigs" target="_blank">Report bug</a>
+ <a id="twigs_documentation" href="documentation.html" target="_blank">Documentation</a>
+ </div>
+ <div id="twigs_menubar"></div>
+ <div id="twigs_main">
+ <div id="twigs_sidebar"></div>
+ <div id="twigs_options"></div>
+ <div id="twigs_editor">
+ <div id="twigs_editor_inner">
+ <div id="twigs_playhead"></div>
+ <div id="twigs_selection"></div>
+ </div>
+ <div id="twigs_editor_hscrollouter">
+ <div id="twigs_editor_hscrollinner"></div>
+ </div>
+ <div id="twigs_editor_vscrollouter">
+ <div id="twigs_editor_vscrollinner"></div>
+ </div>
+ <div id="twigs_editor_vzoom"></div>
+ <div id="twigs_editor_hzoom"></div>
+ </div>
+ </div>
+</div>
+
+
+<div id="twist">
+ <div id="twist_menubar"></div>
+ <div id="twist_main">
+ <div id="twist_views">
+ <div id="twist_analyser"></div>
+ <div id="twist_waveforms"></div>
+ <div id="twist_splines"></div>
+ </div>
+ <div id="twist_sidepane">
+ <div id="twist_panetree"></div>
+ </div>
+ <div id="twist_controls">
+ <div id="twist_wavecontrols">
+ <table><tbody><tr id="twist_waveform_tabs"></tr><tbody></table>
+ <table><tbody><tr id="twist_wavecontrols_inner"></tr><tbody></table>
+ </div>
+ <div id="twist_controls_inner"></div>
+ </div>
+ </div>
+ <div id="twist_welcome">
+ <h4>Hello</h4>
+ Hover over icons and parameter names to see what they do. Transforms can be selected
+ from the menu on the left; the current file can have the transform auditioned (previewed) or committed (applied). Check out the help and settings for further tips and customisation.<br />
+ At the moment, there is a limitation on files to around five minutes in duration.
+ <hr />
+ </div>
+ <div id="twist_script" class="fullscreen_overlay">
+ <h3>Scripting</h3>
+ Scripts can be an individual JSON object or an array of objects in which case they will be committed sequentially. Only single transform scripts can be auditioned.
+ <hr />
+ <textarea id="twist_scriptsource" class="twist_devcode"></textarea>
+ <br />
+ <button id="twist_scriptstop">Stop</button>
+ <button id="twist_scriptaudition" class="twist_scriptbutton">Audition</button>
+ <button id="twist_scriptcommit" class="twist_scriptbutton">Commit</button>
+ <button id="twist_scriptloadlast" class="twist_scriptbutton">Load last</button>
+ <button id="twist_scriptloadall" class="twist_scriptbutton">Load all</button>
+ <button id="twist_scriptcancel" class="twist_scriptbutton">Cancel</button>
+ </div>
+ <div id="twist_developer" class="fullscreen_overlay">
+ <h3>Developer console</h3>
+ Code for transforms can be tested here. The code and definition should follow the guidance and API documentation <a id="twist_developer_documentation" href="developer_documentation.html" target="_blank">provided here.</a> The JSON definition should be a single transform as a JSON object, but mutiple transforms may be loaded individually.<br />
+ Contributions of transforms are warmly welcomed and <a id="twist_developer_submit" href="https://csound.1bpm.net/contact/?type=twist_submit" target="_blank">can be submitted here.</a>
+ <h4>Csound code</h4>
+ <textarea class="twist_devcode" id="twist_devcsound"></textarea>
+ <br /><button id="twist_inject_devcsound">Load Csound orchestra code</button>
+ <hr />
+ <h4>JSON transform definition</h4>
+ <textarea class="twist_devcode" id="twist_devjson"></textarea>
+ <br /><button id="twist_inject_devjson">Load JSON</button>
+ <hr />
+ <button id="twist_exit_devcode">Exit</button>
+ </div>
+ <div id="twist_crash">
+ <h2>twist has crashed.</h2>
+ We are working hard on ironing out all the bugs, but some still occur. To help, details of the last transform you attempted to audition or commit have been sent to the developers.
+ <a href=".">Press here to reload the application.</a>
+ <hr />
+ <div id="twist_crash_recovery">Attempting to recover your work...</div>
+ </div>
+ <div id="twist_hidden_links">
+ <a id="twist_contact" href="https://csound.1bpm.net/contact/?type=general&app=twist" target="_blank">Contact</a>
+ <a id="twist_reportbug" href="https://csound.1bpm.net/contact/?type=report_bug&app=twist" target="_blank">Report bug</a>
+ <a id="twist_documentation" href="documentation.html" target="_blank">Documentation</a>
+ </div>
+</div>
+
+
+
+<div id="twine_start">
+ <div id="twine_startinner">
+ <h1>twine</h1>
+ <p>audio arranger</p>
+ <div id="twine_startbig">Press to begin</div>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twine/libflac.min.js b/site/app/twine/libflac.min.js new file mode 100644 index 0000000..436767e --- /dev/null +++ b/site/app/twine/libflac.min.js @@ -0,0 +1,23 @@ +var Module=typeof Module!=="undefined"?Module:{};(function(root,factory){if(typeof define==="function"&&define.amd){define(["module","require"],factory.bind(null,root))}else if(typeof module==="object"&&module.exports){var env=typeof process!=="undefined"&&process&&process.env?process.env:root;factory(env,module,module.require)}else{root.Flac=factory(root)}})(typeof self!=="undefined"?self:typeof window!=="undefined"?window:this,function(global,expLib,require){null;var Module=Module||{};var _flac_ready=false;Module["onRuntimeInitialized"]=function(){_flac_ready=true;if(!_exported){setTimeout(function(){do_fire_event("ready",[{type:"ready",target:_exported}],true)},0)}else{do_fire_event("ready",[{type:"ready",target:_exported}],true)}};if(global&&global.FLAC_SCRIPT_LOCATION){Module["locateFile"]=function(fileName){var path=global.FLAC_SCRIPT_LOCATION||"";if(path[fileName]){return path[fileName]}path+=path&&!/\/$/.test(path)?"/":"";return path+fileName};var readBinary=function(filePath){if(ENVIRONMENT_IS_NODE){var ret=read_(filePath,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret}return new Promise(function(resolve,reject){var xhr=new XMLHttpRequest;xhr.responseType="arraybuffer";xhr.addEventListener("load",function(evt){resolve(xhr.response)});xhr.addEventListener("error",function(err){reject(err)});xhr.open("GET",filePath);xhr.send()})}}if(global&&typeof global.fetch==="function"){var _fetch=global.fetch;global.fetch=function(url){return _fetch.apply(null,arguments).catch(function(err){try{var result=readBinary(url);if(result&&result.catch){result.catch(function(_err){throw err})}return result}catch(_err){throw err}})}}var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];function convertJsFunctionToWasm(func,sig){return func}var freeTableIndexes=[];var functionsInTableMap;function addFunctionWasm(func,sig){var table=wasmTable;if(!functionsInTableMap){functionsInTableMap=new WeakMap;for(var i=0;i<table.length;i++){var item=table.get(i);if(item){functionsInTableMap.set(item,i)}}}if(functionsInTableMap.has(func)){return functionsInTableMap.get(func)}var ret;if(freeTableIndexes.length){ret=freeTableIndexes.pop()}else{ret=table.length;try{table.grow(1)}catch(err){if(!(err instanceof RangeError)){throw err}throw"Unable to grow wasm table. Set ALLOW_TABLE_GROWTH."}}try{table.set(ret,func)}catch(err){if(!(err instanceof TypeError)){throw err}var wrapped=convertJsFunctionToWasm(func,sig);table.set(ret,wrapped)}functionsInTableMap.set(func,ret);return ret}function addFunction(func,sig){return addFunctionWasm(func,sig)}var GLOBAL_BASE=1024;var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];var WebAssembly={Memory:function(opts){this.buffer=new ArrayBuffer(opts["initial"]*65536);this.grow=function(amount){var ret=__growWasmMemory(amount);return ret}},Table:function(opts){var ret=new Array(opts["initial"]);ret.grow=function(by){if(ret.length>=22+5){abort("Unable to grow wasm table. Use a higher value for RESERVED_FUNCTION_POINTERS or set ALLOW_TABLE_GROWTH.")}ret.push(null)};ret.set=function(i,func){ret[i]=func};ret.get=function(i){return ret[i]};return ret},Module:function(binary){},Instance:function(module,info){this.exports=( +// EMSCRIPTEN_START_ASM +function a(asmLibraryArg,wasmMemory,wasmTable){var scratchBuffer=new ArrayBuffer(8);var b=new Int32Array(scratchBuffer);var c=new Float32Array(scratchBuffer);var d=new Float64Array(scratchBuffer);function e(index){return b[index]}function f(index,value){b[index]=value}function g(){return d[0]}function h(value){d[0]=value}function i(value){c[0]=value}function j(global,env,buffer){var k=env.memory;var l=wasmTable;var m=new global.Int8Array(buffer);var n=new global.Int16Array(buffer);var o=new global.Int32Array(buffer);var p=new global.Uint8Array(buffer);var q=new global.Uint16Array(buffer);var r=new global.Uint32Array(buffer);var s=new global.Float32Array(buffer);var t=new global.Float64Array(buffer);var u=global.Math.imul;var v=global.Math.fround;var w=global.Math.abs;var x=global.Math.clz32;var y=global.Math.min;var z=global.Math.max;var A=global.Math.floor;var B=global.Math.ceil;var C=global.Math.sqrt;var D=env.abort;var E=global.NaN;var F=global.Infinity;var G=env.fd_write;var H=env.round;var I=env.fd_seek;var J=env.emscripten_resize_heap;var K=env.emscripten_memcpy_big;var L=env.fd_read;var M=env.fd_close;var N=5257216;var O=0;var P=0;var Q=0; +// EMSCRIPTEN_START_FUNCS +function Zd(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,R=0,S=0,T=0,U=0,V=0,W=0;a:{if(d>>>0>=13){if((b|0)<1){break a}n=e;m=d+ -13|0;while(1){e=0;d=0;b:{switch(m|0){case 19:d=o[((j<<2)+f|0)+ -128>>2];e=d;h=d>>31;d=o[c+124>>2];e=Ee(e,h,d,d>>31);d=Q;case 18:h=o[((j<<2)+f|0)+ -124>>2];g=h;i=h>>31;h=o[c+120>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 17:h=o[((j<<2)+f|0)+ -120>>2];g=h;i=h>>31;h=o[c+116>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 16:h=o[((j<<2)+f|0)+ -116>>2];g=h;i=h>>31;h=o[c+112>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 15:h=o[((j<<2)+f|0)+ -112>>2];g=h;i=h>>31;h=o[c+108>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 14:h=o[((j<<2)+f|0)+ -108>>2];g=h;i=h>>31;h=o[c+104>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 13:h=o[((j<<2)+f|0)+ -104>>2];g=h;i=h>>31;h=o[c+100>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 12:h=o[((j<<2)+f|0)+ -100>>2];g=h;i=h>>31;h=o[c+96>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 11:h=o[((j<<2)+f|0)+ -96>>2];g=h;i=h>>31;h=o[c+92>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 10:h=o[((j<<2)+f|0)+ -92>>2];g=h;i=h>>31;h=o[c+88>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 9:h=o[((j<<2)+f|0)+ -88>>2];g=h;i=h>>31;h=o[c+84>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 8:h=o[((j<<2)+f|0)+ -84>>2];g=h;i=h>>31;h=o[c+80>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 7:h=o[((j<<2)+f|0)+ -80>>2];g=h;i=h>>31;h=o[c+76>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 6:h=o[((j<<2)+f|0)+ -76>>2];g=h;i=h>>31;h=o[c+72>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 5:h=o[((j<<2)+f|0)+ -72>>2];g=h;i=h>>31;h=o[c+68>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 4:h=o[((j<<2)+f|0)+ -68>>2];g=h;i=h>>31;h=o[c+64>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 3:h=o[((j<<2)+f|0)+ -64>>2];g=h;i=h>>31;h=o[c+60>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 2:h=o[((j<<2)+f|0)+ -60>>2];g=h;i=h>>31;h=o[c+56>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 1:h=o[((j<<2)+f|0)+ -56>>2];g=h;i=h>>31;h=o[c+52>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 0:h=(j<<2)+f|0;i=o[h+ -52>>2];g=i;k=i>>31;i=o[c+48>>2];i=Ee(g,k,i,i>>31)+e|0;g=d+Q|0;g=i>>>0<e>>>0?g+1|0:g;d=o[h+ -48>>2];e=d;k=d>>31;d=o[c+44>>2];e=Ee(e,k,d,d>>31);d=e+i|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -44>>2];e=d;k=d>>31;d=o[c+40>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -40>>2];e=d;k=d>>31;d=o[c+36>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -36>>2];e=d;k=d>>31;d=o[c+32>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -32>>2];e=d;k=d>>31;d=o[c+28>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -28>>2];e=d;k=d>>31;d=o[c+24>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -24>>2];e=d;k=d>>31;d=o[c+20>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -20>>2];e=d;k=d>>31;d=o[c+16>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -16>>2];e=d;k=d>>31;d=o[c+12>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -12>>2];e=d;k=d>>31;d=o[c+8>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -8>>2];e=d;k=d>>31;d=o[c+4>>2];e=Ee(e,k,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;i=d;d=o[h+ -4>>2];e=d;h=d>>31;d=o[c>>2];e=Ee(e,h,d,d>>31);d=i+e|0;g=Q+g|0;g=d>>>0<e>>>0?g+1|0:g;e=d;d=g;break;default:break b}}h=j<<2;k=h+f|0;g=o[a+h>>2];i=e;e=n;h=e&31;o[k>>2]=g+(32<=(e&63)>>>0?d>>h:((1<<h)-1&d)<<32-h|i>>>h);j=j+1|0;if((j|0)!=(b|0)){continue}break}break a}if(d>>>0>=9){if(d>>>0>=11){if((d|0)!=12){if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[f+ -32>>2];p=o[f+ -36>>2];r=o[f+ -40>>2];q=o[f+ -44>>2];g=o[c>>2];s=g;A=g>>31;g=o[c+4>>2];B=g;C=g>>31;g=o[c+8>>2];z=g;E=g>>31;g=o[c+12>>2];F=g;x=g>>31;g=o[c+16>>2];G=g;H=g>>31;g=o[c+20>>2];D=g;J=g>>31;g=o[c+24>>2];K=g;w=g>>31;g=o[c+28>>2];L=g;M=g>>31;g=o[c+32>>2];I=g;O=g>>31;g=o[c+36>>2];P=g;v=g>>31;c=o[c+40>>2];R=c;S=c>>31;c=0;while(1){g=c<<2;N=g+f|0;T=o[a+g>>2];t=r;g=Ee(r,r>>31,P,v);U=Q;r=p;u=Ee(q,q>>31,R,S);q=u+g|0;g=Q+U|0;g=q>>>0<u>>>0?g+1|0:g;u=q;q=Ee(p,p>>31,I,O);p=u+q|0;g=Q+g|0;g=p>>>0<q>>>0?g+1|0:g;q=p;p=l;u=q;q=Ee(l,l>>31,L,M);l=u+q|0;g=Q+g|0;g=l>>>0<q>>>0?g+1|0:g;q=l;l=k;k=q;q=Ee(l,l>>31,K,w);k=k+q|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=k;k=m;u=q;q=Ee(m,m>>31,D,J);m=u+q|0;g=Q+g|0;g=m>>>0<q>>>0?g+1|0:g;q=m;m=i;u=q;q=Ee(i,i>>31,G,H);i=u+q|0;g=Q+g|0;g=i>>>0<q>>>0?g+1|0:g;q=i;i=h;u=q;q=Ee(h,h>>31,F,x);h=u+q|0;g=Q+g|0;g=h>>>0<q>>>0?g+1|0:g;u=h;h=n;q=Ee(h,h>>31,z,E);n=u+q|0;g=Q+g|0;g=n>>>0<q>>>0?g+1|0:g;q=n;n=d;y=N;u=q;q=Ee(d,d>>31,B,C);d=u+q|0;g=Q+g|0;g=d>>>0<q>>>0?g+1|0:g;u=d;d=j;q=Ee(d,d>>31,s,A);j=u+q|0;g=Q+g|0;g=j>>>0<q>>>0?g+1|0:g;N=j;j=e;q=j&31;j=(32<=(j&63)>>>0?g>>q:((1<<q)-1&g)<<32-q|N>>>q)+T|0;o[y>>2]=j;q=t;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[f+ -32>>2];p=o[f+ -36>>2];r=o[f+ -40>>2];q=o[f+ -44>>2];g=o[f+ -48>>2];t=o[c>>2];A=t;B=t>>31;t=o[c+4>>2];C=t;z=t>>31;t=o[c+8>>2];E=t;F=t>>31;t=o[c+12>>2];x=t;G=t>>31;t=o[c+16>>2];H=t;D=t>>31;t=o[c+20>>2];J=t;K=t>>31;t=o[c+24>>2];w=t;L=t>>31;t=o[c+28>>2];M=t;I=t>>31;t=o[c+32>>2];O=t;P=t>>31;t=o[c+36>>2];v=t;R=t>>31;t=o[c+40>>2];S=t;N=t>>31;c=o[c+44>>2];T=c;U=c>>31;c=0;while(1){t=c<<2;u=t+f|0;W=o[a+t>>2];t=q;s=Ee(q,q>>31,S,N);y=Q;q=r;V=Ee(g,g>>31,T,U);s=V+s|0;g=Q+y|0;g=s>>>0<V>>>0?g+1|0:g;y=s;s=Ee(r,r>>31,v,R);r=y+s|0;g=Q+g|0;g=r>>>0<s>>>0?g+1|0:g;s=r;r=p;y=s;s=Ee(p,p>>31,O,P);p=y+s|0;g=Q+g|0;g=p>>>0<s>>>0?g+1|0:g;s=p;p=l;y=s;s=Ee(l,l>>31,M,I);l=y+s|0;g=Q+g|0;g=l>>>0<s>>>0?g+1|0:g;s=l;l=k;k=s;s=Ee(l,l>>31,w,L);k=k+s|0;g=Q+g|0;g=k>>>0<s>>>0?g+1|0:g;s=k;k=m;y=s;s=Ee(m,m>>31,J,K);m=y+s|0;g=Q+g|0;g=m>>>0<s>>>0?g+1|0:g;s=m;m=i;y=s;s=Ee(i,i>>31,H,D);i=y+s|0;g=Q+g|0;g=i>>>0<s>>>0?g+1|0:g;s=i;i=h;y=s;s=Ee(h,h>>31,x,G);h=y+s|0;g=Q+g|0;g=h>>>0<s>>>0?g+1|0:g;y=h;h=n;s=Ee(h,h>>31,E,F);n=y+s|0;g=Q+g|0;g=n>>>0<s>>>0?g+1|0:g;s=n;n=d;y=u;u=s;s=Ee(d,d>>31,C,z);d=u+s|0;g=Q+g|0;g=d>>>0<s>>>0?g+1|0:g;u=d;d=j;s=Ee(d,d>>31,A,B);j=u+s|0;g=Q+g|0;g=j>>>0<s>>>0?g+1|0:g;u=j;j=e;s=j&31;j=(32<=(j&63)>>>0?g>>s:((1<<s)-1&g)<<32-s|u>>>s)+W|0;o[y>>2]=j;g=t;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=10){if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[f+ -32>>2];p=o[f+ -36>>2];g=o[c>>2];q=g;t=g>>31;g=o[c+4>>2];s=g;A=g>>31;g=o[c+8>>2];B=g;C=g>>31;g=o[c+12>>2];z=g;E=g>>31;g=o[c+16>>2];F=g;x=g>>31;g=o[c+20>>2];G=g;H=g>>31;g=o[c+24>>2];D=g;J=g>>31;g=o[c+28>>2];K=g;w=g>>31;c=o[c+32>>2];L=c;M=c>>31;c=0;while(1){g=c<<2;I=g+f|0;O=o[a+g>>2];r=l;g=Ee(l,l>>31,K,w);P=Q;l=k;v=Ee(p,p>>31,L,M);p=v+g|0;g=Q+P|0;g=p>>>0<v>>>0?g+1|0:g;k=p;p=Ee(l,l>>31,D,J);k=k+p|0;g=Q+g|0;g=k>>>0<p>>>0?g+1|0:g;p=k;k=m;v=p;p=Ee(m,m>>31,G,H);m=v+p|0;g=Q+g|0;g=m>>>0<p>>>0?g+1|0:g;p=m;m=i;v=p;p=Ee(i,i>>31,F,x);i=v+p|0;g=Q+g|0;g=i>>>0<p>>>0?g+1|0:g;p=i;i=h;v=p;p=Ee(h,h>>31,z,E);h=v+p|0;g=Q+g|0;g=h>>>0<p>>>0?g+1|0:g;v=h;h=n;p=Ee(h,h>>31,B,C);n=v+p|0;g=Q+g|0;g=n>>>0<p>>>0?g+1|0:g;p=n;n=d;u=I;v=p;p=Ee(d,d>>31,s,A);d=v+p|0;g=Q+g|0;g=d>>>0<p>>>0?g+1|0:g;v=d;d=j;p=Ee(d,d>>31,q,t);j=v+p|0;g=Q+g|0;g=j>>>0<p>>>0?g+1|0:g;I=j;j=e;p=j&31;j=(32<=(j&63)>>>0?g>>p:((1<<p)-1&g)<<32-p|I>>>p)+O|0;o[u>>2]=j;p=r;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[f+ -32>>2];p=o[f+ -36>>2];r=o[f+ -40>>2];g=o[c>>2];t=g;s=g>>31;g=o[c+4>>2];A=g;B=g>>31;g=o[c+8>>2];C=g;z=g>>31;g=o[c+12>>2];E=g;F=g>>31;g=o[c+16>>2];x=g;G=g>>31;g=o[c+20>>2];H=g;D=g>>31;g=o[c+24>>2];J=g;K=g>>31;g=o[c+28>>2];w=g;L=g>>31;g=o[c+32>>2];M=g;I=g>>31;c=o[c+36>>2];O=c;P=c>>31;c=0;while(1){g=c<<2;v=g+f|0;R=o[a+g>>2];q=p;g=Ee(p,p>>31,M,I);S=Q;p=l;N=Ee(r,r>>31,O,P);r=N+g|0;g=Q+S|0;g=r>>>0<N>>>0?g+1|0:g;u=r;r=Ee(l,l>>31,w,L);l=u+r|0;g=Q+g|0;g=l>>>0<r>>>0?g+1|0:g;r=l;l=k;k=r;r=Ee(l,l>>31,J,K);k=k+r|0;g=Q+g|0;g=k>>>0<r>>>0?g+1|0:g;r=k;k=m;u=r;r=Ee(m,m>>31,H,D);m=u+r|0;g=Q+g|0;g=m>>>0<r>>>0?g+1|0:g;r=m;m=i;u=r;r=Ee(i,i>>31,x,G);i=u+r|0;g=Q+g|0;g=i>>>0<r>>>0?g+1|0:g;r=i;i=h;u=r;r=Ee(h,h>>31,E,F);h=u+r|0;g=Q+g|0;g=h>>>0<r>>>0?g+1|0:g;u=h;h=n;r=Ee(h,h>>31,C,z);n=u+r|0;g=Q+g|0;g=n>>>0<r>>>0?g+1|0:g;r=n;n=d;u=v;v=r;r=Ee(d,d>>31,A,B);d=v+r|0;g=Q+g|0;g=d>>>0<r>>>0?g+1|0:g;v=d;d=j;r=Ee(d,d>>31,t,s);j=v+r|0;g=Q+g|0;g=j>>>0<r>>>0?g+1|0:g;v=j;j=e;r=j&31;j=(32<=(j&63)>>>0?g>>r:((1<<r)-1&g)<<32-r|v>>>r)+R|0;o[u>>2]=j;r=q;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=5){if(d>>>0>=7){if((d|0)!=8){if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[c>>2];p=l;r=l>>31;l=o[c+4>>2];q=l;t=l>>31;l=o[c+8>>2];s=l;A=l>>31;l=o[c+12>>2];B=l;C=l>>31;l=o[c+16>>2];z=l;E=l>>31;l=o[c+20>>2];F=l;x=l>>31;c=o[c+24>>2];G=c;H=c>>31;c=0;while(1){l=c<<2;D=l+f|0;J=o[a+l>>2];l=m;g=Ee(l,l>>31,F,x);K=Q;m=i;w=Ee(k,k>>31,G,H);k=w+g|0;g=Q+K|0;g=k>>>0<w>>>0?g+1|0:g;w=k;k=Ee(i,i>>31,z,E);i=w+k|0;g=Q+g|0;g=i>>>0<k>>>0?g+1|0:g;k=i;i=h;w=k;k=Ee(h,h>>31,B,C);h=w+k|0;g=Q+g|0;g=h>>>0<k>>>0?g+1|0:g;w=h;h=n;k=Ee(h,h>>31,s,A);n=w+k|0;g=Q+g|0;g=n>>>0<k>>>0?g+1|0:g;k=n;n=d;v=D;w=k;k=Ee(d,d>>31,q,t);d=w+k|0;g=Q+g|0;g=d>>>0<k>>>0?g+1|0:g;w=d;d=j;k=Ee(d,d>>31,p,r);j=w+k|0;g=Q+g|0;g=j>>>0<k>>>0?g+1|0:g;D=j;j=e;k=j&31;j=(32<=(j&63)>>>0?g>>k:((1<<k)-1&g)<<32-k|D>>>k)+J|0;o[v>>2]=j;k=l;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[f+ -28>>2];l=o[f+ -32>>2];g=o[c>>2];r=g;q=g>>31;g=o[c+4>>2];t=g;s=g>>31;g=o[c+8>>2];A=g;B=g>>31;g=o[c+12>>2];C=g;z=g>>31;g=o[c+16>>2];E=g;F=g>>31;g=o[c+20>>2];x=g;G=g>>31;g=o[c+24>>2];H=g;D=g>>31;c=o[c+28>>2];J=c;K=c>>31;c=0;while(1){g=c<<2;w=g+f|0;L=o[a+g>>2];p=k;g=Ee(k,k>>31,H,D);M=Q;k=m;I=Ee(l,l>>31,J,K);l=I+g|0;g=Q+M|0;g=l>>>0<I>>>0?g+1|0:g;v=l;l=Ee(m,m>>31,x,G);m=v+l|0;g=Q+g|0;g=m>>>0<l>>>0?g+1|0:g;l=m;m=i;v=l;l=Ee(i,i>>31,E,F);i=v+l|0;g=Q+g|0;g=i>>>0<l>>>0?g+1|0:g;l=i;i=h;v=l;l=Ee(h,h>>31,C,z);h=v+l|0;g=Q+g|0;g=h>>>0<l>>>0?g+1|0:g;v=h;h=n;l=Ee(h,h>>31,A,B);n=v+l|0;g=Q+g|0;g=n>>>0<l>>>0?g+1|0:g;l=n;n=d;v=w;w=l;l=Ee(d,d>>31,t,s);d=w+l|0;g=Q+g|0;g=d>>>0<l>>>0?g+1|0:g;w=d;d=j;l=Ee(d,d>>31,r,q);j=w+l|0;g=Q+g|0;g=j>>>0<l>>>0?g+1|0:g;w=j;j=e;l=j&31;j=(32<=(j&63)>>>0?g>>l:((1<<l)-1&g)<<32-l|w>>>l)+L|0;o[v>>2]=j;l=p;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=6){if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[c>>2];k=m;l=m>>31;m=o[c+4>>2];p=m;r=m>>31;m=o[c+8>>2];q=m;t=m>>31;m=o[c+12>>2];s=m;A=m>>31;c=o[c+16>>2];B=c;C=c>>31;c=0;while(1){m=c<<2;z=m+f|0;E=o[a+m>>2];m=h;g=Ee(h,h>>31,s,A);F=Q;h=n;x=Ee(i,i>>31,B,C);i=x+g|0;g=Q+F|0;g=i>>>0<x>>>0?g+1|0:g;n=i;i=Ee(h,h>>31,q,t);n=n+i|0;g=Q+g|0;g=n>>>0<i>>>0?g+1|0:g;i=n;n=d;x=i;i=Ee(d,d>>31,p,r);d=x+i|0;g=Q+g|0;g=d>>>0<i>>>0?g+1|0:g;i=d;d=j;j=Ee(d,d>>31,k,l);i=i+j|0;g=Q+g|0;g=i>>>0<j>>>0?g+1|0:g;j=e&31;j=(32<=(e&63)>>>0?g>>j:((1<<j)-1&g)<<32-j|i>>>j)+E|0;o[z>>2]=j;i=m;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[f+ -20>>2];m=o[f+ -24>>2];k=o[c>>2];l=k;p=l>>31;k=o[c+4>>2];r=k;q=k>>31;k=o[c+8>>2];t=k;s=k>>31;k=o[c+12>>2];A=k;B=k>>31;k=o[c+16>>2];C=k;z=k>>31;c=o[c+20>>2];E=c;F=c>>31;c=0;while(1){k=c<<2;x=k+f|0;G=o[a+k>>2];k=i;g=Ee(i,i>>31,C,z);H=Q;i=h;D=Ee(m,m>>31,E,F);m=D+g|0;g=Q+H|0;g=m>>>0<D>>>0?g+1|0:g;w=m;m=Ee(h,h>>31,A,B);h=w+m|0;g=Q+g|0;g=h>>>0<m>>>0?g+1|0:g;w=h;h=n;m=Ee(h,h>>31,t,s);n=w+m|0;g=Q+g|0;g=n>>>0<m>>>0?g+1|0:g;m=n;n=d;w=x;x=m;m=Ee(d,d>>31,r,q);d=x+m|0;g=Q+g|0;g=d>>>0<m>>>0?g+1|0:g;m=d;d=j;j=Ee(d,d>>31,l,p);m=m+j|0;g=Q+g|0;g=m>>>0<j>>>0?g+1|0:g;j=e&31;j=(32<=(e&63)>>>0?g>>j:((1<<j)-1&g)<<32-j|m>>>j)+G|0;o[w>>2]=j;m=k;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=3){if((d|0)!=4){if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[c>>2];m=h;k=h>>31;h=o[c+4>>2];l=h;p=h>>31;c=o[c+8>>2];r=c;q=c>>31;c=0;while(1){h=c<<2;i=h+f|0;t=o[a+h>>2];h=d;d=Ee(h,h>>31,l,p);g=Q;s=i;n=Ee(n,n>>31,r,q);d=n+d|0;g=Q+g|0;g=d>>>0<n>>>0?g+1|0:g;i=d;d=j;j=Ee(d,d>>31,m,k);n=i+j|0;g=Q+g|0;g=n>>>0<j>>>0?g+1|0:g;j=n;i=e&31;j=(32<=(e&63)>>>0?g>>i:((1<<i)-1&g)<<32-i|j>>>i)+t|0;o[s>>2]=j;n=h;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[f+ -12>>2];h=o[f+ -16>>2];i=o[c>>2];k=i;l=i>>31;i=o[c+4>>2];p=i;r=i>>31;i=o[c+8>>2];q=i;t=i>>31;c=o[c+12>>2];s=c;A=c>>31;c=0;while(1){i=c<<2;m=i+f|0;B=o[a+i>>2];i=n;g=Ee(i,i>>31,q,t);C=Q;n=d;x=m;z=Ee(h,h>>31,s,A);h=z+g|0;g=Q+C|0;g=h>>>0<z>>>0?g+1|0:g;m=h;h=Ee(d,d>>31,p,r);d=m+h|0;g=Q+g|0;g=d>>>0<h>>>0?g+1|0:g;h=d;d=j;j=Ee(d,d>>31,k,l);h=h+j|0;g=Q+g|0;g=h>>>0<j>>>0?g+1|0:g;j=h;h=e;m=h&31;j=(32<=(h&63)>>>0?g>>m:((1<<m)-1&g)<<32-m|j>>>m)+B|0;o[x>>2]=j;h=i;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=2){if((b|0)<1){break a}j=o[f+ -4>>2];c=o[c>>2];i=c;m=c>>31;c=0;while(1){d=c<<2;k=d+f|0;g=o[a+d>>2];j=Ee(j,j>>31,i,m);h=Q;d=e;n=d&31;j=g+(32<=(d&63)>>>0?h>>n:((1<<n)-1&h)<<32-n|j>>>n)|0;o[k>>2]=j;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}j=o[f+ -4>>2];d=o[f+ -8>>2];n=o[c>>2];i=n;m=i>>31;c=o[c+4>>2];k=c;l=c>>31;c=0;while(1){n=c<<2;h=n+f|0;p=o[a+n>>2];n=j;j=Ee(j,j>>31,i,m);g=Q;q=h;h=j;j=Ee(d,d>>31,k,l);d=h+j|0;g=Q+g|0;g=d>>>0<j>>>0?g+1|0:g;j=d;d=e;h=d&31;j=(32<=(d&63)>>>0?g>>h:((1<<h)-1&g)<<32-h|j>>>h)+p|0;o[q>>2]=j;d=n;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function ae(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,R=0,S=0,T=0,U=0,V=0;a:{if(d>>>0>=13){if((b|0)<1){break a}s=e;m=d+ -13|0;while(1){e=0;d=0;b:{switch(m|0){case 19:d=o[((n<<2)+a|0)+ -128>>2];e=d;h=d>>31;d=o[c+124>>2];e=Ee(e,h,d,d>>31);d=Q;case 18:h=o[((n<<2)+a|0)+ -124>>2];g=h;i=h>>31;h=o[c+120>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 17:h=o[((n<<2)+a|0)+ -120>>2];g=h;i=h>>31;h=o[c+116>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 16:h=o[((n<<2)+a|0)+ -116>>2];g=h;i=h>>31;h=o[c+112>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 15:h=o[((n<<2)+a|0)+ -112>>2];g=h;i=h>>31;h=o[c+108>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 14:h=o[((n<<2)+a|0)+ -108>>2];g=h;i=h>>31;h=o[c+104>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 13:h=o[((n<<2)+a|0)+ -104>>2];g=h;i=h>>31;h=o[c+100>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 12:h=o[((n<<2)+a|0)+ -100>>2];g=h;i=h>>31;h=o[c+96>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 11:h=o[((n<<2)+a|0)+ -96>>2];g=h;i=h>>31;h=o[c+92>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 10:h=o[((n<<2)+a|0)+ -92>>2];g=h;i=h>>31;h=o[c+88>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 9:h=o[((n<<2)+a|0)+ -88>>2];g=h;i=h>>31;h=o[c+84>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 8:h=o[((n<<2)+a|0)+ -84>>2];g=h;i=h>>31;h=o[c+80>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 7:h=o[((n<<2)+a|0)+ -80>>2];g=h;i=h>>31;h=o[c+76>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 6:h=o[((n<<2)+a|0)+ -76>>2];g=h;i=h>>31;h=o[c+72>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 5:h=o[((n<<2)+a|0)+ -72>>2];g=h;i=h>>31;h=o[c+68>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 4:h=o[((n<<2)+a|0)+ -68>>2];g=h;i=h>>31;h=o[c+64>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 3:h=o[((n<<2)+a|0)+ -64>>2];g=h;i=h>>31;h=o[c+60>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 2:h=o[((n<<2)+a|0)+ -60>>2];g=h;i=h>>31;h=o[c+56>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 1:h=o[((n<<2)+a|0)+ -56>>2];g=h;i=h>>31;h=o[c+52>>2];h=Ee(g,i,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;e=h;d=g;case 0:i=(n<<2)+a|0;h=o[i+ -52>>2];g=h;j=h>>31;h=o[c+48>>2];h=Ee(g,j,h,h>>31)+e|0;g=d+Q|0;g=h>>>0<e>>>0?g+1|0:g;d=o[i+ -48>>2];e=d;j=d>>31;d=o[c+44>>2];d=Ee(e,j,d,d>>31);e=d+h|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -44>>2];h=d;j=d>>31;d=o[c+40>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -40>>2];h=d;j=d>>31;d=o[c+36>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -36>>2];h=d;j=d>>31;d=o[c+32>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -32>>2];h=d;j=d>>31;d=o[c+28>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -28>>2];h=d;j=d>>31;d=o[c+24>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -24>>2];h=d;j=d>>31;d=o[c+20>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -20>>2];h=d;j=d>>31;d=o[c+16>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -16>>2];h=d;j=d>>31;d=o[c+12>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -12>>2];h=d;j=d>>31;d=o[c+8>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -8>>2];h=d;j=d>>31;d=o[c+4>>2];d=Ee(h,j,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=o[i+ -4>>2];h=d;i=d>>31;d=o[c>>2];d=Ee(h,i,d,d>>31);e=d+e|0;g=Q+g|0;g=e>>>0<d>>>0?g+1|0:g;d=g;break;default:break b}}h=n<<2;g=h+f|0;j=o[a+h>>2];h=d;d=s;i=d&31;o[g>>2]=j-(32<=(d&63)>>>0?h>>i:((1<<i)-1&h)<<32-i|e>>>i);n=n+1|0;if((n|0)!=(b|0)){continue}break}break a}if(d>>>0>=9){if(d>>>0>=11){if((d|0)!=12){if((b|0)<1){break a}k=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];i=o[a+ -28>>2];j=o[a+ -32>>2];l=o[a+ -36>>2];r=o[a+ -40>>2];t=o[a+ -44>>2];g=o[c>>2];P=g;R=g>>31;g=o[c+4>>2];S=g;M=g>>31;g=o[c+8>>2];N=g;O=g>>31;g=o[c+12>>2];J=g;K=g>>31;g=o[c+16>>2];L=g;G=g>>31;g=o[c+20>>2];H=g;I=g>>31;g=o[c+24>>2];E=g;F=g>>31;g=o[c+28>>2];B=g;C=g>>31;g=o[c+32>>2];D=g;y=g>>31;g=o[c+36>>2];z=g;A=g>>31;c=o[c+40>>2];w=c;x=c>>31;c=0;while(1){q=r;r=l;l=j;j=i;i=m;m=h;h=s;s=d;d=n;n=k;g=c<<2;v=g+f|0;k=o[a+g>>2];p=Ee(q,q>>31,z,A);g=Q;u=p;p=Ee(t,t>>31,w,x);t=u+p|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(r,r>>31,D,y);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(l,l>>31,B,C);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(j,j>>31,E,F);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(i,i>>31,H,I);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(m,m>>31,L,G);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(h,h>>31,J,K);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(s,s>>31,N,O);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(d,d>>31,S,M);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=Ee(n,n>>31,P,R);t=p+t|0;g=Q+g|0;g=t>>>0<p>>>0?g+1|0:g;p=g;g=e;u=g&31;o[v>>2]=k-(32<=(g&63)>>>0?p>>u:((1<<u)-1&p)<<32-u|t>>>u);t=q;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}t=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];i=o[a+ -28>>2];j=o[a+ -32>>2];l=o[a+ -36>>2];r=o[a+ -40>>2];q=o[a+ -44>>2];k=o[a+ -48>>2];g=o[c>>2];T=g;U=g>>31;g=o[c+4>>2];V=g;P=g>>31;g=o[c+8>>2];R=g;S=g>>31;g=o[c+12>>2];M=g;N=g>>31;g=o[c+16>>2];O=g;J=g>>31;g=o[c+20>>2];K=g;L=g>>31;g=o[c+24>>2];G=g;H=g>>31;g=o[c+28>>2];I=g;E=g>>31;g=o[c+32>>2];F=g;B=g>>31;g=o[c+36>>2];C=g;D=g>>31;g=o[c+40>>2];y=g;z=g>>31;c=o[c+44>>2];A=c;w=c>>31;c=0;while(1){p=q;q=r;r=l;l=j;j=i;i=m;m=h;h=s;s=d;d=n;n=t;g=c<<2;x=g+f|0;t=o[a+g>>2];u=Ee(p,p>>31,y,z);g=Q;k=Ee(k,k>>31,A,w);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(q,q>>31,C,D);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(r,r>>31,F,B);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(l,l>>31,I,E);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(j,j>>31,G,H);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(i,i>>31,K,L);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(m,m>>31,O,J);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(h,h>>31,M,N);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(s,s>>31,R,S);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(d,d>>31,V,P);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=Ee(n,n>>31,T,U);u=k+u|0;g=Q+g|0;g=u>>>0<k>>>0?g+1|0:g;k=g;g=e;v=g&31;o[x>>2]=t-(32<=(g&63)>>>0?k>>v:((1<<v)-1&k)<<32-v|u>>>v);k=p;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=10){if((b|0)<1){break a}r=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];i=o[a+ -28>>2];j=o[a+ -32>>2];q=o[a+ -36>>2];l=o[c>>2];J=l;K=l>>31;l=o[c+4>>2];L=l;G=l>>31;l=o[c+8>>2];H=l;I=l>>31;l=o[c+12>>2];E=l;F=l>>31;l=o[c+16>>2];B=l;C=l>>31;l=o[c+20>>2];D=l;y=l>>31;l=o[c+24>>2];z=l;A=l>>31;l=o[c+28>>2];w=l;x=l>>31;c=o[c+32>>2];v=c;u=c>>31;c=0;while(1){l=j;j=i;i=m;m=h;h=s;s=d;d=n;n=r;g=c<<2;t=g+f|0;r=o[a+g>>2];k=Ee(l,l>>31,w,x);g=Q;q=Ee(q,q>>31,v,u);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(j,j>>31,z,A);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(i,i>>31,D,y);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(m,m>>31,B,C);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(h,h>>31,E,F);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(s,s>>31,H,I);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(d,d>>31,L,G);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=Ee(n,n>>31,J,K);k=q+k|0;g=Q+g|0;g=k>>>0<q>>>0?g+1|0:g;q=g;g=e;p=g&31;o[t>>2]=r-(32<=(g&63)>>>0?q>>p:((1<<p)-1&q)<<32-p|k>>>p);q=l;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}q=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];i=o[a+ -28>>2];j=o[a+ -32>>2];l=o[a+ -36>>2];k=o[a+ -40>>2];g=o[c>>2];M=g;N=g>>31;g=o[c+4>>2];O=g;J=g>>31;g=o[c+8>>2];K=g;L=g>>31;g=o[c+12>>2];G=g;H=g>>31;g=o[c+16>>2];I=g;E=g>>31;g=o[c+20>>2];F=g;B=g>>31;g=o[c+24>>2];C=g;D=g>>31;g=o[c+28>>2];y=g;z=g>>31;g=o[c+32>>2];A=g;w=g>>31;c=o[c+36>>2];x=c;v=c>>31;c=0;while(1){r=l;l=j;j=i;i=m;m=h;h=s;s=d;d=n;n=q;g=c<<2;u=g+f|0;q=o[a+g>>2];p=Ee(r,r>>31,A,w);g=Q;k=Ee(k,k>>31,x,v);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(l,l>>31,y,z);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(j,j>>31,C,D);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(i,i>>31,F,B);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(m,m>>31,I,E);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(h,h>>31,G,H);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(s,s>>31,K,L);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(d,d>>31,O,J);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=Ee(n,n>>31,M,N);p=k+p|0;g=Q+g|0;g=p>>>0<k>>>0?g+1|0:g;k=g;g=e;t=g&31;o[u>>2]=q-(32<=(g&63)>>>0?k>>t:((1<<t)-1&k)<<32-t|p>>>t);k=r;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=5){if(d>>>0>=7){if((d|0)!=8){if((b|0)<1){break a}j=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];l=o[a+ -28>>2];i=o[c>>2];E=i;F=i>>31;i=o[c+4>>2];B=i;C=i>>31;i=o[c+8>>2];D=i;y=i>>31;i=o[c+12>>2];z=i;A=i>>31;i=o[c+16>>2];w=i;x=i>>31;i=o[c+20>>2];v=i;u=i>>31;c=o[c+24>>2];t=c;p=c>>31;c=0;while(1){i=m;m=h;h=s;s=d;d=n;n=j;j=c<<2;k=j+f|0;j=o[a+j>>2];r=Ee(i,i>>31,v,u);g=Q;l=Ee(l,l>>31,t,p);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;l=Ee(m,m>>31,w,x);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;l=Ee(h,h>>31,z,A);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;l=Ee(s,s>>31,D,y);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;l=Ee(d,d>>31,B,C);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;l=Ee(n,n>>31,E,F);r=l+r|0;g=Q+g|0;g=r>>>0<l>>>0?g+1|0:g;q=e&31;o[k>>2]=j-(32<=(e&63)>>>0?g>>q:((1<<q)-1&g)<<32-q|r>>>q);l=i;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}l=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];m=o[a+ -24>>2];i=o[a+ -28>>2];r=o[a+ -32>>2];j=o[c>>2];G=j;H=j>>31;j=o[c+4>>2];I=j;E=j>>31;j=o[c+8>>2];F=j;B=j>>31;j=o[c+12>>2];C=j;D=j>>31;j=o[c+16>>2];y=j;z=j>>31;j=o[c+20>>2];A=j;w=j>>31;j=o[c+24>>2];x=j;v=j>>31;c=o[c+28>>2];u=c;t=c>>31;c=0;while(1){j=i;i=m;m=h;h=s;s=d;d=n;n=l;l=c<<2;p=l+f|0;l=o[a+l>>2];q=Ee(j,j>>31,x,v);g=Q;r=Ee(r,r>>31,u,t);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(i,i>>31,A,w);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(m,m>>31,y,z);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(h,h>>31,C,D);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(s,s>>31,F,B);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(d,d>>31,I,E);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=Ee(n,n>>31,G,H);q=r+q|0;g=Q+g|0;g=q>>>0<r>>>0?g+1|0:g;r=g;g=e;k=g&31;o[p>>2]=l-(32<=(g&63)>>>0?r>>k:((1<<k)-1&r)<<32-k|q>>>k);r=j;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=6){if((b|0)<1){break a}m=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];i=o[a+ -20>>2];h=o[c>>2];y=h;z=h>>31;h=o[c+4>>2];A=h;w=h>>31;h=o[c+8>>2];x=h;v=h>>31;h=o[c+12>>2];u=h;t=h>>31;c=o[c+16>>2];p=c;k=c>>31;c=0;while(1){h=s;s=d;d=n;n=m;m=c<<2;q=m+f|0;m=o[a+m>>2];l=Ee(h,h>>31,u,t);j=Q;i=Ee(i,i>>31,p,k);l=i+l|0;g=Q+j|0;g=l>>>0<i>>>0?g+1|0:g;i=Ee(s,s>>31,x,v);j=i+l|0;g=Q+g|0;g=j>>>0<i>>>0?g+1|0:g;i=Ee(d,d>>31,A,w);j=i+j|0;g=Q+g|0;g=j>>>0<i>>>0?g+1|0:g;i=Ee(n,n>>31,y,z);j=i+j|0;g=Q+g|0;g=j>>>0<i>>>0?g+1|0:g;l=e&31;o[q>>2]=m-(32<=(e&63)>>>0?g>>l:((1<<l)-1&g)<<32-l|j>>>l);i=h;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}i=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];s=o[a+ -16>>2];h=o[a+ -20>>2];j=o[a+ -24>>2];m=o[c>>2];C=m;D=m>>31;m=o[c+4>>2];y=m;z=m>>31;m=o[c+8>>2];A=m;w=m>>31;m=o[c+12>>2];x=m;v=m>>31;m=o[c+16>>2];u=m;t=m>>31;c=o[c+20>>2];p=c;k=c>>31;c=0;while(1){m=h;h=s;s=d;d=n;n=i;i=c<<2;q=i+f|0;i=o[a+i>>2];g=Ee(m,m>>31,u,t);l=Q;j=Ee(j,j>>31,p,k);B=j+g|0;g=Q+l|0;g=B>>>0<j>>>0?g+1|0:g;j=Ee(h,h>>31,x,v);l=j+B|0;g=Q+g|0;g=l>>>0<j>>>0?g+1|0:g;j=Ee(s,s>>31,A,w);l=j+l|0;g=Q+g|0;g=l>>>0<j>>>0?g+1|0:g;j=Ee(d,d>>31,y,z);l=j+l|0;g=Q+g|0;g=l>>>0<j>>>0?g+1|0:g;j=Ee(n,n>>31,C,D);l=j+l|0;g=Q+g|0;g=l>>>0<j>>>0?g+1|0:g;r=e&31;o[q>>2]=i-(32<=(e&63)>>>0?g>>r:((1<<r)-1&g)<<32-r|l>>>r);j=m;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=3){if((d|0)!=4){if((b|0)<1){break a}s=o[a+ -4>>2];n=o[a+ -8>>2];h=o[a+ -12>>2];d=o[c>>2];u=d;t=d>>31;d=o[c+4>>2];p=d;k=d>>31;c=o[c+8>>2];q=c;r=c>>31;c=0;while(1){d=n;n=s;s=c<<2;l=s+f|0;s=o[a+s>>2];j=s;i=Ee(d,d>>31,p,k);m=Q;h=Ee(h,h>>31,q,r);i=h+i|0;g=Q+m|0;g=i>>>0<h>>>0?g+1|0:g;h=Ee(n,n>>31,u,t);m=h+i|0;g=Q+g|0;g=m>>>0<h>>>0?g+1|0:g;h=e;i=h&31;o[l>>2]=j-(32<=(h&63)>>>0?g>>i:((1<<i)-1&g)<<32-i|m>>>i);h=d;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}h=o[a+ -4>>2];n=o[a+ -8>>2];d=o[a+ -12>>2];m=o[a+ -16>>2];s=o[c>>2];w=s;x=s>>31;s=o[c+4>>2];v=s;u=s>>31;s=o[c+8>>2];t=s;p=s>>31;c=o[c+12>>2];k=c;q=c>>31;c=0;while(1){s=d;d=n;n=h;h=c<<2;r=h+f|0;h=o[a+h>>2];j=Ee(s,s>>31,t,p);i=Q;m=Ee(m,m>>31,k,q);j=m+j|0;g=Q+i|0;g=j>>>0<m>>>0?g+1|0:g;m=Ee(d,d>>31,v,u);i=m+j|0;g=Q+g|0;g=i>>>0<m>>>0?g+1|0:g;m=Ee(n,n>>31,w,x);i=m+i|0;g=Q+g|0;g=i>>>0<m>>>0?g+1|0:g;j=e&31;o[r>>2]=h-(32<=(e&63)>>>0?g>>j:((1<<j)-1&g)<<32-j|i>>>j);m=s;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=2){if((b|0)<1){break a}n=o[a+ -4>>2];c=o[c>>2];j=c;i=c>>31;c=0;while(1){d=c<<2;g=d+f|0;s=o[a+d>>2];n=Ee(n,n>>31,j,i);h=Q;d=e;m=d&31;o[g>>2]=s-(32<=(d&63)>>>0?h>>m:((1<<m)-1&h)<<32-m|n>>>m);n=s;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}d=o[a+ -4>>2];s=o[a+ -8>>2];n=o[c>>2];k=n;q=k>>31;c=o[c+4>>2];r=c;l=c>>31;c=0;while(1){n=d;d=c<<2;j=d+f|0;d=o[a+d>>2];m=Ee(n,n>>31,k,q);h=Q;s=Ee(s,s>>31,r,l);m=s+m|0;g=Q+h|0;g=m>>>0<s>>>0?g+1|0:g;h=m;m=e&31;o[j>>2]=d-(32<=(e&63)>>>0?g>>m:((1<<m)-1&g)<<32-m|h>>>m);s=n;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function ob(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,n=0,s=0,t=0,v=0,w=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0;f=N+ -64|0;N=f;o[b>>2]=0;c=o[a+4>>2];d=o[c+56>>2];e=p[c+3589|0];c=q[(p[c+3588|0]<<1)+1280>>1];o[d+24>>2]=q[((e^c>>>8)<<1)+1280>>1]^c<<8&65280;c=o[d+20>>2];o[d+28>>2]=o[d+16>>2];o[d+32>>2]=c;d=o[a+4>>2];m[f+32|0]=p[d+3588|0];c=p[d+3589|0];o[f+12>>2]=2;m[f+33|0]=c;a:{if(!Y(o[d+56>>2],f+28|0,8)){break a}b:{c:{d:{e:{d=o[f+28>>2];if((d|0)==255){break e}m[f+34|0]=d;o[f+12>>2]=3;if(!Y(o[o[a+4>>2]+56>>2],f+28|0,8)){break c}d=o[f+28>>2];if((d|0)==255){break e}c=c>>>1&1;i=o[f+12>>2];m[i+(f+32|0)|0]=d;d=1;o[f+12>>2]=i+1;i=p[f+34|0];g=i>>>4|0;o[f+28>>2]=g;f:{g:{h:{i:{switch(g-1|0){case 7:case 8:case 9:case 10:case 11:case 12:case 13:case 14:o[o[a+4>>2]+1136>>2]=256<<g+ -8;break h;case 1:case 2:case 3:case 4:o[o[a+4>>2]+1136>>2]=576<<g+ -2;break h;case 5:case 6:break g;case 0:break i;default:break f}}o[o[a+4>>2]+1136>>2]=192}g=0}d=c}e=i&15;o[f+28>>2]=e;j:{k:{l:{switch(e-1|0){default:e=0;c=o[a+4>>2];if(o[c+248>>2]){break k}d=1;break j;case 0:o[o[a+4>>2]+1140>>2]=88200;e=0;break j;case 1:o[o[a+4>>2]+1140>>2]=176400;e=0;break j;case 2:o[o[a+4>>2]+1140>>2]=192e3;e=0;break j;case 3:o[o[a+4>>2]+1140>>2]=8e3;e=0;break j;case 4:o[o[a+4>>2]+1140>>2]=16e3;e=0;break j;case 5:o[o[a+4>>2]+1140>>2]=22050;e=0;break j;case 6:o[o[a+4>>2]+1140>>2]=24e3;e=0;break j;case 7:o[o[a+4>>2]+1140>>2]=32e3;e=0;break j;case 8:o[o[a+4>>2]+1140>>2]=44100;e=0;break j;case 9:o[o[a+4>>2]+1140>>2]=48e3;e=0;break j;case 10:o[o[a+4>>2]+1140>>2]=96e3;e=0;break j;case 11:case 12:case 13:break j;case 14:break l}}d=o[a+4>>2];if(!o[d+3632>>2]){l[o[d+32>>2]](a,1,o[d+48>>2])}c=o[a>>2];o[c>>2]=2;break d}o[c+1140>>2]=o[c+288>>2]}j=p[f+35|0];h=j>>>4|0;o[f+28>>2]=h;m:{n:{if(h&8){c=o[a+4>>2];o[c+1144>>2]=2;i=1;o:{switch(h&7){case 1:i=2;break n;case 0:break n;case 2:break o;default:break m}}i=3;break n}c=o[a+4>>2];o[c+1144>>2]=h+1;i=0}o[c+1148>>2]=i;i=d}h=j>>>1&7;o[f+28>>2]=h;d=1;p:{q:{r:{switch(h-1|0){default:if(!o[c+248>>2]){break p}o[c+1152>>2]=o[c+296>>2];break q;case 0:o[c+1152>>2]=8;break q;case 1:o[c+1152>>2]=12;break q;case 3:o[c+1152>>2]=16;break q;case 4:o[c+1152>>2]=20;break q;case 2:case 6:break p;case 5:break r}}o[c+1152>>2]=24}d=i}s:{if(!(!o[c+248>>2]|o[c+272>>2]==o[c+276>>2]?!(m[f+33|0]&1):0)){if(!we(o[c+56>>2],f+16|0,f+32|0,f+12|0)){break c}c=o[f+20>>2];i=c;h=o[f+16>>2];if((h|0)==-1&(c|0)==-1){c=p[(o[f+12>>2]+f|0)+31|0];d=o[a+4>>2];o[d+3520>>2]=1;m[d+3590|0]=c;if(!o[d+3632>>2]){l[o[d+32>>2]](a,1,o[d+48>>2])}c=o[a>>2];o[c>>2]=2;break d}c=o[a+4>>2];n=c+1160|0;o[n>>2]=h;o[n+4>>2]=i;o[c+1156>>2]=1;break s}if(!xe(o[c+56>>2],f+28|0,f+32|0,f+12|0)){break c}c=o[f+28>>2];if((c|0)==-1){c=p[(o[f+12>>2]+f|0)+31|0];d=o[a+4>>2];o[d+3520>>2]=1;m[d+3590|0]=c;if(!o[d+3632>>2]){l[o[d+32>>2]](a,1,o[d+48>>2])}c=o[a>>2];o[c>>2]=2;break d}i=o[a+4>>2];o[i+1160>>2]=c;o[i+1156>>2]=0}c=o[a+4>>2];if(g){if(!Y(o[c+56>>2],f+28|0,8)){break c}c=o[f+12>>2];i=o[f+28>>2];m[c+(f+32|0)|0]=i;o[f+12>>2]=c+1;if((g|0)==7){if(!Y(o[o[a+4>>2]+56>>2],f+8|0,8)){break c}c=o[f+12>>2];i=o[f+8>>2];m[c+(f+32|0)|0]=i;o[f+12>>2]=c+1;i=i|o[f+28>>2]<<8;o[f+28>>2]=i}c=o[a+4>>2];o[c+1136>>2]=i+1}if(e){if(!Y(o[c+56>>2],f+28|0,8)){break c}c=o[f+12>>2];i=o[f+28>>2];m[c+(f+32|0)|0]=i;o[f+12>>2]=c+1;t:{if((e|0)!=12){if(!Y(o[o[a+4>>2]+56>>2],f+8|0,8)){break c}c=o[f+12>>2];i=o[f+8>>2];m[c+(f+32|0)|0]=i;o[f+12>>2]=c+1;g=i|o[f+28>>2]<<8;o[f+28>>2]=g;if((e|0)==13){break t}g=u(g,10);break t}g=u(i,1e3)}c=o[a+4>>2];o[c+1140>>2]=g}if(!Y(o[c+56>>2],f+28|0,8)){break c}i=p[f+28|0];e=Vb(f+32|0,o[f+12>>2]);c=o[a+4>>2];if((e|0)!=(i|0)){if(!o[c+3632>>2]){l[o[c+32>>2]](a,1,o[c+48>>2])}c=o[a>>2];o[c>>2]=2;break d}o[c+232>>2]=0;u:{v:{if(o[c+1156>>2]){break v}e=c+1160|0;i=o[e>>2];o[f+28>>2]=i;o[c+1156>>2]=1;g=o[c+228>>2];if(g){D=e,E=Ee(g,0,i,0),o[D>>2]=E;o[e+4>>2]=Q;break v}if(o[c+248>>2]){e=o[c+272>>2];if((e|0)!=o[c+276>>2]){break u}c=c+1160|0;D=c,E=Ee(e,0,i,0),o[D>>2]=E;o[c+4>>2]=Q;c=o[a+4>>2];o[c+232>>2]=o[c+276>>2];break v}if(!i){c=c+1160|0;o[c>>2]=0;o[c+4>>2]=0;c=o[a+4>>2];o[c+232>>2]=o[c+1136>>2];break v}e=c+1160|0;D=e,E=Ee(o[c+1136>>2],0,i,0),o[D>>2]=E;o[e+4>>2]=Q}if(!(d|j&1)){c=o[a>>2];break d}c=o[a+4>>2]}w:{if(!o[c+3632>>2]){l[o[c+32>>2]](a,3,o[c+48>>2]);break w}o[c+6152>>2]=o[c+6152>>2]+1}c=o[a>>2];o[c>>2]=2;break d}d=o[a+4>>2];o[d+3520>>2]=1;m[d+3590|0]=255;if(!o[d+3632>>2]){l[o[d+32>>2]](a,1,o[d+48>>2])}c=o[a>>2];o[c>>2]=2}i=1;if(o[c>>2]==2){break a}c=o[a+4>>2];e=o[c+1144>>2];h=o[c+1136>>2];if(!(r[c+224>>2]>=e>>>0?r[c+220>>2]>=h>>>0:0)){d=o[c+60>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+60>>2]=0;c=o[a+4>>2]}d=o[c+3592>>2];if(d){X(d);o[o[a+4>>2]+92>>2]=0;o[o[a+4>>2]+3592>>2]=0;c=o[a+4>>2]}d=o[c- -64>>2];if(d){X(d+ -16|0);o[o[a+4>>2]- -64>>2]=0;c=o[a+4>>2]}d=o[c+3596>>2];if(d){X(d);o[o[a+4>>2]+96>>2]=0;o[o[a+4>>2]+3596>>2]=0;c=o[a+4>>2]}d=o[c+68>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+68>>2]=0;c=o[a+4>>2]}d=o[c+3600>>2];if(d){X(d);o[o[a+4>>2]+100>>2]=0;o[o[a+4>>2]+3600>>2]=0;c=o[a+4>>2]}d=o[c+72>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+72>>2]=0;c=o[a+4>>2]}d=o[c+3604>>2];if(d){X(d);o[o[a+4>>2]+104>>2]=0;o[o[a+4>>2]+3604>>2]=0;c=o[a+4>>2]}d=o[c+76>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+76>>2]=0;c=o[a+4>>2]}d=o[c+3608>>2];if(d){X(d);o[o[a+4>>2]+108>>2]=0;o[o[a+4>>2]+3608>>2]=0;c=o[a+4>>2]}d=o[c+80>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+80>>2]=0;c=o[a+4>>2]}d=o[c+3612>>2];if(d){X(d);o[o[a+4>>2]+112>>2]=0;o[o[a+4>>2]+3612>>2]=0;c=o[a+4>>2]}d=o[c+84>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+84>>2]=0;c=o[a+4>>2]}d=o[c+3616>>2];if(d){X(d);o[o[a+4>>2]+116>>2]=0;o[o[a+4>>2]+3616>>2]=0;c=o[a+4>>2]}d=o[c+88>>2];if(d){X(d+ -16|0);o[o[a+4>>2]+88>>2]=0;c=o[a+4>>2]}d=o[c+3620>>2];if(d){X(d);o[o[a+4>>2]+120>>2]=0;o[o[a+4>>2]+3620>>2]=0}x:{if(!e){break x}if(h>>>0>4294967291){break b}d=h+4|0;if((d&1073741823)!=(d|0)){break b}c=d<<2;g=0;while(1){d=da(c);if(!d){break b}o[d>>2]=0;o[d+4>>2]=0;o[d+8>>2]=0;o[d+12>>2]=0;j=g<<2;o[(j+o[a+4>>2]|0)+60>>2]=d+16;d=j+o[a+4>>2]|0;if(ta(h,d+3592|0,d+92|0)){g=g+1|0;if((e|0)==(g|0)){break x}continue}break}o[o[a>>2]>>2]=8;break c}c=o[a+4>>2];o[c+224>>2]=e;o[c+220>>2]=h;e=o[c+1144>>2]}y:{if(e){z=o[1412];B=-1<<z^-1;w=o[1406];A=o[1405];C=o[1413];d=0;while(1){g=o[c+1152>>2];z:{A:{switch(o[c+1148>>2]+ -1|0){case 0:g=((d|0)==1)+g|0;break z;case 1:g=!d+g|0;break z;case 2:break A;default:break z}}g=((d|0)==1)+g|0}if(!Y(o[c+56>>2],f+28|0,8)){break c}c=o[f+28>>2];o[f+28>>2]=c&254;t=c&1;B:{if(t){if(!eb(o[o[a+4>>2]+56>>2],f+32|0)){break c}c=o[a+4>>2];e=o[f+32>>2]+1|0;o[(c+u(d,292)|0)+1464>>2]=e;if(g>>>0<=e>>>0){break c}g=g-e|0;break B}c=o[a+4>>2];o[(c+u(d,292)|0)+1464>>2]=0}e=o[f+28>>2];C:{if(e&128){if(!o[c+3632>>2]){l[o[c+32>>2]](a,0,o[c+48>>2])}o[o[a>>2]>>2]=2;break C}D:{E:{F:{switch(e|0){case 0:e=o[((d<<2)+c|0)+60>>2];h=u(d,292)+c|0;o[h+1176>>2]=0;if(!xa(o[c+56>>2],f+32|0,g)){break c}o[h+1180>>2]=o[f+32>>2];c=0;g=o[a+4>>2];if(!o[g+1136>>2]){break E}while(1){o[e+(c<<2)>>2]=o[f+32>>2];c=c+1|0;if(c>>>0<r[g+1136>>2]){continue}break}break E;case 2:e=(c+1136|0)+u(d,292)|0;h=e;j=d<<2;n=o[(j+c|0)+92>>2];o[e+44>>2]=n;o[e+40>>2]=1;e=0;if(o[c+1136>>2]){while(1){if(!xa(o[c+56>>2],f+32|0,g)){break c}o[n+(e<<2)>>2]=o[f+32>>2];e=e+1|0;c=o[a+4>>2];k=o[c+1136>>2];if(e>>>0<k>>>0){continue}break}e=k<<2}ca(o[(c+j|0)+60>>2],o[h+44>>2],e);break E;default:break F}}if(e>>>0<=15){G:{if(!o[c+3632>>2]){l[o[c+32>>2]](a,3,o[c+48>>2]);break G}o[c+6152>>2]=o[c+6152>>2]+1}o[o[a>>2]>>2]=2;break C}if(e>>>0<=24){h=u(d,292)+c|0;o[h+1176>>2]=2;n=d<<2;k=o[(n+c|0)+92>>2];j=e>>>1&7;o[h+1192>>2]=j;o[h+1212>>2]=k;e=o[c+56>>2];if(j){k=h+1196|0;c=0;while(1){if(!xa(e,f+32|0,g)){break c}o[k+(c<<2)>>2]=o[f+32>>2];e=o[o[a+4>>2]+56>>2];c=c+1|0;if((j|0)!=(c|0)){continue}break}}if(!Y(e,f+16|0,A)){break c}g=h+1180|0;e=o[f+16>>2];o[g>>2]=e;c=o[a+4>>2];H:{I:{if(e>>>0<=1){if(!Y(o[c+56>>2],f+16|0,w)){break c}c=o[a+4>>2];e=o[f+16>>2];if(o[c+1136>>2]>>>e>>>0>=j>>>0){break I}if(!o[c+3632>>2]){l[o[c+32>>2]](a,0,o[c+48>>2])}o[o[a>>2]>>2]=2;break H}J:{if(!o[c+3632>>2]){l[o[c+32>>2]](a,3,o[c+48>>2]);break J}o[c+6152>>2]=o[c+6152>>2]+1}o[o[a>>2]>>2]=2;break H}o[h+1184>>2]=e;c=u(d,12);o[h+1188>>2]=(c+o[a+4>>2]|0)+124;g=o[g>>2];if(g>>>0<2){k=c;c=o[a+4>>2];if(!nb(a,j,e,(k+c|0)+124|0,o[(c+n|0)+92>>2],(g|0)==1)){break c}}c=j<<2;ca(o[(n+o[a+4>>2]|0)+60>>2],h+1196|0,c);e=o[a+4>>2];g=e+n|0;me(o[g+92>>2],o[e+1136>>2]-j|0,j,c+o[g+60>>2]|0)}if(o[o[a>>2]>>2]==2){break C}if(t){break D}break C}if(e>>>0<=63){K:{if(!o[c+3632>>2]){l[o[c+32>>2]](a,3,o[c+48>>2]);break K}o[c+6152>>2]=o[c+6152>>2]+1}o[o[a>>2]>>2]=2;break C}h=u(d,292)+c|0;o[h+1176>>2]=3;n=d<<2;s=o[(n+c|0)+92>>2];k=e>>>1&31;j=k+1|0;o[h+1192>>2]=j;o[h+1460>>2]=s;e=o[c+56>>2];c=0;while(1){if(!xa(e,f+32|0,g)){break c}o[(h+(c<<2)|0)+1332>>2]=o[f+32>>2];s=(c|0)!=(k|0);e=o[o[a+4>>2]+56>>2];c=c+1|0;if(s){continue}break}if(!Y(e,f+16|0,z)){break c}c=o[f+16>>2];L:{if((c|0)==(B|0)){c=o[a+4>>2];if(!o[c+3632>>2]){l[o[c+32>>2]](a,0,o[c+48>>2])}o[o[a>>2]>>2]=2;break L}y=h+1196|0;o[y>>2]=c+1;if(!xa(o[o[a+4>>2]+56>>2],f+32|0,C)){break c}c=o[f+32>>2];if((c|0)<=-1){c=o[a+4>>2];if(!o[c+3632>>2]){l[o[c+32>>2]](a,0,o[c+48>>2])}o[o[a>>2]>>2]=2;break L}s=h+1200|0;o[s>>2]=c;e=o[o[a+4>>2]+56>>2];c=0;while(1){if(!xa(e,f+32|0,o[y>>2])){break c}o[(h+(c<<2)|0)+1204>>2]=o[f+32>>2];v=(c|0)!=(k|0);e=o[o[a+4>>2]+56>>2];c=c+1|0;if(v){continue}break}if(!Y(e,f+16|0,A)){break c}v=h+1180|0;e=o[f+16>>2];o[v>>2]=e;c=o[a+4>>2];M:{if(e>>>0<=1){if(!Y(o[c+56>>2],f+16|0,w)){break c}c=o[a+4>>2];e=o[f+16>>2];if(o[c+1136>>2]>>>e>>>0>k>>>0){break M}if(!o[c+3632>>2]){l[o[c+32>>2]](a,0,o[c+48>>2])}o[o[a>>2]>>2]=2;break L}N:{if(!o[c+3632>>2]){l[o[c+32>>2]](a,3,o[c+48>>2]);break N}o[c+6152>>2]=o[c+6152>>2]+1}o[o[a>>2]>>2]=2;break L}o[h+1184>>2]=e;c=u(d,12);o[h+1188>>2]=(c+o[a+4>>2]|0)+124;k=o[v>>2];if(k>>>0<2){v=c;c=o[a+4>>2];if(!nb(a,j,e,(v+c|0)+124|0,o[(c+n|0)+92>>2],(k|0)==1)){break c}}e=j<<2;ca(o[(n+o[a+4>>2]|0)+60>>2],h+1332|0,e);O:{k=o[y>>2];if(k+((x(j)^31)+g|0)>>>0<=32){c=o[a+4>>2];if(g>>>0>16|k>>>0>16){break O}g=c+n|0;l[o[c+44>>2]](o[g+92>>2],o[c+1136>>2]-j|0,h+1204|0,j,o[s>>2],e+o[g+60>>2]|0);break L}c=o[a+4>>2];g=c+n|0;l[o[c+40>>2]](o[g+92>>2],o[c+1136>>2]-j|0,h+1204|0,j,o[s>>2],e+o[g+60>>2]|0);break L}g=c+n|0;l[o[c+36>>2]](o[g+92>>2],o[c+1136>>2]-j|0,h+1204|0,j,o[s>>2],e+o[g+60>>2]|0)}if(!t|o[o[a>>2]>>2]==2){break C}break D}if(!t){break C}}e=o[a+4>>2];c=o[(e+u(d,292)|0)+1464>>2];o[f+28>>2]=c;if(!o[e+1136>>2]){break C}g=o[(e+(d<<2)|0)+60>>2];o[g>>2]=o[g>>2]<<c;c=1;if(r[e+1136>>2]<2){break C}while(1){h=g+(c<<2)|0;o[h>>2]=o[h>>2]<<o[f+28>>2];c=c+1|0;if(c>>>0<r[e+1136>>2]){continue}break}}if(o[o[a>>2]>>2]==2){break y}d=d+1|0;c=o[a+4>>2];if(d>>>0<r[c+1144>>2]){continue}break}}P:{if(!(p[o[c+56>>2]+20|0]&7)){break P}o[f+32>>2]=0;d=o[o[a+4>>2]+56>>2];if(!Y(d,f+32|0,8-(o[d+20>>2]&7)|0)){break c}if(!o[f+32>>2]){break P}d=o[a+4>>2];if(!o[d+3632>>2]){l[o[d+32>>2]](a,0,o[d+48>>2])}o[o[a>>2]>>2]=2}if(o[o[a>>2]>>2]==2){break a}d=ze(o[o[a+4>>2]+56>>2]);i=0;if(!Y(o[o[a+4>>2]+56>>2],f+16|0,o[1404])){break a}Q:{if((d|0)==o[f+16>>2]){R:{S:{T:{d=o[a+4>>2];switch(o[d+1148>>2]+ -1|0){case 2:break R;case 0:break S;case 1:break T;default:break Q}}if(!o[d+1136>>2]){break Q}c=o[d- -64>>2];e=o[d+60>>2];g=0;while(1){h=g<<2;j=h+e|0;o[j>>2]=o[j>>2]+o[c+h>>2];g=g+1|0;if(g>>>0<r[d+1136>>2]){continue}break}break Q}if(!o[d+1136>>2]){break Q}c=o[d- -64>>2];e=o[d+60>>2];g=0;while(1){h=g<<2;j=h+c|0;o[j>>2]=o[e+h>>2]-o[j>>2];g=g+1|0;if(g>>>0<r[d+1136>>2]){continue}break}break Q}if(!o[d+1136>>2]){break Q}j=o[d- -64>>2];n=o[d+60>>2];g=0;while(1){e=g<<2;c=e+n|0;t=e+j|0;e=o[t>>2];h=e&1|o[c>>2]<<1;o[c>>2]=e+h>>1;o[t>>2]=h-e>>1;g=g+1|0;if(g>>>0<r[d+1136>>2]){continue}break}break Q}d=o[a+4>>2];if(!o[d+3632>>2]){l[o[d+32>>2]](a,2,o[d+48>>2])}c=o[a+4>>2];if(!o[c+1144>>2]){break Q}g=0;while(1){fa(o[((g<<2)+c|0)+60>>2],o[c+1136>>2]<<2);g=g+1|0;c=o[a+4>>2];if(g>>>0<r[c+1144>>2]){continue}break}}o[b>>2]=1;c=o[a+4>>2];b=o[c+232>>2];if(b){o[c+228>>2]=b}b=o[a>>2];n=o[c+1144>>2];o[b+8>>2]=n;o[b+12>>2]=o[c+1148>>2];j=o[c+1152>>2];o[b+16>>2]=j;o[b+20>>2]=o[c+1140>>2];e=o[c+1136>>2];o[b+24>>2]=e;b=c+1160|0;d=o[b>>2];t=o[b+4>>2];b=t;k=d+e|0;if(k>>>0<e>>>0){b=b+1|0}w=k;o[c+240>>2]=k;h=b;o[c+244>>2]=h;k=c+60|0;s=c+1136|0;U:{V:{W:{if(o[c+3632>>2]){o[c+6156>>2]=1;b=o[c+6144>>2];j=o[c+6148>>2];ca(c+3752|0,s,2384);if((j|0)==(t|0)&b>>>0<d>>>0|j>>>0<t>>>0|((h|0)==(j|0)&b>>>0>=w>>>0|j>>>0>h>>>0)){break U}g=0;h=o[a+4>>2];o[h+3632>>2]=0;b=b-d|0;d=b;if(d){if(n){while(1){e=g<<2;o[e+(f+32|0)>>2]=o[(c+e|0)+60>>2]+(d<<2);g=g+1|0;if((n|0)!=(g|0)){continue}break}}o[h+3752>>2]=o[h+3752>>2]-d;c=h+3776|0;e=c;h=c;d=o[c+4>>2];c=b+o[c>>2]|0;if(c>>>0<b>>>0){d=d+1|0}o[h>>2]=c;o[e+4>>2]=d;b=o[a+4>>2];b=l[o[b+24>>2]](a,b+3752|0,f+32|0,o[b+48>>2])|0;break W}b=l[o[h+24>>2]](a,s,k,o[h+48>>2])|0;break W}X:{if(!o[c+248>>2]){o[c+3624>>2]=0;break X}if(!o[c+3624>>2]){break X}if(!$b(c+3636|0,k,n,e,j+7>>>3|0)){break V}c=o[a+4>>2]}b=l[o[c+24>>2]](a,s,k,o[c+48>>2])|0}if(!b){break U}}o[o[a>>2]>>2]=7;break a}o[o[a>>2]>>2]=2}i=1;break a}i=0;break a}o[o[a>>2]>>2]=8;i=0}N=f- -64|0;return i}function da(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;l=N-16|0;N=l;a:{b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{if(a>>>0<=244){f=o[2897];g=a>>>0<11?16:a+11&-8;a=g>>>3|0;b=f>>>a|0;if(b&3){c=a+((b^-1)&1)|0;e=c<<3;b=o[e+11636>>2];a=b+8|0;d=o[b+8>>2];e=e+11628|0;l:{if((d|0)==(e|0)){m=11588,n=He(-2,c)&f,o[m>>2]=n;break l}o[d+12>>2]=e;o[e+8>>2]=d}c=c<<3;o[b+4>>2]=c|3;b=b+c|0;o[b+4>>2]=o[b+4>>2]|1;break a}i=o[2899];if(g>>>0<=i>>>0){break k}if(b){c=2<<a;a=(0-c|c)&b<<a;a=(0-a&a)+ -1|0;b=a>>>12&16;c=b;a=a>>>b|0;b=a>>>5&8;c=c|b;a=a>>>b|0;b=a>>>2&4;c=c|b;a=a>>>b|0;b=a>>>1&2;c=c|b;a=a>>>b|0;b=a>>>1&1;c=(c|b)+(a>>>b|0)|0;d=c<<3;b=o[d+11636>>2];a=o[b+8>>2];d=d+11628|0;m:{if((a|0)==(d|0)){f=He(-2,c)&f;o[2897]=f;break m}o[a+12>>2]=d;o[d+8>>2]=a}a=b+8|0;o[b+4>>2]=g|3;h=b+g|0;c=c<<3;e=c-g|0;o[h+4>>2]=e|1;o[b+c>>2]=e;if(i){c=i>>>3|0;b=(c<<3)+11628|0;d=o[2902];c=1<<c;n:{if(!(c&f)){o[2897]=c|f;c=b;break n}c=o[b+8>>2]}o[b+8>>2]=d;o[c+12>>2]=d;o[d+12>>2]=b;o[d+8>>2]=c}o[2902]=h;o[2899]=e;break a}k=o[2898];if(!k){break k}a=(k&0-k)+ -1|0;b=a>>>12&16;c=b;a=a>>>b|0;b=a>>>5&8;c=c|b;a=a>>>b|0;b=a>>>2&4;c=c|b;a=a>>>b|0;b=a>>>1&2;c=c|b;a=a>>>b|0;b=a>>>1&1;b=o[((c|b)+(a>>>b|0)<<2)+11892>>2];d=(o[b+4>>2]&-8)-g|0;c=b;while(1){o:{a=o[c+16>>2];if(!a){a=o[c+20>>2];if(!a){break o}}e=(o[a+4>>2]&-8)-g|0;c=e>>>0<d>>>0;d=c?e:d;b=c?a:b;c=a;continue}break}j=o[b+24>>2];e=o[b+12>>2];if((e|0)!=(b|0)){a=o[b+8>>2];o[a+12>>2]=e;o[e+8>>2]=a;break b}c=b+20|0;a=o[c>>2];if(!a){a=o[b+16>>2];if(!a){break j}c=b+16|0}while(1){h=c;e=a;c=a+20|0;a=o[c>>2];if(a){continue}c=e+16|0;a=o[e+16>>2];if(a){continue}break}o[h>>2]=0;break b}g=-1;if(a>>>0>4294967231){break k}b=a+11|0;g=b&-8;i=o[2898];if(!i){break k}c=0-g|0;b=b>>>8|0;f=0;p:{if(!b){break p}f=31;if(g>>>0>16777215){break p}d=b+1048320>>>16&8;b=b<<d;a=b+520192>>>16&4;f=b<<a;b=f+245760>>>16&2;a=(f<<b>>>15|0)-(b|(a|d))|0;f=(a<<1|g>>>a+21&1)+28|0}d=o[(f<<2)+11892>>2];q:{r:{s:{if(!d){a=0;break s}b=g<<((f|0)==31?0:25-(f>>>1|0)|0);a=0;while(1){t:{h=(o[d+4>>2]&-8)-g|0;if(h>>>0>=c>>>0){break t}e=d;c=h;if(c){break t}c=0;a=d;break r}h=o[d+20>>2];d=o[((b>>>29&4)+d|0)+16>>2];a=h?(h|0)==(d|0)?a:h:a;b=b<<((d|0)!=0);if(d){continue}break}}if(!(a|e)){a=2<<f;a=(0-a|a)&i;if(!a){break k}a=(a&0-a)+ -1|0;b=a>>>12&16;d=b;a=a>>>b|0;b=a>>>5&8;d=d|b;a=a>>>b|0;b=a>>>2&4;d=d|b;a=a>>>b|0;b=a>>>1&2;d=d|b;a=a>>>b|0;b=a>>>1&1;a=o[((d|b)+(a>>>b|0)<<2)+11892>>2]}if(!a){break q}}while(1){d=(o[a+4>>2]&-8)-g|0;b=d>>>0<c>>>0;c=b?d:c;e=b?a:e;b=o[a+16>>2];if(b){a=b}else{a=o[a+20>>2]}if(a){continue}break}}if(!e|c>>>0>=o[2899]-g>>>0){break k}h=o[e+24>>2];b=o[e+12>>2];if((e|0)!=(b|0)){a=o[e+8>>2];o[a+12>>2]=b;o[b+8>>2]=a;break c}d=e+20|0;a=o[d>>2];if(!a){a=o[e+16>>2];if(!a){break i}d=e+16|0}while(1){f=d;b=a;d=a+20|0;a=o[d>>2];if(a){continue}d=b+16|0;a=o[b+16>>2];if(a){continue}break}o[f>>2]=0;break c}b=o[2899];if(b>>>0>=g>>>0){a=o[2902];c=b-g|0;u:{if(c>>>0>=16){o[2899]=c;d=a+g|0;o[2902]=d;o[d+4>>2]=c|1;o[a+b>>2]=c;o[a+4>>2]=g|3;break u}o[2902]=0;o[2899]=0;o[a+4>>2]=b|3;b=a+b|0;o[b+4>>2]=o[b+4>>2]|1}a=a+8|0;break a}d=o[2900];if(d>>>0>g>>>0){b=d-g|0;o[2900]=b;a=o[2903];c=a+g|0;o[2903]=c;o[c+4>>2]=b|1;o[a+4>>2]=g|3;a=a+8|0;break a}a=0;e=g+47|0;c=e;if(o[3015]){b=o[3017]}else{o[3018]=-1;o[3019]=-1;o[3016]=4096;o[3017]=4096;o[3015]=l+12&-16^1431655768;o[3020]=0;o[3008]=0;b=4096}f=c+b|0;h=0-b|0;c=f&h;if(c>>>0<=g>>>0){break a}b=o[3007];if(b){i=o[3005];j=i+c|0;if(j>>>0<=i>>>0|j>>>0>b>>>0){break a}}if(p[12032]&4){break f}v:{w:{b=o[2903];if(b){a=12036;while(1){i=o[a>>2];if(i+o[a+4>>2]>>>0>b>>>0?i>>>0<=b>>>0:0){break w}a=o[a+8>>2];if(a){continue}break}}b=ya(0);if((b|0)==-1){break g}f=c;a=o[3016];d=a+ -1|0;if(d&b){f=(c-b|0)+(b+d&0-a)|0}if(f>>>0<=g>>>0|f>>>0>2147483646){break g}a=o[3007];if(a){d=o[3005];h=d+f|0;if(h>>>0<=d>>>0|h>>>0>a>>>0){break g}}a=ya(f);if((b|0)!=(a|0)){break v}break e}f=h&f-d;if(f>>>0>2147483646){break g}b=ya(f);if((b|0)==(o[a>>2]+o[a+4>>2]|0)){break h}a=b}if(!((a|0)==-1|g+48>>>0<=f>>>0)){b=o[3017];b=b+(e-f|0)&0-b;if(b>>>0>2147483646){b=a;break e}if((ya(b)|0)!=-1){f=b+f|0;b=a;break e}ya(0-f|0);break g}b=a;if((a|0)!=-1){break e}break g}e=0;break b}b=0;break c}if((b|0)!=-1){break e}}o[3008]=o[3008]|4}if(c>>>0>2147483646){break d}b=ya(c);a=ya(0);if(b>>>0>=a>>>0|(b|0)==-1|(a|0)==-1){break d}f=a-b|0;if(f>>>0<=g+40>>>0){break d}}a=o[3005]+f|0;o[3005]=a;if(a>>>0>r[3006]){o[3006]=a}x:{y:{z:{c=o[2903];if(c){a=12036;while(1){d=o[a>>2];e=o[a+4>>2];if((d+e|0)==(b|0)){break z}a=o[a+8>>2];if(a){continue}break}break y}a=o[2901];if(!(b>>>0>=a>>>0?a:0)){o[2901]=b}a=0;o[3010]=f;o[3009]=b;o[2905]=-1;o[2906]=o[3015];o[3012]=0;while(1){c=a<<3;d=c+11628|0;o[c+11636>>2]=d;o[c+11640>>2]=d;a=a+1|0;if((a|0)!=32){continue}break}a=f+ -40|0;c=b+8&7?-8-b&7:0;d=a-c|0;o[2900]=d;c=b+c|0;o[2903]=c;o[c+4>>2]=d|1;o[(a+b|0)+4>>2]=40;o[2904]=o[3019];break x}if(p[a+12|0]&8|b>>>0<=c>>>0|d>>>0>c>>>0){break y}o[a+4>>2]=e+f;a=c+8&7?-8-c&7:0;b=a+c|0;o[2903]=b;d=o[2900]+f|0;a=d-a|0;o[2900]=a;o[b+4>>2]=a|1;o[(c+d|0)+4>>2]=40;o[2904]=o[3019];break x}e=o[2901];if(b>>>0<e>>>0){o[2901]=b;e=0}d=b+f|0;a=12036;A:{B:{C:{D:{E:{F:{while(1){if((d|0)!=o[a>>2]){a=o[a+8>>2];if(a){continue}break F}break}if(!(p[a+12|0]&8)){break E}}a=12036;while(1){d=o[a>>2];if(d>>>0<=c>>>0){e=d+o[a+4>>2]|0;if(e>>>0>c>>>0){break D}}a=o[a+8>>2];continue}}o[a>>2]=b;o[a+4>>2]=o[a+4>>2]+f;j=(b+8&7?-8-b&7:0)+b|0;o[j+4>>2]=g|3;b=d+(d+8&7?-8-d&7:0)|0;a=(b-j|0)-g|0;h=g+j|0;if((b|0)==(c|0)){o[2903]=h;a=o[2900]+a|0;o[2900]=a;o[h+4>>2]=a|1;break B}if(o[2902]==(b|0)){o[2902]=h;a=o[2899]+a|0;o[2899]=a;o[h+4>>2]=a|1;o[a+h>>2]=a;break B}c=o[b+4>>2];if((c&3)==1){k=c&-8;G:{if(c>>>0<=255){e=c>>>3|0;c=o[b+8>>2];d=o[b+12>>2];if((d|0)==(c|0)){m=11588,n=o[2897]&He(-2,e),o[m>>2]=n;break G}o[c+12>>2]=d;o[d+8>>2]=c;break G}i=o[b+24>>2];f=o[b+12>>2];H:{if((f|0)!=(b|0)){c=o[b+8>>2];o[c+12>>2]=f;o[f+8>>2]=c;break H}I:{d=b+20|0;g=o[d>>2];if(g){break I}d=b+16|0;g=o[d>>2];if(g){break I}f=0;break H}while(1){c=d;f=g;d=g+20|0;g=o[d>>2];if(g){continue}d=f+16|0;g=o[f+16>>2];if(g){continue}break}o[c>>2]=0}if(!i){break G}c=o[b+28>>2];d=(c<<2)+11892|0;J:{if(o[d>>2]==(b|0)){o[d>>2]=f;if(f){break J}m=11592,n=o[2898]&He(-2,c),o[m>>2]=n;break G}o[i+(o[i+16>>2]==(b|0)?16:20)>>2]=f;if(!f){break G}}o[f+24>>2]=i;c=o[b+16>>2];if(c){o[f+16>>2]=c;o[c+24>>2]=f}c=o[b+20>>2];if(!c){break G}o[f+20>>2]=c;o[c+24>>2]=f}b=b+k|0;a=a+k|0}o[b+4>>2]=o[b+4>>2]&-2;o[h+4>>2]=a|1;o[a+h>>2]=a;if(a>>>0<=255){b=a>>>3|0;a=(b<<3)+11628|0;c=o[2897];b=1<<b;K:{if(!(c&b)){o[2897]=b|c;b=a;break K}b=o[a+8>>2]}o[a+8>>2]=h;o[b+12>>2]=h;o[h+12>>2]=a;o[h+8>>2]=b;break B}c=h;d=a>>>8|0;b=0;L:{if(!d){break L}b=31;if(a>>>0>16777215){break L}e=d+1048320>>>16&8;d=d<<e;b=d+520192>>>16&4;g=d<<b;d=g+245760>>>16&2;b=(g<<d>>>15|0)-(d|(b|e))|0;b=(b<<1|a>>>b+21&1)+28|0}o[c+28>>2]=b;o[h+16>>2]=0;o[h+20>>2]=0;c=(b<<2)+11892|0;d=o[2898];e=1<<b;M:{if(!(d&e)){o[2898]=d|e;o[c>>2]=h;break M}d=a<<((b|0)==31?0:25-(b>>>1|0)|0);b=o[c>>2];while(1){c=b;if((o[b+4>>2]&-8)==(a|0)){break C}b=d>>>29|0;d=d<<1;e=(b&4)+c|0;b=o[e+16>>2];if(b){continue}break}o[e+16>>2]=h}o[h+24>>2]=c;o[h+12>>2]=h;o[h+8>>2]=h;break B}a=f+ -40|0;d=b+8&7?-8-b&7:0;h=a-d|0;o[2900]=h;d=b+d|0;o[2903]=d;o[d+4>>2]=h|1;o[(a+b|0)+4>>2]=40;o[2904]=o[3019];a=(e+(e+ -39&7?39-e&7:0)|0)+ -47|0;d=a>>>0<c+16>>>0?c:a;o[d+4>>2]=27;a=o[3012];o[d+16>>2]=o[3011];o[d+20>>2]=a;a=o[3010];o[d+8>>2]=o[3009];o[d+12>>2]=a;o[3011]=d+8;o[3010]=f;o[3009]=b;o[3012]=0;a=d+24|0;while(1){o[a+4>>2]=7;b=a+8|0;a=a+4|0;if(e>>>0>b>>>0){continue}break}if((c|0)==(d|0)){break x}o[d+4>>2]=o[d+4>>2]&-2;e=d-c|0;o[c+4>>2]=e|1;o[d>>2]=e;if(e>>>0<=255){b=e>>>3|0;a=(b<<3)+11628|0;d=o[2897];b=1<<b;N:{if(!(d&b)){o[2897]=b|d;b=a;break N}b=o[a+8>>2]}o[a+8>>2]=c;o[b+12>>2]=c;o[c+12>>2]=a;o[c+8>>2]=b;break x}o[c+16>>2]=0;o[c+20>>2]=0;b=c;d=e>>>8|0;a=0;O:{if(!d){break O}a=31;if(e>>>0>16777215){break O}f=d+1048320>>>16&8;d=d<<f;a=d+520192>>>16&4;h=d<<a;d=h+245760>>>16&2;a=(h<<d>>>15|0)-(d|(a|f))|0;a=(a<<1|e>>>a+21&1)+28|0}o[b+28>>2]=a;b=(a<<2)+11892|0;d=o[2898];f=1<<a;P:{if(!(d&f)){o[2898]=d|f;o[b>>2]=c;o[c+24>>2]=b;break P}a=e<<((a|0)==31?0:25-(a>>>1|0)|0);b=o[b>>2];while(1){d=b;if((e|0)==(o[b+4>>2]&-8)){break A}b=a>>>29|0;a=a<<1;f=d+(b&4)|0;b=o[f+16>>2];if(b){continue}break}o[f+16>>2]=c;o[c+24>>2]=d}o[c+12>>2]=c;o[c+8>>2]=c;break x}a=o[c+8>>2];o[a+12>>2]=h;o[c+8>>2]=h;o[h+24>>2]=0;o[h+12>>2]=c;o[h+8>>2]=a}a=j+8|0;break a}a=o[d+8>>2];o[a+12>>2]=c;o[d+8>>2]=c;o[c+24>>2]=0;o[c+12>>2]=d;o[c+8>>2]=a}a=o[2900];if(a>>>0<=g>>>0){break d}b=a-g|0;o[2900]=b;a=o[2903];c=a+g|0;o[2903]=c;o[c+4>>2]=b|1;o[a+4>>2]=g|3;a=a+8|0;break a}o[2896]=48;a=0;break a}Q:{if(!h){break Q}a=o[e+28>>2];d=(a<<2)+11892|0;R:{if(o[d>>2]==(e|0)){o[d>>2]=b;if(b){break R}i=He(-2,a)&i;o[2898]=i;break Q}o[h+(o[h+16>>2]==(e|0)?16:20)>>2]=b;if(!b){break Q}}o[b+24>>2]=h;a=o[e+16>>2];if(a){o[b+16>>2]=a;o[a+24>>2]=b}a=o[e+20>>2];if(!a){break Q}o[b+20>>2]=a;o[a+24>>2]=b}S:{if(c>>>0<=15){a=c+g|0;o[e+4>>2]=a|3;a=a+e|0;o[a+4>>2]=o[a+4>>2]|1;break S}o[e+4>>2]=g|3;d=e+g|0;o[d+4>>2]=c|1;o[c+d>>2]=c;if(c>>>0<=255){b=c>>>3|0;a=(b<<3)+11628|0;c=o[2897];b=1<<b;T:{if(!(c&b)){o[2897]=b|c;b=a;break T}b=o[a+8>>2]}o[a+8>>2]=d;o[b+12>>2]=d;o[d+12>>2]=a;o[d+8>>2]=b;break S}b=d;g=c>>>8|0;a=0;U:{if(!g){break U}a=31;if(c>>>0>16777215){break U}f=g+1048320>>>16&8;g=g<<f;a=g+520192>>>16&4;h=g<<a;g=h+245760>>>16&2;a=(h<<g>>>15|0)-(g|(a|f))|0;a=(a<<1|c>>>a+21&1)+28|0}o[b+28>>2]=a;o[d+16>>2]=0;o[d+20>>2]=0;b=(a<<2)+11892|0;V:{g=1<<a;W:{if(!(g&i)){o[2898]=g|i;o[b>>2]=d;break W}a=c<<((a|0)==31?0:25-(a>>>1|0)|0);g=o[b>>2];while(1){b=g;if((o[b+4>>2]&-8)==(c|0)){break V}g=a>>>29|0;a=a<<1;f=(g&4)+b|0;g=o[f+16>>2];if(g){continue}break}o[f+16>>2]=d}o[d+24>>2]=b;o[d+12>>2]=d;o[d+8>>2]=d;break S}a=o[b+8>>2];o[a+12>>2]=d;o[b+8>>2]=d;o[d+24>>2]=0;o[d+12>>2]=b;o[d+8>>2]=a}a=e+8|0;break a}X:{if(!j){break X}a=o[b+28>>2];c=(a<<2)+11892|0;Y:{if(o[c>>2]==(b|0)){o[c>>2]=e;if(e){break Y}m=11592,n=He(-2,a)&k,o[m>>2]=n;break X}o[j+(o[j+16>>2]==(b|0)?16:20)>>2]=e;if(!e){break X}}o[e+24>>2]=j;a=o[b+16>>2];if(a){o[e+16>>2]=a;o[a+24>>2]=e}a=o[b+20>>2];if(!a){break X}o[e+20>>2]=a;o[a+24>>2]=e}Z:{if(d>>>0<=15){a=d+g|0;o[b+4>>2]=a|3;a=a+b|0;o[a+4>>2]=o[a+4>>2]|1;break Z}o[b+4>>2]=g|3;g=b+g|0;o[g+4>>2]=d|1;o[d+g>>2]=d;if(i){c=i>>>3|0;a=(c<<3)+11628|0;e=o[2902];c=1<<c;_:{if(!(c&f)){o[2897]=c|f;c=a;break _}c=o[a+8>>2]}o[a+8>>2]=e;o[c+12>>2]=e;o[e+12>>2]=a;o[e+8>>2]=c}o[2902]=g;o[2899]=d}a=b+8|0}N=l+16|0;return a|0}function vb(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,m=0,n=0,p=0,q=0,t=0,u=0,v=0,w=0;t=N-176|0;N=t;i=13;j=o[a>>2];a:{if(o[j>>2]!=1){break a}i=3;if(!c|(e?0:d)){break a}i=4;m=o[j+24>>2];if(m+ -1>>>0>7){break a}b:{c:{if((m|0)!=2){o[j+16>>2]=0;break c}if(o[j+16>>2]){break b}}o[j+20>>2]=0}m=o[j+28>>2];if(m>>>0>=32){o[j+16>>2]=0;i=5;break a}i=5;if(m+ -4>>>0>20){break a}if(o[j+32>>2]+ -1>>>0>=655350){i=6;break a}j=o[a>>2];k=o[j+36>>2];d:{if(!k){k=o[j+556>>2]?4096:1152;o[j+36>>2]=k;break d}i=7;if(k+ -16>>>0>65519){break a}}i=8;m=o[j+556>>2];if(m>>>0>32){break a}i=10;if(k>>>0<m>>>0){break a}m=o[j+560>>2];e:{if(!m){m=j;n=o[j+28>>2];f:{if(n>>>0<=15){n=n>>>0>5?(n>>>1|0)+2|0:5;break f}if((n|0)==16){n=7;if(k>>>0<193){break f}n=8;if(k>>>0<385){break f}n=9;if(k>>>0<577){break f}n=10;if(k>>>0<1153){break f}n=11;if(k>>>0<2305){break f}n=k>>>0<4609?12:13;break f}n=13;if(k>>>0<385){break f}n=k>>>0<1153?14:15}o[m+560>>2]=n;break e}i=9;if(m+ -5>>>0>10){break a}}g:{if(!o[j+8>>2]){k=o[j+580>>2];break g}i=11;if(!((k>>>0<4609|r[j+32>>2]>48e3)&k>>>0<16385)){break a}if(!he(o[o[a>>2]+32>>2])){break a}j=o[a>>2];if(He(o[j+28>>2]+ -8|0,30)>>>0>4){break a}k=o[j+580>>2];if(k>>>0>8){break a}if(r[j+32>>2]>48e3){break g}if(r[j+36>>2]>4608|r[j+556>>2]>12){break a}}m=1<<o[1406];if(k>>>0>=m>>>0){k=m+ -1|0;o[j+580>>2]=k}if(r[j+576>>2]>=k>>>0){o[j+576>>2]=k}h:{if(!h){break h}k=o[j+600>>2];if(!k){break h}n=o[j+604>>2];if(n>>>0<2){break h}i=1;while(1){m=o[(i<<2)+k>>2];if(!(!m|o[m>>2]!=4)){while(1){j=(i<<2)+k|0;i=i+ -1|0;o[j>>2]=o[(i<<2)+k>>2];k=o[o[a>>2]+600>>2];if(i){continue}break}o[k>>2]=m;j=o[a>>2];break h}i=i+1|0;if((n|0)!=(i|0)){continue}break}}m=o[j+604>>2];i:{j:{k=o[j+600>>2];if(k){n=0;if(!m){break i}while(1){j=o[(n<<2)+k>>2];if(!(!j|o[j>>2]!=3)){o[o[a+4>>2]+7048>>2]=j+16;break j}n=n+1|0;if((m|0)!=(n|0)){continue}break}break j}i=12;if(m){break a}n=0;break i}j=0;n=0;m=0;while(1){i=12;k:{l:{m:{n:{o:{k=o[(q<<2)+k>>2];switch(o[k>>2]){case 0:break a;case 6:break l;case 5:break m;case 4:break n;case 3:break o;default:break k}}if(v){break a}v=1;n=p;m=j;if(ge(k+16|0)){break k}break a}n=1;m=j;if(!p){break k}break a}n=p;m=j;if(le(k+16|0,o[k+160>>2])){break k}break a}if(!ie(k+16|0)){break a}n=p;m=j;p:{switch(o[k+16>>2]+ -1|0){case 0:if(w){break a}m=o[k+20>>2];if(ib(m,10763)){if(ib(m,10773)){break a}}if(o[k+28>>2]!=32){break a}w=1;m=j;if(o[k+32>>2]==32){break k}break a;case 1:break p;default:break k}}m=1;if(j){break a}}q=q+1|0;j=o[a>>2];if(q>>>0>=r[j+604>>2]){break i}k=o[j+600>>2];j=m;p=n;continue}}k=0;q=o[a+4>>2];o[q>>2]=0;if(o[j+24>>2]){while(1){j=k<<2;o[(j+q|0)+4>>2]=0;o[(j+o[a+4>>2]|0)+7328>>2]=0;o[(j+o[a+4>>2]|0)+44>>2]=0;o[(j+o[a+4>>2]|0)+7368>>2]=0;q=o[a+4>>2];k=k+1|0;if(k>>>0<r[o[a>>2]+24>>2]){continue}break}}j=0;o[q+36>>2]=0;o[o[a+4>>2]+7360>>2]=0;o[o[a+4>>2]+76>>2]=0;o[o[a+4>>2]+7400>>2]=0;o[o[a+4>>2]+40>>2]=0;o[o[a+4>>2]+7364>>2]=0;o[o[a+4>>2]+80>>2]=0;o[o[a+4>>2]+7404>>2]=0;i=o[a+4>>2];k=o[a>>2];if(o[k+40>>2]){while(1){m=j<<2;o[(m+i|0)+84>>2]=0;o[(m+o[a+4>>2]|0)+7408>>2]=0;i=o[a+4>>2];j=j+1|0;k=o[a>>2];if(j>>>0<r[k+40>>2]){continue}break}}j=0;o[i+7536>>2]=0;o[i+212>>2]=0;if(o[k+24>>2]){while(1){m=j<<3;o[(m+i|0)+256>>2]=0;o[(m+o[a+4>>2]|0)+7540>>2]=0;o[(m+o[a+4>>2]|0)+260>>2]=0;o[(m+o[a+4>>2]|0)+7544>>2]=0;i=o[a+4>>2];o[(i+(j<<2)|0)+6768>>2]=0;j=j+1|0;if(j>>>0<r[o[a>>2]+24>>2]){continue}break}}o[i+320>>2]=0;o[o[a+4>>2]+7604>>2]=0;o[o[a+4>>2]+324>>2]=0;o[o[a+4>>2]+7608>>2]=0;j=o[a+4>>2];o[j+6800>>2]=0;o[j+328>>2]=0;o[o[a+4>>2]+7612>>2]=0;o[o[a+4>>2]+332>>2]=0;o[o[a+4>>2]+7616>>2]=0;j=o[a+4>>2];o[j+7620>>2]=0;o[j+7624>>2]=0;o[j+6848>>2]=0;o[j+6852>>2]=0;o[j+6804>>2]=0;m=o[a>>2];p=o[m+36>>2];i=o[m+32>>2];o[j+7052>>2]=0;o[j+7056>>2]=0;o[j+6864>>2]=0;m=j;u=+(i>>>0)*.4/+(p>>>0)+.5;q:{if(u<4294967296&u>=0){p=~~u>>>0;break q}p=0}o[m+6860>>2]=p?p:1;Xb(j+7156|0);i=o[a+4>>2];o[i+7244>>2]=12;o[i+7240>>2]=13;o[i+7236>>2]=12;o[i+7228>>2]=14;o[i+7224>>2]=15;o[i+7220>>2]=16;o[i+7232>>2]=17;k=o[a>>2];o[k>>2]=0;o[i+7260>>2]=h;r:{s:{t:{if(h){if(!Sd(k+632|0)){break t}k=o[a>>2];i=o[a+4>>2]}o[i+7276>>2]=c;o[i+7264>>2]=b;o[i+7288>>2]=g;o[i+7280>>2]=f;o[i+7272>>2]=e;o[i+7268>>2]=d;b=o[k+36>>2];if(r[i>>2]<b>>>0){d=b+5|0;u:{v:{w:{if(o[k+24>>2]){c=0;while(1){f=c<<2;e=f+o[a+4>>2]|0;g=ta(d,e+7328|0,e+4|0);e=o[(f+o[a+4>>2]|0)+4>>2];o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;o[e+12>>2]=0;e=f+o[a+4>>2]|0;o[e+4>>2]=o[e+4>>2]+16;if(!g){break w}c=c+1|0;if(c>>>0<r[o[a>>2]+24>>2]){continue}break}}c=o[a+4>>2];c=ta(d,c+7360|0,c+36|0);e=o[o[a+4>>2]+36>>2];o[e>>2]=0;o[e+4>>2]=0;o[e+8>>2]=0;o[e+12>>2]=0;e=o[a+4>>2];o[e+36>>2]=o[e+36>>2]+16;if(c){c=o[a+4>>2];c=ta(d,c+7364|0,c+40|0);d=o[o[a+4>>2]+40>>2];o[d>>2]=0;o[d+4>>2]=0;o[d+8>>2]=0;o[d+12>>2]=0;d=o[a+4>>2];o[d+40>>2]=o[d+40>>2]+16}if(!c){break w}d=o[a>>2];if(o[d+556>>2]){c=o[a+4>>2];if(o[d+40>>2]){i=0;while(1){c=(i<<2)+c|0;if(!ta(b,c+7408|0,c+84|0)){break w}c=o[a+4>>2];i=i+1|0;if(i>>>0<r[o[a>>2]+40>>2]){continue}break}}if(!ta(b,c+7536|0,c+212|0)){break w}}g=0;k=1;f=0;while(1){if(f>>>0<r[o[a>>2]+24>>2]){i=0;c=1;d=0;while(1){if(i&1){break w}h=c;c=(o[a+4>>2]+(f<<3)|0)+(d<<2)|0;e=ta(b,c+7540|0,c+256|0);h=h&(e|0)!=0;i=!e;d=1;c=0;if(h){continue}break}f=f+1|0;if(e){continue}break w}break}h=1;while(1){i=0;c=1;d=0;if(!h){break w}while(1){if(i&1){break w}f=c;c=(o[a+4>>2]+(g<<3)|0)+(d<<2)|0;e=ta(b,c+7604|0,c+320|0);f=f&(e|0)!=0;i=!e;d=1;c=0;if(f){continue}break}h=(e|0)!=0;c=k&h;g=1;k=0;if(c){continue}break}if(!e){break w}d=b<<1;c=o[a+4>>2];c=Xd(d,c+7620|0,c+6848|0);i=o[a>>2];e=o[i+572>>2];if(!e|!c){break v}c=o[a+4>>2];if(ta(d,c+7624|0,c+6852|0)){break u}}i=o[a>>2];break r}if(e|!c){break r}}i=o[a+4>>2];x:{if((b|0)==o[i>>2]){break x}c=o[a>>2];if(!o[c+556>>2]|!o[c+40>>2]){break x}i=0;while(1){y:{z:{A:{B:{C:{D:{E:{F:{G:{H:{I:{J:{K:{L:{M:{N:{O:{P:{Q:{c=(i<<4)+c|0;switch(o[c+44>>2]){case 16:break A;case 15:break B;case 14:break C;case 13:break D;case 12:break E;case 11:break F;case 10:break G;case 9:break H;case 8:break I;case 7:break J;case 6:break K;case 5:break L;case 4:break M;case 3:break N;case 2:break O;case 1:break P;case 0:break Q;default:break z}}jd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}id(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}hd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}gd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}fd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}ed(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}dd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b,s[c+48>>2]);break y}cd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}Lb(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}bd(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}ad(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}Zc(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}Yc(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}Xc(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b,s[c+48>>2]);break y}$c(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b,s[c+48>>2],s[c+52>>2],s[c+56>>2]);break y}_c(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b,s[c+48>>2],s[c+52>>2],s[c+56>>2]);break y}Wc(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b);break y}Lb(o[(o[a+4>>2]+(i<<2)|0)+84>>2],b)}i=i+1|0;c=o[a>>2];if(i>>>0<r[c+40>>2]){continue}break}i=o[a+4>>2]}o[i>>2]=b}b=o[i+6856>>2];o[b+16>>2]=0;o[b+8>>2]=8192;o[b+12>>2]=0;c=b;b=da(32768);o[c>>2]=b;d=o[a>>2];if(!b){o[d>>2]=8;i=1;break a}if(o[d+4>>2]){i=1;c=o[a+4>>2];b=o[d+36>>2]+1|0;o[c+11796>>2]=b;R:{if(!o[d+24>>2]){break R}b=Na(4,b);o[o[a+4>>2]+11764>>2]=b;d=o[a>>2];if(b){while(1){c=o[a+4>>2];if(i>>>0>=r[d+24>>2]){break R}b=Na(4,o[c+11796>>2]);o[(o[a+4>>2]+(i<<2)|0)+11764>>2]=b;i=i+1|0;d=o[a>>2];if(b){continue}break}}o[d>>2]=8;i=1;break a}o[c+11800>>2]=0;S:{c=o[c+11752>>2];if(c){break S}c=Pb();o[o[a+4>>2]+11752>>2]=c;if(c){break S}o[o[a>>2]>>2]=3;i=1;break a}b=Qb(c,18,0,0,0,0,19,20,21,a);d=o[a>>2];if(b){break s}c=!o[d+4>>2]}else{c=1}b=o[a+4>>2];o[b+7312>>2]=0;o[b+7316>>2]=0;o[b+7292>>2]=0;e=b+11816|0;o[e>>2]=0;o[e+4>>2]=0;e=b+11824|0;o[e>>2]=0;o[e+4>>2]=0;e=b+11832|0;o[e>>2]=0;o[e+4>>2]=0;o[b+11840>>2]=0;o[d+624>>2]=0;o[d+628>>2]=0;o[d+616>>2]=0;o[d+620>>2]=0;o[d+608>>2]=0;o[d+612>>2]=0;if(!c){o[b+11756>>2]=0}if(!_(o[b+6856>>2],o[1354],o[1355])){o[o[a>>2]>>2]=7;i=1;break a}i=1;if(!Fa(a,0,0)){break a}b=o[a+4>>2];c=o[a>>2];if(o[c+4>>2]){o[b+11756>>2]=1}o[b+6872>>2]=0;o[b+6876>>2]=0;o[b+6880>>2]=34;o[b+6888>>2]=o[c+36>>2];o[o[a+4>>2]+6892>>2]=o[o[a>>2]+36>>2];o[o[a+4>>2]+6896>>2]=0;o[o[a+4>>2]+6900>>2]=0;o[o[a+4>>2]+6904>>2]=o[o[a>>2]+32>>2];o[o[a+4>>2]+6908>>2]=o[o[a>>2]+24>>2];o[o[a+4>>2]+6912>>2]=o[o[a>>2]+28>>2];c=o[a>>2];d=o[c+596>>2];b=o[a+4>>2]+6920|0;o[b>>2]=o[c+592>>2];o[b+4>>2]=d;b=o[a+4>>2];c=b+6936|0;o[c>>2]=0;o[c+4>>2]=0;b=b+6928|0;o[b>>2]=0;o[b+4>>2]=0;if(o[o[a>>2]+12>>2]){b=o[a+4>>2]+7060|0;o[b+80>>2]=0;o[b+84>>2]=0;o[b+64>>2]=1732584193;o[b+68>>2]=-271733879;o[b+72>>2]=-1732584194;o[b+76>>2]=271733878;o[b+88>>2]=0;o[b+92>>2]=0}b=o[a+4>>2];if(!hb(b+6872|0,o[b+6856>>2])){o[o[a>>2]>>2]=7;break a}if(!Fa(a,0,0)){break a}o[o[a+4>>2]+6896>>2]=-1<<o[1358]^-1;b=o[a+4>>2]+6920|0;o[b>>2]=0;o[b+4>>2]=0;if(!n){o[t>>2]=4;c=o[o[a>>2]+604>>2];b=t;o[b+24>>2]=0;o[b+28>>2]=0;o[b+16>>2]=0;o[b+20>>2]=0;o[b+8>>2]=8;o[b+4>>2]=!c;if(!hb(b,o[o[a+4>>2]+6856>>2])){o[o[a>>2]>>2]=7;break a}if(!Fa(a,0,0)){break a}}T:{d=o[a>>2];e=o[d+604>>2];if(!e){break T}c=0;while(1){b=o[o[d+600>>2]+(c<<2)>>2];o[b+4>>2]=(e+ -1|0)==(c|0);if(!hb(b,o[o[a+4>>2]+6856>>2])){o[o[a>>2]>>2]=7;break a}if(Fa(a,0,0)){c=c+1|0;d=o[a>>2];e=o[d+604>>2];if(c>>>0>=e>>>0){break T}continue}break}break a}U:{b=o[a+4>>2];c=o[b+7272>>2];if(!c){break U}b=l[c](a,d+624|0,o[b+7288>>2])|0;d=o[a>>2];if((b|0)!=1){break U}o[d>>2]=5;break a}i=0;if(!o[d+4>>2]){break a}o[o[a+4>>2]+11756>>2]=2;break a}o[o[a>>2]>>2]=2;i=1;break a}o[d>>2]=3;i=1;break a}o[i>>2]=8;i=1}N=t+176|0;return i}function Kb(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,O=0,P=0,R=0,S=0,T=0;n=N-192|0;N=n;F=h;H=i&65535;r=d;p=e&65535;D=(e^i)&-2147483648;l=i>>>16&32767;a:{s=e>>>16&32767;b:{c:{if(l+ -1>>>0<32766?s+ -1>>>0<=32765:0){break c}m=e&2147483647;k=m;j=d;if(!(!j&(k|0)==2147418112?!(b|c):(k|0)==2147418112&j>>>0<0|k>>>0<2147418112)){K=d;D=e|32768;break b}m=i&2147483647;e=m;d=h;if(!(!d&(e|0)==2147418112?!(f|g):(e|0)==2147418112&d>>>0<0|e>>>0<2147418112)){K=h;D=i|32768;b=f;c=g;break b}if(!(b|j|(k^2147418112|c))){if(!(d|f|(e^2147418112|g))){b=0;c=0;D=2147450880;break b}D=D|2147418112;b=0;c=0;break b}if(!(d|f|(e^2147418112|g))){b=0;c=0;break b}if(!(b|j|(c|k))){break a}if(!(d|f|(e|g))){D=D|2147418112;b=0;c=0;break b}if((k|0)==65535|k>>>0<65535){i=b;d=!(p|r);h=d<<6;j=x(d?b:r)+32|0;b=x(d?c:p);b=h+((b|0)==32?j:b)|0;ia(n+176|0,i,c,r,p,b+ -15|0);I=16-b|0;r=o[n+184>>2];p=o[n+188>>2];c=o[n+180>>2];b=o[n+176>>2]}if(e>>>0>65535){break c}d=!(F|H);e=d<<6;h=x(d?f:F)+32|0;d=x(d?g:H);d=e+((d|0)==32?h:d)|0;ia(n+160|0,f,g,F,H,d+ -15|0);I=(d+I|0)+ -16|0;F=o[n+168>>2];H=o[n+172>>2];f=o[n+160>>2];g=o[n+164>>2]}e=H|65536;J=e;L=F;d=F;k=e<<15|d>>>17;d=d<<15|g>>>17;h=-102865788-d|0;e=k;i=1963258675-(k+(4192101508<d>>>0)|0)|0;ra(n+144|0,d,k,h,i);j=o[n+152>>2];ra(n+128|0,0-j|0,0-(o[n+156>>2]+(0<j>>>0)|0)|0,h,i);h=o[n+136>>2];i=h<<1|o[n+132>>2]>>>31;h=o[n+140>>2]<<1|h>>>31;ra(n+112|0,i,h,d,k);j=h;h=o[n+120>>2];ra(n+96|0,i,j,0-h|0,0-(o[n+124>>2]+(0<h>>>0)|0)|0);h=o[n+104>>2];i=h<<1|o[n+100>>2]>>>31;h=o[n+108>>2]<<1|h>>>31;ra(n+80|0,i,h,d,k);j=h;h=o[n+88>>2];ra(n- -64|0,i,j,0-h|0,0-(o[n+92>>2]+(0<h>>>0)|0)|0);h=o[n+72>>2];i=h<<1|o[n+68>>2]>>>31;h=o[n+76>>2]<<1|h>>>31;ra(n+48|0,i,h,d,k);j=h;h=o[n+56>>2];ra(n+32|0,i,j,0-h|0,0-(o[n+60>>2]+(0<h>>>0)|0)|0);h=o[n+40>>2];i=h<<1|o[n+36>>2]>>>31;h=o[n+44>>2]<<1|h>>>31;ra(n+16|0,i,h,d,k);j=h;h=o[n+24>>2];ra(n,i,j,0-h|0,0-(o[n+28>>2]+(0<h>>>0)|0)|0);I=(s-l|0)+I|0;h=o[n+8>>2];j=o[n+12>>2]<<1|h>>>31;i=h<<1;k=j+ -1|0;i=(o[n+4>>2]>>>31|i)+ -1|0;if((i|0)!=-1){k=k+1|0}h=i;j=0;y=j;t=e;l=0;m=Ee(h,j,e,l);e=Q;w=e;u=k;s=0;j=d;h=Ee(k,s,j,0);d=h+m|0;k=Q+e|0;k=d>>>0<h>>>0?k+1|0:k;h=d;d=k;q=Ee(i,y,j,q);e=0+q|0;k=h;j=k+Q|0;j=e>>>0<q>>>0?j+1|0:j;q=e;e=j;j=(k|0)==(j|0)&q>>>0<A>>>0|j>>>0<k>>>0;k=(d|0)==(w|0)&k>>>0<m>>>0|d>>>0<w>>>0;h=d;d=Ee(u,s,t,l)+d|0;l=k+Q|0;l=d>>>0<h>>>0?l+1|0:l;h=d;d=j+d|0;j=l;B=d;h=d>>>0<h>>>0?j+1|0:j;d=g;z=(d&131071)<<15|f>>>17;t=Ee(i,y,z,0);d=Q;A=d;k=f;v=k<<15&-32768;m=Ee(u,s,v,0);j=m+t|0;k=Q+d|0;k=j>>>0<m>>>0?k+1|0:k;d=k;C=Ee(i,y,v,C);v=0+C|0;k=j+Q|0;k=v>>>0<C>>>0?k+1|0:k;k=(j|0)==(k|0)&v>>>0<E>>>0|k>>>0<j>>>0;j=(d|0)==(A|0)&j>>>0<t>>>0|d>>>0<A>>>0;m=d;d=Ee(u,s,z,G)+d|0;l=j+Q|0;l=d>>>0<m>>>0?l+1|0:l;j=d;d=k+j|0;m=d>>>0<j>>>0?l+1|0:l;k=d;d=q+d|0;j=m+e|0;j=d>>>0<k>>>0?j+1|0:j;w=d;k=h;t=j;d=(e|0)==(j|0)&d>>>0<q>>>0|j>>>0<e>>>0;e=d+B|0;if(e>>>0<d>>>0){k=k+1|0}j=k;d=(w|0)!=0|(t|0)!=0;e=e+d|0;if(e>>>0<d>>>0){j=j+1|0}k=e;e=0-k|0;q=0;h=Ee(e,q,i,y);d=Q;A=d;v=Ee(u,s,e,q);e=Q;B=e;z=0-((0<k>>>0)+j|0)|0;j=0;q=Ee(i,y,z,j);l=q+v|0;k=Q+e|0;k=l>>>0<q>>>0?k+1|0:k;e=l;q=0+h|0;l=d+e|0;l=q>>>0<G>>>0?l+1|0:l;m=q;d=l;l=(A|0)==(d|0)&m>>>0<h>>>0|d>>>0<A>>>0;m=(k|0)==(B|0)&e>>>0<v>>>0|k>>>0<B>>>0;e=Ee(u,s,z,j)+k|0;j=m+Q|0;j=e>>>0<k>>>0?j+1|0:j;h=e;e=l+e|0;if(e>>>0<h>>>0){j=j+1|0}z=e;h=j;l=q;e=0-w|0;G=0-((0<w>>>0)+t|0)|0;w=0;B=Ee(G,w,i,y);v=Q;t=e;C=0;j=Ee(e,C,u,s);e=j+B|0;k=Q+v|0;m=e;e=e>>>0<j>>>0?k+1|0:k;t=Ee(i,y,t,C);i=0+t|0;j=m;k=j+Q|0;k=i>>>0<t>>>0?k+1|0:k;k=(j|0)==(k|0)&i>>>0<E>>>0|k>>>0<j>>>0;j=(e|0)==(v|0)&j>>>0<B>>>0|e>>>0<v>>>0;i=e;e=Ee(u,s,G,w)+e|0;m=j+Q|0;m=e>>>0<i>>>0?m+1|0:m;i=e;e=k+e|0;j=m;j=e>>>0<i>>>0?j+1|0:j;i=e;e=e+l|0;j=j+d|0;j=e>>>0<i>>>0?j+1|0:j;i=e;k=h;e=j;d=(d|0)==(j|0)&i>>>0<l>>>0|j>>>0<d>>>0;h=d+z|0;if(h>>>0<d>>>0){k=k+1|0}d=h;j=k;m=d;l=e+ -1|0;d=i+ -2|0;if(d>>>0<4294967294){l=l+1|0}h=d;k=d;d=l;e=(e|0)==(d|0)&k>>>0<i>>>0|d>>>0<e>>>0;i=m+e|0;if(i>>>0<e>>>0){j=j+1|0}e=i+ -1|0;k=j+ -1|0;k=(e|0)!=-1?k+1|0:k;i=0;u=i;s=e;j=r;v=j<<2|c>>>30;z=0;q=Ee(e,i,v,z);i=Q;m=i;i=c;G=(i&1073741823)<<2|b>>>30;C=k;i=0;j=Ee(G,0,k,i);e=j+q|0;l=Q+m|0;l=e>>>0<j>>>0?l+1|0:l;j=e;t=l;A=(m|0)==(l|0)&j>>>0<q>>>0|l>>>0<m>>>0;m=l;l=0;q=l;k=0;B=d;E=((p&1073741823)<<2|r>>>30)&-262145|262144;e=Ee(d,l,E,0);d=e+j|0;m=Q+m|0;m=d>>>0<e>>>0?m+1|0:m;r=d;e=m;d=(t|0)==(e|0)&d>>>0<j>>>0|e>>>0<t>>>0;j=d+A|0;if(j>>>0<d>>>0){k=1}m=Ee(C,i,E,M);d=m+j|0;j=Q+k|0;k=d>>>0<m>>>0?j+1|0:j;l=Ee(s,u,E,M);j=Q;c=d;p=Ee(v,z,C,i);d=p+l|0;m=Q+j|0;m=d>>>0<p>>>0?m+1|0:m;p=d;d=m;m=(j|0)==(d|0)&p>>>0<l>>>0|d>>>0<j>>>0;l=c+d|0;k=k+m|0;j=l;m=j>>>0<d>>>0?k+1|0:k;c=j;l=e+p|0;k=0;d=k+r|0;if(d>>>0<k>>>0){l=l+1|0}p=d;j=d;d=l;e=(e|0)==(d|0)&j>>>0<r>>>0|d>>>0<e>>>0;j=c+e|0;if(j>>>0<e>>>0){m=m+1|0}O=j;e=p;k=d;r=Ee(G,w,B,q);l=Q;t=h;A=Ee(h,0,v,z);h=A+r|0;j=Q+l|0;j=h>>>0<A>>>0?j+1|0:j;y=h;h=j;r=(l|0)==(j|0)&y>>>0<r>>>0|j>>>0<l>>>0;R=e;j=0;S=r;c=b<<2&-4;r=Ee(s,u,c,0);e=r+y|0;l=Q+h|0;l=e>>>0<r>>>0?l+1|0:l;A=e;r=e;e=l;h=(h|0)==(e|0)&r>>>0<y>>>0|e>>>0<h>>>0;l=S+h|0;if(l>>>0<h>>>0){j=1}h=R+l|0;k=j+k|0;k=h>>>0<l>>>0?k+1|0:k;r=h;l=m;h=k;d=(d|0)==(k|0)&r>>>0<p>>>0|k>>>0<d>>>0;j=d+O|0;if(j>>>0<d>>>0){l=l+1|0}R=j;p=r;y=h;O=Ee(C,i,c,T);C=Q;i=Ee(E,M,t,P);d=i+O|0;m=Q+C|0;m=d>>>0<i>>>0?m+1|0:m;E=d;j=Ee(v,z,B,q);d=d+j|0;i=m;k=i+Q|0;k=d>>>0<j>>>0?k+1|0:k;v=d;m=Ee(s,u,G,w);d=d+m|0;j=Q+k|0;s=d;j=d>>>0<m>>>0?j+1|0:j;u=0;m=l;d=j;j=(j|0)==(k|0)&s>>>0<v>>>0|j>>>0<k>>>0;l=(i|0)==(C|0)&E>>>0<O>>>0|i>>>0<C>>>0;i=(i|0)==(k|0)&v>>>0<E>>>0|k>>>0<i>>>0;k=l+i|0;k>>>0<i>>>0;i=j+k|0;k=i;j=d|0;i=j+p|0;k=(k|u)+y|0;k=i>>>0<j>>>0?k+1|0:k;y=i;p=k;h=(h|0)==(k|0)&i>>>0<r>>>0|k>>>0<h>>>0;i=h+R|0;if(i>>>0<h>>>0){m=m+1|0}z=i;i=m;m=y;r=p;u=A;B=Ee(B,q,c,T);q=Q;j=Ee(G,w,t,P);h=j+B|0;l=Q+q|0;l=h>>>0<j>>>0?l+1|0:l;k=l;w=k;l=0;j=(k|0)==(q|0)&h>>>0<B>>>0|k>>>0<q>>>0;h=k+u|0;k=(j|l)+e|0;k=h>>>0<w>>>0?k+1|0:k;w=h;j=h;h=k;j=(e|0)==(k|0)&j>>>0<u>>>0|k>>>0<e>>>0;c=m;e=j;j=k+s|0;m=0;d=m+w|0;if(d>>>0<m>>>0){j=j+1|0}d=(h|0)==(j|0)&d>>>0<w>>>0|j>>>0<h>>>0;e=e+d|0;if(e>>>0<d>>>0){l=1}d=c+e|0;m=l+r|0;h=d;j=i;m=d>>>0<e>>>0?m+1|0:m;i=m;d=(p|0)==(i|0)&d>>>0<y>>>0|i>>>0<p>>>0;e=d+z|0;if(e>>>0<d>>>0){j=j+1|0}d=e;e=j;d:{if((j|0)==131071|j>>>0<131071){u=0;p=f;v=0;k=Ee(h,u,p,v);l=Q;j=b<<17;b=0;c=(k|0)!=0|(l|0)!=0;r=b-c|0;E=j-(b>>>0<c>>>0)|0;w=0-k|0;q=0-((0<k>>>0)+l|0)|0;c=0;z=Ee(i,c,p,v);b=Q;G=b;s=0;k=Ee(h,u,g,s);j=k+z|0;l=Q+b|0;l=j>>>0<k>>>0?l+1|0:l;b=j;k=j;t=0;j=t;A=k;j=(k|0)==(q|0)&w>>>0<j>>>0|q>>>0<k>>>0;y=r-j|0;r=E-(r>>>0<j>>>0)|0;j=Ee(d,0,p,v);k=Q;p=Ee(h,u,F,0);j=p+j|0;m=Q+k|0;m=j>>>0<p>>>0?m+1|0:m;p=Ee(g,s,i,c);j=p+j|0;k=Q+m|0;k=j>>>0<p>>>0?k+1|0:k;m=k;k=(l|0)==(G|0)&b>>>0<z>>>0|l>>>0<G>>>0;b=l+j|0;k=k+m|0;m=b;b=m>>>0<l>>>0?k+1|0:k;j=Ee(h,i,J,0);l=Q;p=m;m=Ee(f,g,e,0);k=m+j|0;j=Q+l|0;j=k>>>0<m>>>0?j+1|0:j;l=Ee(d,e,g,s);m=l+k|0;j=Ee(i,c,F,H);c=j+m|0;j=c;k=0;c=p+k|0;j=b+j|0;b=c;F=y-b|0;H=r-((y>>>0<b>>>0)+(b>>>0<k>>>0?j+1|0:j)|0)|0;I=I+ -1|0;c=w-t|0;b=q-((w>>>0<t>>>0)+A|0)|0;break d}q=i>>>1|0;l=0;r=b<<16;k=d<<31;h=(i&1)<<31|h>>>1;i=i>>>1|k;z=0;c=f;m=0;b=Ee(h,z,c,m);j=Q;k=j;p=0;j=(b|0)!=0|(j|0)!=0;t=p-j|0;E=r-(p>>>0<j>>>0)|0;A=0-b|0;y=0-((0<b>>>0)+k|0)|0;p=y;r=0;w=Ee(h,z,g,r);b=Q;C=b;k=e<<31|d>>>1;q=q|d<<31;M=k|l;k=q;u=Ee(k,0,c,m);l=u+w|0;j=Q+b|0;j=l>>>0<u>>>0?j+1|0:j;b=j;j=l;v=j;u=0;j=(j|0)==(p|0)&A>>>0<u>>>0|p>>>0<j>>>0;B=t-j|0;t=E-(t>>>0<j>>>0)|0;E=Ee(g,r,k,P);P=Q;j=c;k=m;c=e>>>1|0;p=(e&1)<<31|d>>>1;m=Ee(j,k,p,0);j=m+E|0;k=Q+P|0;k=j>>>0<m>>>0?k+1|0:k;s=Ee(h,z,F,0);m=s+j|0;j=Q+k|0;k=m;m=k>>>0<s>>>0?j+1|0:j;j=(b|0)==(C|0)&l>>>0<w>>>0|b>>>0<C>>>0;s=b;b=b+k|0;l=j+m|0;m=b;b=m>>>0<s>>>0?l+1|0:l;j=Ee(h,i,J,0);k=Q;e=Ee(f,g,e>>>1|0,0);d=e+j|0;j=Q+k|0;j=d>>>0<e>>>0?j+1|0:j;e=Ee(p,c,g,r);d=e+d|0;j=Q+j|0;e=Ee(q,M,F,H);d=e+d|0;j=d;e=0;d=e+m|0;k=b+j|0;F=B-d|0;H=t-((B>>>0<d>>>0)+(d>>>0<e>>>0?k+1|0:k)|0)|0;d=p;e=c;c=A-u|0;b=y-((A>>>0<u>>>0)+v|0)|0}if((I|0)>=16384){D=D|2147418112;b=0;c=0;break b}l=I+16383|0;if((I|0)<=-16383){e:{if(l){break e}l=i;m=b<<1|c>>>31;j=c<<1;g=(g|0)==(m|0)&j>>>0>f>>>0|m>>>0>g>>>0;j=e&65535;f=F;m=H<<1|f>>>31;c=f<<1|b>>>31;e=c;b=(e|0)==(L|0)&(m|0)==(J|0)?g:(J|0)==(m|0)&e>>>0>L>>>0|m>>>0>J>>>0;c=b+h|0;if(c>>>0<b>>>0){l=l+1|0}b=c;e=b;c=l;e=d+((i|0)==(l|0)&e>>>0<h>>>0|l>>>0<i>>>0)|0;if(e>>>0<d>>>0){j=j+1|0}d=j;if(!(j&65536)){break e}K=e|K;D=d|D;break b}b=0;c=0;break b}k=i;e=e&65535;j=b<<1|c>>>31;p=c<<1;g=(g|0)==(j|0)&p>>>0>=f>>>0|j>>>0>g>>>0;f=F;j=H<<1|f>>>31;c=f<<1|b>>>31;b=(c|0)==(L|0)&(j|0)==(J|0)?g:(J|0)==(j|0)&c>>>0>=L>>>0|j>>>0>J>>>0;c=b+h|0;if(c>>>0<b>>>0){k=k+1|0}b=c;c=k;f=d;d=((i|0)==(k|0)&b>>>0<h>>>0|k>>>0<i>>>0)+d|0;k=l<<16|e;K=d|K;D=D|(d>>>0<f>>>0?k+1|0:k)}o[a>>2]=b;o[a+4>>2]=c;o[a+8>>2]=K;o[a+12>>2]=D;N=n+192|0;return}o[a>>2]=0;o[a+4>>2]=0;b=!(d|f|(e|g));o[a+8>>2]=b?0:K;o[a+12>>2]=b?2147450880:D;N=n+192|0}function Dc(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,q=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0;g=N-8976|0;N=g;y=d+e|0;E=0-y|0;a:{b:{while(1){c:{if((c|0)!=48){if((c|0)!=46){break a}c=o[b+4>>2];if(c>>>0>=r[b+104>>2]){break c}o[b+4>>2]=c+1;c=p[c|0];break b}c=o[b+4>>2];if(c>>>0<r[b+104>>2]){i=1;o[b+4>>2]=c+1;c=p[c|0]}else{i=1;c=ga(b)}continue}break}c=ga(b)}k=1;if((c|0)!=48){break a}while(1){c=o[b+4>>2];d:{if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break d}c=ga(b)}h=h+ -1|0;n=j+ -1|0;if((n|0)!=-1){h=h+1|0}j=n;if((c|0)==48){continue}break}i=1}o[g+784>>2]=0;e:{f:{q=(c|0)==46;n=c+ -48|0;g:{h:{i:{if(q|n>>>0<=9){while(1){j:{if(q&1){if(!k){j=m;h=l;k=1;break j}i=!i;break i}m=m+1|0;if(m>>>0<1){l=l+1|0}if((s|0)<=2044){x=(c|0)==48?x:m;i=(g+784|0)+(s<<2)|0;q=i;if(t){n=(u(o[i>>2],10)+c|0)+ -48|0}o[q>>2]=n;i=1;n=t+1|0;c=(n|0)==9;t=c?0:n;s=c+s|0;break j}if((c|0)==48){break j}o[g+8960>>2]=o[g+8960>>2]|1;x=18396}c=o[b+4>>2];k:{if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break k}c=ga(b)}q=(c|0)==46;n=c+ -48|0;if(q|n>>>0<10){continue}break}}j=k?j:m;h=k?h:l;if(!(!i|(c&-33)!=69)){k=lb(b);c=Q;q=c;l:{if(k|(c|0)!=-2147483648){break l}k=0;q=0;if(!o[b+104>>2]){break l}o[b+4>>2]=o[b+4>>2]+ -1}if(!i){break g}h=h+q|0;b=j+k|0;if(b>>>0<k>>>0){h=h+1|0}j=b;break f}i=!i;if((c|0)<0){break h}}if(!o[b+104>>2]){break h}o[b+4>>2]=o[b+4>>2]+ -1}if(!i){break f}}o[2896]=28;m=0;l=0;o[b+112>>2]=0;o[b+116>>2]=0;c=o[b+8>>2];d=c-o[b+4>>2]|0;o[b+120>>2]=d;o[b+124>>2]=d>>31;o[b+104>>2]=c;c=0;b=0;break e}b=o[g+784>>2];if(!b){sa(g,+(f|0)*0);m=o[g>>2];l=o[g+4>>2];c=o[g+12>>2];b=o[g+8>>2];break e}if(!((j|0)!=(m|0)|(h|0)!=(l|0)|((l|0)>0?1:(l|0)>=0?m>>>0<=9?0:1:0)|(b>>>d|0?(d|0)<=30:0))){ka(g+48|0,f);Ba(g+32|0,b);$(g+16|0,o[g+48>>2],o[g+52>>2],o[g+56>>2],o[g+60>>2],o[g+32>>2],o[g+36>>2],o[g+40>>2],o[g+44>>2]);m=o[g+16>>2];l=o[g+20>>2];c=o[g+28>>2];b=o[g+24>>2];break e}if((h|0)>0?1:(h|0)>=0?j>>>0<=(e|0)/-2>>>0?0:1:0){o[2896]=68;ka(g+96|0,f);$(g+80|0,o[g+96>>2],o[g+100>>2],o[g+104>>2],o[g+108>>2],-1,-1,-1,2147418111);$(g- -64|0,o[g+80>>2],o[g+84>>2],o[g+88>>2],o[g+92>>2],-1,-1,-1,2147418111);m=o[g+64>>2];l=o[g+68>>2];c=o[g+76>>2];b=o[g+72>>2];break e}b=e+ -226|0;c=j>>>0>=b>>>0?0:1;b=b>>31;if((h|0)<(b|0)?1:(h|0)<=(b|0)?c:0){o[2896]=68;ka(g+144|0,f);$(g+128|0,o[g+144>>2],o[g+148>>2],o[g+152>>2],o[g+156>>2],0,0,0,65536);$(g+112|0,o[g+128>>2],o[g+132>>2],o[g+136>>2],o[g+140>>2],0,0,0,65536);m=o[g+112>>2];l=o[g+116>>2];c=o[g+124>>2];b=o[g+120>>2];break e}if(t){if((t|0)<=8){c=(g+784|0)+(s<<2)|0;b=o[c>>2];while(1){b=u(b,10);t=t+1|0;if((t|0)!=9){continue}break}o[c>>2]=b}s=s+1|0}m:{k=j;if((x|0)>(k|0)|(x|0)>=9|(k|0)>17){break m}if((k|0)==9){ka(g+192|0,f);Ba(g+176|0,o[g+784>>2]);$(g+160|0,o[g+192>>2],o[g+196>>2],o[g+200>>2],o[g+204>>2],o[g+176>>2],o[g+180>>2],o[g+184>>2],o[g+188>>2]);m=o[g+160>>2];l=o[g+164>>2];c=o[g+172>>2];b=o[g+168>>2];break e}if((k|0)<=8){ka(g+272|0,f);Ba(g+256|0,o[g+784>>2]);$(g+240|0,o[g+272>>2],o[g+276>>2],o[g+280>>2],o[g+284>>2],o[g+256>>2],o[g+260>>2],o[g+264>>2],o[g+268>>2]);ka(g+224|0,o[(0-k<<2)+10560>>2]);Kb(g+208|0,o[g+240>>2],o[g+244>>2],o[g+248>>2],o[g+252>>2],o[g+224>>2],o[g+228>>2],o[g+232>>2],o[g+236>>2]);m=o[g+208>>2];l=o[g+212>>2];c=o[g+220>>2];b=o[g+216>>2];break e}b=(u(k,-3)+d|0)+27|0;c=o[g+784>>2];if(c>>>b|0?(b|0)<=30:0){break m}ka(g+352|0,f);Ba(g+336|0,c);$(g+320|0,o[g+352>>2],o[g+356>>2],o[g+360>>2],o[g+364>>2],o[g+336>>2],o[g+340>>2],o[g+344>>2],o[g+348>>2]);ka(g+304|0,o[(k<<2)+10488>>2]);$(g+288|0,o[g+320>>2],o[g+324>>2],o[g+328>>2],o[g+332>>2],o[g+304>>2],o[g+308>>2],o[g+312>>2],o[g+316>>2]);m=o[g+288>>2];l=o[g+292>>2];c=o[g+300>>2];b=o[g+296>>2];break e}while(1){c=s;s=c+ -1|0;if(!o[(g+784|0)+(s<<2)>>2]){continue}break}t=0;b=(k|0)%9|0;n:{if(!b){i=0;break n}n=(k|0)>-1?b:b+9|0;o:{if(!c){i=0;c=0;break o}h=o[(0-n<<2)+10560>>2];l=1e9/(h|0)|0;q=0;b=0;i=0;while(1){j=q;m=(g+784|0)+(b<<2)|0;q=o[m>>2];s=(q>>>0)/(h>>>0)|0;j=j+s|0;o[m>>2]=j;j=!j&(b|0)==(i|0);i=j?i+1&2047:i;k=j?k+ -9|0:k;q=u(l,q-u(h,s)|0);b=b+1|0;if((c|0)!=(b|0)){continue}break}if(!q){break o}o[(g+784|0)+(c<<2)>>2]=q;c=c+1|0}k=(k-n|0)+9|0}while(1){m=(g+784|0)+(i<<2)|0;p:{while(1){if((k|0)!=36|r[m>>2]>=10384593?(k|0)>=36:0){break p}s=c+2047|0;q=0;n=c;while(1){c=n;l=s&2047;s=(g+784|0)+(l<<2)|0;b=o[s>>2];h=b>>>3|0;n=b<<29;b=n+q|0;if(b>>>0<n>>>0){h=h+1|0}j=b;n=0;q:{if(!h&b>>>0<1000000001|h>>>0<0){break q}n=Fe(b,h,1e9);j=j-Ee(n,Q,1e9,0)|0}q=n;o[s>>2]=j;n=(l|0)!=(c+ -1&2047)?c:(l|0)==(i|0)?c:j?c:l;s=l+ -1|0;if((l|0)!=(i|0)){continue}break}t=t+ -29|0;if(!q){continue}break}i=i+ -1&2047;if((n|0)==(i|0)){b=(g+784|0)+((n+2046&2047)<<2)|0;c=n+ -1&2047;o[b>>2]=o[b>>2]|o[(g+784|0)+(c<<2)>>2]}k=k+9|0;o[(g+784|0)+(i<<2)>>2]=q;continue}break}r:{s:while(1){h=c+1&2047;l=(g+784|0)+((c+ -1&2047)<<2)|0;while(1){j=(k|0)>45?9:1;t:{while(1){n=i;b=0;u:{while(1){v:{i=b+n&2047;if((i|0)==(c|0)){break v}i=o[(g+784|0)+(i<<2)>>2];m=o[(b<<2)+10512>>2];if(i>>>0<m>>>0){break v}if(i>>>0>m>>>0){break u}b=b+1|0;if((b|0)!=4){continue}}break}if((k|0)!=36){break u}j=0;h=0;b=0;m=0;l=0;while(1){i=b+n&2047;if((i|0)==(c|0)){c=c+1&2047;o[((c<<2)+g|0)+780>>2]=0}$(g+768|0,j,h,m,l,0,0,1342177280,1075633366);Ba(g+752|0,o[(g+784|0)+(i<<2)>>2]);ja(g+736|0,o[g+768>>2],o[g+772>>2],o[g+776>>2],o[g+780>>2],o[g+752>>2],o[g+756>>2],o[g+760>>2],o[g+764>>2]);m=o[g+744>>2];l=o[g+748>>2];j=o[g+736>>2];h=o[g+740>>2];b=b+1|0;if((b|0)!=4){continue}break}ka(g+720|0,f);$(g+704|0,j,h,m,l,o[g+720>>2],o[g+724>>2],o[g+728>>2],o[g+732>>2]);m=o[g+712>>2];l=o[g+716>>2];j=0;h=0;k=o[g+704>>2];q=o[g+708>>2];s=t+113|0;e=s-e|0;i=(e|0)<(d|0);d=i?(e|0)>0?e:0:d;if((d|0)<=112){break t}break r}t=j+t|0;i=c;if((c|0)==(n|0)){continue}break}m=1e9>>>j|0;q=-1<<j^-1;b=0;i=n;while(1){s=(g+784|0)+(n<<2)|0;x=o[s>>2];b=(x>>>j|0)+b|0;o[s>>2]=b;b=!b&(i|0)==(n|0);i=b?i+1&2047:i;k=b?k+ -9|0:k;b=u(m,q&x);n=n+1&2047;if((n|0)!=(c|0)){continue}break}if(!b){continue}if((h|0)!=(i|0)){o[(g+784|0)+(c<<2)>>2]=b;c=h;continue s}o[l>>2]=o[l>>2]|1;i=h;continue}break}break}sa(g+656|0,ua(1,225-d|0));Fb(g+688|0,o[g+656>>2],o[g+660>>2],o[g+664>>2],o[g+668>>2],k,q,m,l);z=o[g+696>>2];A=o[g+700>>2];B=o[g+688>>2];C=o[g+692>>2];sa(g+640|0,ua(1,113-d|0));zb(g+672|0,k,q,m,l,o[g+640>>2],o[g+644>>2],o[g+648>>2],o[g+652>>2]);j=o[g+672>>2];h=o[g+676>>2];v=o[g+680>>2];w=o[g+684>>2];Xa(g+624|0,k,q,m,l,j,h,v,w);ja(g+608|0,B,C,z,A,o[g+624>>2],o[g+628>>2],o[g+632>>2],o[g+636>>2]);m=o[g+616>>2];l=o[g+620>>2];k=o[g+608>>2];q=o[g+612>>2]}b=n+4&2047;w:{if((b|0)==(c|0)){break w}b=o[(g+784|0)+(b<<2)>>2];x:{if(b>>>0<=499999999){if((n+5&2047)==(c|0)?!b:0){break x}sa(g+496|0,+(f|0)*.25);ja(g+480|0,j,h,v,w,o[g+496>>2],o[g+500>>2],o[g+504>>2],o[g+508>>2]);v=o[g+488>>2];w=o[g+492>>2];j=o[g+480>>2];h=o[g+484>>2];break x}if((b|0)!=5e8){sa(g+592|0,+(f|0)*.75);ja(g+576|0,j,h,v,w,o[g+592>>2],o[g+596>>2],o[g+600>>2],o[g+604>>2]);v=o[g+584>>2];w=o[g+588>>2];j=o[g+576>>2];h=o[g+580>>2];break x}D=+(f|0);if((n+5&2047)==(c|0)){sa(g+528|0,D*.5);ja(g+512|0,j,h,v,w,o[g+528>>2],o[g+532>>2],o[g+536>>2],o[g+540>>2]);v=o[g+520>>2];w=o[g+524>>2];j=o[g+512>>2];h=o[g+516>>2];break x}sa(g+560|0,D*.75);ja(g+544|0,j,h,v,w,o[g+560>>2],o[g+564>>2],o[g+568>>2],o[g+572>>2]);v=o[g+552>>2];w=o[g+556>>2];j=o[g+544>>2];h=o[g+548>>2]}if((d|0)>111){break w}zb(g+464|0,j,h,v,w,0,0,0,1073676288);if(za(o[g+464>>2],o[g+468>>2],o[g+472>>2],o[g+476>>2],0,0,0,0)){break w}ja(g+448|0,j,h,v,w,0,0,0,1073676288);v=o[g+456>>2];w=o[g+460>>2];j=o[g+448>>2];h=o[g+452>>2]}ja(g+432|0,k,q,m,l,j,h,v,w);Xa(g+416|0,o[g+432>>2],o[g+436>>2],o[g+440>>2],o[g+444>>2],B,C,z,A);m=o[g+424>>2];l=o[g+428>>2];k=o[g+416>>2];q=o[g+420>>2];y:{if((s&2147483647)<=(-2-y|0)){break y}o[g+408>>2]=m;o[g+412>>2]=l&2147483647;o[g+400>>2]=k;o[g+404>>2]=q;$(g+384|0,k,q,m,l,0,0,0,1073610752);c=Jb(o[g+400>>2],o[g+404>>2],o[g+408>>2],o[g+412>>2],1081081856);b=(c|0)<0;m=b?m:o[g+392>>2];l=b?l:o[g+396>>2];k=b?k:o[g+384>>2];q=b?q:o[g+388>>2];t=((c|0)>-1)+t|0;if(F=!(i&(b|(d|0)!=(e|0))&(za(j,h,v,w,0,0,0,0)|0)!=0),G=0,H=(t+110|0)<=(E|0),H?F:G){break y}o[2896]=68}mb(g+368|0,k,q,m,l,t);m=o[g+368>>2];l=o[g+372>>2];c=o[g+380>>2];b=o[g+376>>2]}o[a>>2]=m;o[a+4>>2]=l;o[a+8>>2]=b;o[a+12>>2]=c;N=g+8976|0}function Ta(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,n=0,q=0,s=0,t=0,v=0,w=0,x=0,y=0;g=N-192|0;N=g;a:{b:{if(!Y(o[o[a+4>>2]+56>>2],g+184|0,o[1391])){break b}t=o[g+184>>2];if(!Y(o[o[a+4>>2]+56>>2],g+180|0,o[1392])){break a}if(!Y(o[o[a+4>>2]+56>>2],g+176|0,o[1393])){break a}f=(t|0)!=0;c:{d:{e:{f:{g:{c=o[g+180>>2];switch(c|0){case 3:break f;case 0:break g;default:break e}}d=o[g+176>>2];c=0;b=o[a+4>>2];o[b+256>>2]=0;o[b+264>>2]=d;o[b+260>>2]=f;e=o[b+56>>2];b=o[1356];if(!Y(e,g,b)){break a}o[o[a+4>>2]+272>>2]=o[g>>2];e=o[1357];if(!Y(o[o[a+4>>2]+56>>2],g,e)){break a}o[o[a+4>>2]+276>>2]=o[g>>2];f=o[1358];if(!Y(o[o[a+4>>2]+56>>2],g,f)){break a}o[o[a+4>>2]+280>>2]=o[g>>2];h=o[1359];if(!Y(o[o[a+4>>2]+56>>2],g,h)){break a}o[o[a+4>>2]+284>>2]=o[g>>2];j=o[1360];if(!Y(o[o[a+4>>2]+56>>2],g,j)){break a}o[o[a+4>>2]+288>>2]=o[g>>2];i=o[1361];if(!Y(o[o[a+4>>2]+56>>2],g,i)){break a}o[o[a+4>>2]+292>>2]=o[g>>2]+1;k=o[1362];if(!Y(o[o[a+4>>2]+56>>2],g,k)){break a}o[o[a+4>>2]+296>>2]=o[g>>2]+1;n=o[a+4>>2];q=o[n+56>>2];s=n+304|0;n=o[1363];if(!wa(q,s,n)){break a}q=o[a+4>>2];if(!na(o[q+56>>2],q+312|0,16)){break a}if(!Ea(o[o[a+4>>2]+56>>2],d-((n+(k+(i+(j+(h+(f+(b+e|0)|0)|0)|0)|0)|0)|0)+128>>>3|0)|0)){break b}b=o[a+4>>2];o[b+248>>2]=1;if(!Pa(b+312|0,7555,16)){o[b+3624>>2]=0}if(o[b+3632>>2]|!o[b+608>>2]){break d}c=o[b+28>>2];if(!c){break d}l[c](a,b+256|0,o[b+48>>2]);break d}b=o[a+4>>2];o[b+252>>2]=0;e=o[g+176>>2];o[b+448>>2]=(e>>>0)/18;o[b+440>>2]=e;o[b+436>>2]=f;o[b+432>>2]=3;b=o[a+4>>2];c=o[b+452>>2];d=o[b+448>>2];h:{if(d){Ee(d,0,24,0);if(!Q){b=ea(c,u(d,24));if(b){o[o[a+4>>2]+452>>2]=b;break h}X(c);b=o[a+4>>2]}o[b+452>>2]=0;break c}b=ea(c,0);o[o[a+4>>2]+452>>2]=b;if(!b){break c}}c=o[a+4>>2];b=0;i:{if(!o[c+448>>2]){break i}f=o[1367];h=o[1366];j=o[1365];d=0;while(1){if(!wa(o[c+56>>2],g,j)){break b}k=o[g+4>>2];b=u(d,24);c=o[a+4>>2];i=b+o[c+452>>2]|0;o[i>>2]=o[g>>2];o[i+4>>2]=k;if(!wa(o[c+56>>2],g,h)){break b}k=o[g+4>>2];c=o[a+4>>2];i=b+o[c+452>>2]|0;o[i+8>>2]=o[g>>2];o[i+12>>2]=k;if(!Y(o[c+56>>2],g+188|0,f)){break b}c=o[a+4>>2];o[(b+o[c+452>>2]|0)+16>>2]=o[g+188>>2];d=d+1|0;b=o[c+448>>2];if(d>>>0<b>>>0){continue}break}b=u(b,-18)}b=b+e|0;if(b){if(!Ea(o[c+56>>2],b)){break b}c=o[a+4>>2]}o[c+252>>2]=1;if(o[c+3632>>2]|!o[c+620>>2]){break d}b=o[c+28>>2];if(!b){break d}l[b](a,c+432|0,o[c+48>>2]);break d}d=o[a+4>>2];h=o[(d+(c<<2)|0)+608>>2];e=o[g+176>>2];b=fa(g,176);o[b+8>>2]=e;o[b>>2]=c;o[b+4>>2]=f;j=!h;j:{if((c|0)!=2){break j}i=b+16|0;f=o[1364]>>>3|0;if(!na(o[d+56>>2],i,f)){break b}if(e>>>0<f>>>0){o[o[a>>2]>>2]=8;c=0;break a}e=e-f|0;d=o[a+4>>2];k=o[d+1124>>2];if(!k){break j}n=o[d+1120>>2];c=0;while(1){if(Pa(n+u(c,f)|0,i,f)){c=c+1|0;if((k|0)!=(c|0)){continue}break j}break}j=(h|0)!=0}if(j){if(!Ea(o[d+56>>2],e)){break b}break d}k:{l:{m:{n:{o:{p:{q:{switch(o[b+180>>2]){case 1:if(Ea(o[d+56>>2],e)){break o}f=0;break k;case 2:if(!e){break p}c=da(e);o[b+20>>2]=c;if(!c){o[o[a>>2]>>2]=8;f=0;break k}if(na(o[d+56>>2],c,e)){break o}f=0;break k;case 4:r:{if(e>>>0<8){break r}f=0;if(!fb(o[d+56>>2],b+16|0)){break k}e=e+ -8|0;c=o[b+16>>2];s:{if(c){if(e>>>0<c>>>0){o[b+16>>2]=0;o[b+20>>2]=0;break r}t:{u:{if((c|0)==-1){o[b+20>>2]=0;break u}d=da(c+1|0);o[b+20>>2]=d;if(d){break t}}o[o[a>>2]>>2]=8;break k}if(!na(o[o[a+4>>2]+56>>2],d,c)){break k}e=e-c|0;m[o[b+20>>2]+o[b+16>>2]|0]=0;break s}o[b+20>>2]=0}if(!fb(o[o[a+4>>2]+56>>2],b+24|0)){break k}c=o[b+24>>2];if(c>>>0>=100001){o[b+24>>2]=0;break k}if(!c){break r}d=Na(c,8);o[b+28>>2]=d;if(!d){break m}if(!o[b+24>>2]){break r}o[d>>2]=0;o[d+4>>2]=0;c=0;v:{if(e>>>0<4){break v}while(1){if(!fb(o[o[a+4>>2]+56>>2],d)){break l}e=e+ -4|0;h=o[b+28>>2];j=c<<3;d=h+j|0;f=o[d>>2];w:{if(f){if(e>>>0<f>>>0){break v}x:{y:{if((f|0)==-1){o[(h+(c<<3)|0)+4>>2]=0;break y}h=da(f+1|0);o[d+4>>2]=h;if(h){break x}}o[o[a>>2]>>2]=8;break l}e=e-f|0;fa(h,o[d>>2]);f=na(o[o[a+4>>2]+56>>2],o[d+4>>2],o[d>>2]);h=j+o[b+28>>2]|0;d=o[h+4>>2];if(!f){X(d);o[(o[b+28>>2]+(c<<3)|0)+4>>2]=0;break v}m[d+o[h>>2]|0]=0;break w}o[d+4>>2]=0}c=c+1|0;if(c>>>0>=r[b+24>>2]){break r}d=o[b+28>>2]+(c<<3)|0;o[d>>2]=0;o[d+4>>2]=0;if(e>>>0>=4){continue}break}}o[b+24>>2]=c}if(!e){break o}if(!o[b+24>>2]){X(o[b+28>>2]);o[b+28>>2]=0}if(Ea(o[o[a+4>>2]+56>>2],e)){break o}f=0;break k;case 5:f=0;c=fa(b+16|0,160);if(!na(o[d+56>>2],c,o[1378]>>>3|0)){break k}if(!wa(o[o[a+4>>2]+56>>2],b+152|0,o[1379])){break k}if(!Y(o[o[a+4>>2]+56>>2],b+188|0,o[1380])){break k}o[b+160>>2]=o[b+188>>2]!=0;if(!db(o[o[a+4>>2]+56>>2],o[1381])){break k}if(!Y(o[o[a+4>>2]+56>>2],b+188|0,o[1382])){break k}c=o[b+188>>2];o[b+164>>2]=c;if(!c){break o}c=qa(c,32);o[b+168>>2]=c;if(!c){break n}i=o[1371];if(!wa(o[o[a+4>>2]+56>>2],c,i)){break k}k=o[1373]>>>3|0;n=o[1370];q=o[1369];j=o[1368];s=o[1377];v=o[1376];w=o[1375];x=o[1374];y=o[1372];e=0;while(1){if(!Y(o[o[a+4>>2]+56>>2],b+188|0,y)){break k}h=(e<<5)+c|0;m[h+8|0]=o[b+188>>2];if(!na(o[o[a+4>>2]+56>>2],h+9|0,k)){break k}if(!Y(o[o[a+4>>2]+56>>2],b+188|0,x)){break k}m[h+22|0]=p[h+22|0]&254|m[b+188|0]&1;if(!Y(o[o[a+4>>2]+56>>2],b+188|0,w)){break k}m[h+22|0]=p[b+188|0]<<1&2|p[h+22|0]&253;if(!db(o[o[a+4>>2]+56>>2],v)){break k}if(!Y(o[o[a+4>>2]+56>>2],b+188|0,s)){break k}c=o[b+188>>2];m[h+23|0]=c;z:{c=c&255;if(!c){break z}d=qa(c,16);o[h+24>>2]=d;A:{if(d){if(!p[h+23|0]){break z}if(!wa(o[o[a+4>>2]+56>>2],d,j)){break k}c=0;break A}o[o[a>>2]>>2]=8;break k}while(1){if(!Y(o[o[a+4>>2]+56>>2],b+188|0,q)){break k}m[((c<<4)+d|0)+8|0]=o[b+188>>2];if(!db(o[o[a+4>>2]+56>>2],n)){break k}c=c+1|0;if(c>>>0>=p[h+23|0]){break z}d=o[h+24>>2];if(wa(o[o[a+4>>2]+56>>2],d+(c<<4)|0,j)){continue}break}break k}e=e+1|0;if(e>>>0>=r[b+164>>2]){break o}c=o[b+168>>2];if(wa(o[o[a+4>>2]+56>>2],c+(e<<5)|0,i)){continue}break}break k;case 6:B:{if(!Y(o[d+56>>2],b+188|0,o[1383])){break B}o[b+16>>2]=o[b+188>>2];if(!Y(o[o[a+4>>2]+56>>2],b+188|0,o[1384])){break B}C:{c=o[b+188>>2];D:{if((c|0)==-1){o[b+20>>2]=0;break D}d=da(c+1|0);o[b+20>>2]=d;if(d){break C}}o[o[a>>2]>>2]=8;f=0;break k}if(c){if(!na(o[o[a+4>>2]+56>>2],d,c)){break B}d=o[b+20>>2];c=o[b+188>>2]}else{c=0}m[c+d|0]=0;if(!Y(o[o[a+4>>2]+56>>2],b+188|0,o[1385])){break B}E:{c=o[b+188>>2];F:{if((c|0)==-1){o[b+24>>2]=0;break F}d=da(c+1|0);o[b+24>>2]=d;if(d){break E}}o[o[a>>2]>>2]=8;f=0;break k}if(c){if(!na(o[o[a+4>>2]+56>>2],d,c)){break B}d=o[b+24>>2];c=o[b+188>>2]}else{c=0}m[c+d|0]=0;if(!Y(o[o[a+4>>2]+56>>2],b+28|0,o[1386])){break B}if(!Y(o[o[a+4>>2]+56>>2],b+32|0,o[1387])){break B}if(!Y(o[o[a+4>>2]+56>>2],b+36|0,o[1388])){break B}if(!Y(o[o[a+4>>2]+56>>2],b+40|0,o[1389])){break B}if(!Y(o[o[a+4>>2]+56>>2],b+44|0,o[1390])){break B}c=o[b+44>>2];d=da(c?c:1);o[b+48>>2]=d;if(!d){o[o[a>>2]>>2]=8;f=0;break k}if(!c){break o}if(na(o[o[a+4>>2]+56>>2],d,c)){break o}}f=0;break k;case 0:case 3:break o;default:break q}}G:{if(e){c=da(e);o[b+16>>2]=c;if(c){break G}o[o[a>>2]>>2]=8;f=0;break k}o[b+16>>2]=0;break o}if(na(o[d+56>>2],c,e)){break o}f=0;break k}o[b+20>>2]=0}f=1;c=o[a+4>>2];if(o[c+3632>>2]){break k}d=o[c+28>>2];if(!d){break k}l[d](a,b,o[c+48>>2]);break k}o[o[a>>2]>>2]=8;break k}o[b+24>>2]=0;o[o[a>>2]>>2]=8;break k}o[b+24>>2]=c;f=0}H:{I:{switch(o[b+180>>2]+ -1|0){case 1:b=o[b+20>>2];if(!b){break H}X(b);break H;case 3:c=o[b+20>>2];if(c){X(c)}d=o[b+24>>2];if(d){c=0;while(1){e=o[(o[b+28>>2]+(c<<3)|0)+4>>2];if(e){X(e);d=o[b+24>>2]}c=c+1|0;if(c>>>0<d>>>0){continue}break}}b=o[b+28>>2];if(!b){break H}X(b);break H;case 4:d=o[b+164>>2];if(d){c=0;while(1){e=o[(o[b+168>>2]+(c<<5)|0)+24>>2];if(e){X(e);d=o[b+164>>2]}c=c+1|0;if(c>>>0<d>>>0){continue}break}}b=o[b+168>>2];if(!b){break H}X(b);break H;case 5:c=o[b+20>>2];if(c){X(c)}c=o[b+24>>2];if(c){X(c)}b=o[b+48>>2];if(!b){break H}X(b);break H;case 0:break H;default:break I}}b=o[b+16>>2];if(!b){break H}X(b)}if(!f){break b}}c=1;if(!t){break a}J:{K:{d=o[a+4>>2];if(o[d>>2]){break K}e=o[d+12>>2];if(!e){break K}b=d+6136|0;if(l[e](a,b,o[d+48>>2])|p[o[o[a+4>>2]+56>>2]+20|0]&7){break K}e=o[b>>2];d=o[o[a+4>>2]+56>>2];d=((o[d+8>>2]-o[d+16>>2]<<5)+(o[d+12>>2]<<3)|0)-o[d+20>>2]>>>3|0;f=o[b+4>>2]-(e>>>0<d>>>0)|0;o[b>>2]=e-d;o[b+4>>2]=f;break J}b=o[a+4>>2];o[b+6136>>2]=0;o[b+6140>>2]=0}o[o[a>>2]>>2]=2;break a}o[o[a>>2]>>2]=8}c=0}N=g+192|0;return c}function Mb(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,s=0,t=0,v=0,w=0,x=0;f=N-32|0;N=f;a:{if(!a){break a}b:{c:{d=o[a>>2];c=o[d>>2];switch(c|0){case 1:break a;case 0:break c;default:break b}}b=o[a+4>>2];if(o[b+11848>>2]){break b}b=o[b+7052>>2];if(!b){break b}e=o[d+36>>2];o[d+36>>2]=b;i=!Oa(a,(b|0)!=(e|0),1);d=o[a>>2]}if(o[d+12>>2]){b=o[a+4>>2];_b(b+6928|0,b+7060|0)}c=o[a+4>>2];d:{if(o[c+11848>>2]){e=i;break d}d=o[a>>2];e:{if(o[d>>2]){break e}t=o[c+7268>>2];if(t){f:{if(o[c+7260>>2]){k=o[c+6900>>2];v=o[c+6896>>2];b=c+6920|0;h=o[b>>2];b=o[b+4>>2];if((l[t](a,0,0,o[c+7288>>2])|0)==2){break f}o[f>>2]=0;o[f+4>>2]=0;o[f+8>>2]=0;o[f+12>>2]=0;e=o[a>>2];d=o[e+608>>2];w=o[e+612>>2];e=o[a+4>>2];g:{if(!kb(a,d,w,f,o[e+7268>>2],o[e+7264>>2],o[e+7288>>2])){break g}t=o[1357]+o[1356]|0;s=o[1362]+(o[1361]+(o[1360]+(o[1359]+(t+o[1358]|0)|0)|0)|0)|0;e=s+o[1363]>>>3|0;if(e+33>>>0>r[f+12>>2]){o[o[a>>2]>>2]=2;Aa(f);break f}g=c+6936|0;j=p[g+4|0]|p[g+5|0]<<8|(p[g+6|0]<<16|p[g+7|0]<<24);e=e+o[f+8>>2]|0;d=e;g=p[g|0]|p[g+1|0]<<8|(p[g+2|0]<<16|p[g+3|0]<<24);m[d+25|0]=g;m[d+26|0]=g>>>8;m[d+27|0]=g>>>16;m[d+28|0]=g>>>24;m[d+29|0]=j;m[d+30|0]=j>>>8;m[d+31|0]=j>>>16;m[d+32|0]=j>>>24;d=c+6928|0;g=p[d+4|0]|p[d+5|0]<<8|(p[d+6|0]<<16|p[d+7|0]<<24);d=p[d|0]|p[d+1|0]<<8|(p[d+2|0]<<16|p[d+3|0]<<24);m[e+17|0]=d;m[e+18|0]=d>>>8;m[e+19|0]=d>>>16;m[e+20|0]=d>>>24;m[e+21|0]=g;m[e+22|0]=g>>>8;m[e+23|0]=g>>>16;m[e+24|0]=g>>>24;e=s+ -4>>>3|0;if(e+22>>>0>r[f+12>>2]){o[o[a>>2]>>2]=2;Aa(f);break f}g=e+o[f+8>>2]|0;m[g+21|0]=h;d=h;m[g+20|0]=(b&255)<<24|d>>>8;m[g+19|0]=(b&65535)<<16|d>>>16;m[g+18|0]=(b&16777215)<<8|d>>>24;m[g+17|0]=p[g+17|0]&240|b&15;b=t>>>3|0;if(b+23>>>0>r[f+12>>2]){o[o[a>>2]>>2]=2;Aa(f);break f}b=b+o[f+8>>2]|0;m[b+22|0]=k;m[b+21|0]=k>>>8;m[b+20|0]=k>>>16;m[b+19|0]=v;m[b+18|0]=v>>>8;m[b+17|0]=v>>>16;b=o[a>>2];e=o[b+608>>2];d=o[b+612>>2];b=o[a+4>>2];b=jb(a,e,d,f,o[b+7268>>2],o[b+7276>>2],o[b+7288>>2]);Aa(f);if(!b){break f}b=o[o[a+4>>2]+7048>>2];if(!b|!o[b>>2]){break f}e=o[a>>2];if(!(o[e+616>>2]|o[e+620>>2])){break f}Ub(b);o[f>>2]=0;o[f+4>>2]=0;o[f+8>>2]=0;o[f+12>>2]=0;b=o[a>>2];e=o[b+616>>2];d=o[b+620>>2];b=o[a+4>>2];if(!kb(a,e,d,f,o[b+7268>>2],o[b+7264>>2],o[b+7288>>2])){break g}e=o[a+4>>2];b=o[e+7048>>2];h=o[b>>2];if(o[f+12>>2]!=(u(h,18)+4|0)){o[o[a>>2]>>2]=2;Aa(f);break f}if(h){c=o[f+8>>2]+4|0;d=0;while(1){h=o[b+4>>2]+u(d,24)|0;g=o[h>>2];b=o[h+4>>2];j=o[h+8>>2];e=o[h+12>>2];h=o[h+16>>2];m[c+17|0]=h;m[c+15|0]=j;m[c+7|0]=g;m[c+16|0]=h>>>8;m[c+14|0]=(e&255)<<24|j>>>8;m[c+13|0]=(e&65535)<<16|j>>>16;m[c+12|0]=(e&16777215)<<8|j>>>24;m[c+11|0]=e;m[c+10|0]=e>>>8;m[c+9|0]=e>>>16;m[c+8|0]=e>>>24;m[c+6|0]=(b&255)<<24|g>>>8;m[c+5|0]=(b&65535)<<16|g>>>16;m[c+4|0]=(b&16777215)<<8|g>>>24;m[c+3|0]=b;m[c+2|0]=b>>>8;m[c+1|0]=b>>>16;m[c|0]=b>>>24;c=c+18|0;d=d+1|0;e=o[a+4>>2];b=o[e+7048>>2];if(d>>>0<r[b>>2]){continue}break}}b=o[a>>2];jb(a,o[b+616>>2],o[b+620>>2],f,o[e+7268>>2],o[e+7276>>2],o[e+7288>>2])}Aa(f);break f}v=o[c+6912>>2];j=o[c+6900>>2];k=o[c+6896>>2];b=c+6920|0;e=o[b>>2];b=o[b+4>>2];h:{i:{w=a;g=o[d+612>>2];s=o[1357]+o[1356]|0;x=o[1362]+(o[1361]+(o[1360]+(o[1359]+(s+o[1358]|0)|0)|0)|0)|0;h=(x+o[1363]>>>3|0)+4|0;d=h+o[d+608>>2]|0;if(d>>>0<h>>>0){g=g+1|0}switch(l[t](w,d,g,o[c+7288>>2])|0){case 0:break h;case 1:break i;default:break f}}o[o[a>>2]>>2]=5;break f}h=o[a+4>>2];if(l[o[h+7276>>2]](a,c+6928|0,16,0,0,o[h+7288>>2])){o[o[a>>2]>>2]=5;break f}m[f+4|0]=e;m[f+3|0]=(b&255)<<24|e>>>8;m[f+2|0]=(b&65535)<<16|e>>>16;m[f+1|0]=(b&16777215)<<8|e>>>24;m[f|0]=(b&15|v<<4)+240;e=o[a+4>>2];j:{k:{d=(x+ -4>>>3|0)+4|0;b=o[a>>2];h=d+o[b+608>>2]|0;b=o[b+612>>2];switch(l[o[e+7268>>2]](a,h,h>>>0<d>>>0?b+1|0:b,o[e+7288>>2])|0){case 0:break j;case 1:break k;default:break f}}o[o[a>>2]>>2]=5;break f}b=o[a+4>>2];if(l[o[b+7276>>2]](a,f,5,0,0,o[b+7288>>2])){o[o[a>>2]>>2]=5;break f}m[f+5|0]=j;m[f+4|0]=j>>>8;m[f+3|0]=j>>>16;m[f+2|0]=k;m[f+1|0]=k>>>8;m[f|0]=k>>>16;b=o[a+4>>2];l:{m:{d=(s>>>3|0)+4|0;h=o[a>>2];e=d+o[h+608>>2]|0;k=o[h+612>>2];switch(l[o[b+7268>>2]](a,e,e>>>0<d>>>0?k+1|0:k,o[b+7288>>2])|0){case 0:break l;case 1:break m;default:break f}}o[o[a>>2]>>2]=5;break f}b=o[a+4>>2];if(l[o[b+7276>>2]](a,f,6,0,0,o[b+7288>>2])){o[o[a>>2]>>2]=5;break f}b=o[o[a+4>>2]+7048>>2];if(!b|!o[b>>2]){break f}e=o[a>>2];if(!(o[e+616>>2]|o[e+620>>2])){break f}Ub(b);b=o[a+4>>2];n:{o:{p:{h=o[a>>2];e=o[h+616>>2]+4|0;g=o[h+620>>2];switch(l[o[b+7268>>2]](a,e,e>>>0<4?g+1|0:g,o[b+7288>>2])|0){case 1:break o;case 0:break p;default:break f}}d=o[a+4>>2];c=o[d+7048>>2];if(!o[c>>2]){break f}e=0;break n}o[o[a>>2]>>2]=5;break f}while(1){q:{t=0;v=u(e,24);g=v+o[c+4>>2]|0;b=o[g+4>>2];j=o[g>>2];s=j<<24|j<<8&16711680;k=b<<24|j>>>8;g=b<<8|j>>>24;s=k&65280|g&255|s;o[f>>2]=((b&255)<<24|j>>>8)&-16777216|((b&16777215)<<8|j>>>24)&16711680|(b>>>8&65280|b>>>24)|t;o[f+4>>2]=s;g=v+o[c+4>>2]|0;b=o[g+12>>2];j=o[g+8>>2];s=j<<24|j<<8&16711680;k=b<<24|j>>>8;g=b<<8|j>>>24;s=k&65280|g&255|s;o[f+8>>2]=((b&255)<<24|j>>>8)&-16777216|((b&16777215)<<8|j>>>24)&16711680|(b>>>8&65280|b>>>24)|t;o[f+12>>2]=s;b=q[(v+o[c+4>>2]|0)+16>>1];n[f+16>>1]=(b<<24|b<<8&16711680)>>>16;if(l[o[d+7276>>2]](a,f,18,0,0,o[d+7288>>2])){break q}e=e+1|0;d=o[a+4>>2];c=o[d+7048>>2];if(e>>>0<r[c>>2]){continue}break f}break}o[o[a>>2]>>2]=5}c=o[a+4>>2];d=o[a>>2];i=o[d>>2]?1:i}b=o[c+7280>>2];if(!b){break e}l[b](a,c+6872|0,o[c+7288>>2]);d=o[a>>2]}if(!o[d+4>>2]){e=i;break d}b=o[o[a+4>>2]+11752>>2];if(!b){e=i;break d}if($a(b)){e=i;break d}e=1;if(i){break d}o[o[a>>2]>>2]=4}c=o[a+4>>2];b=o[c+7296>>2];if(b){if((b|0)!=o[1896]){Cb(b);c=o[a+4>>2]}o[c+7296>>2]=0}if(o[c+7260>>2]){sb(o[a>>2]+640|0)}c=o[a>>2];b=o[c+600>>2];if(b){X(b);c=o[a>>2];b=c;o[b+600>>2]=0;o[b+604>>2]=0}if(o[c+24>>2]){i=0;while(1){b=o[a+4>>2];h=i<<2;d=o[(b+h|0)+7328>>2];if(d){X(d);o[(h+o[a+4>>2]|0)+7328>>2]=0;b=o[a+4>>2]}b=o[(b+h|0)+7368>>2];if(b){X(b);o[(h+o[a+4>>2]|0)+7368>>2]=0}i=i+1|0;if(i>>>0<r[o[a>>2]+24>>2]){continue}break}}c=o[a+4>>2];b=o[c+7360>>2];if(b){X(b);o[o[a+4>>2]+7360>>2]=0;c=o[a+4>>2]}b=o[c+7400>>2];if(b){X(b);o[o[a+4>>2]+7400>>2]=0;c=o[a+4>>2]}b=o[c+7364>>2];if(b){X(b);o[o[a+4>>2]+7364>>2]=0;c=o[a+4>>2]}b=o[c+7404>>2];if(b){X(b);o[o[a+4>>2]+7404>>2]=0;c=o[a+4>>2]}d=o[a>>2];if(o[d+40>>2]){i=0;while(1){b=i<<2;h=o[(b+c|0)+7408>>2];if(h){X(h);o[(b+o[a+4>>2]|0)+7408>>2]=0;c=o[a+4>>2];d=o[a>>2]}i=i+1|0;if(i>>>0<r[d+40>>2]){continue}break}}b=o[c+7536>>2];if(b){X(b);c=o[a+4>>2];o[c+7536>>2]=0;d=o[a>>2]}if(o[d+24>>2]){d=0;while(1){b=d<<3;i=o[(b+c|0)+7540>>2];if(i){X(i);o[(b+o[a+4>>2]|0)+7540>>2]=0;c=o[a+4>>2]}i=o[(b+c|0)+7544>>2];if(i){X(i);o[(b+o[a+4>>2]|0)+7544>>2]=0;c=o[a+4>>2]}d=d+1|0;if(d>>>0<r[o[a>>2]+24>>2]){continue}break}}b=o[c+7604>>2];if(b){X(b);o[o[a+4>>2]+7604>>2]=0;c=o[a+4>>2]}b=o[c+7608>>2];if(b){X(b);o[o[a+4>>2]+7608>>2]=0;c=o[a+4>>2]}b=o[c+7612>>2];if(b){X(b);o[o[a+4>>2]+7612>>2]=0;c=o[a+4>>2]}b=o[c+7616>>2];if(b){X(b);o[o[a+4>>2]+7616>>2]=0;c=o[a+4>>2]}b=o[c+7620>>2];if(b){X(b);c=o[a+4>>2];o[c+7620>>2]=0}b=o[c+7624>>2];if(b){X(b);c=o[a+4>>2];o[c+7624>>2]=0}i=o[a>>2];if(!(!o[i+4>>2]|!o[i+24>>2])){d=0;while(1){b=d<<2;h=o[(b+c|0)+11764>>2];if(h){X(h);o[(b+o[a+4>>2]|0)+11764>>2]=0;c=o[a+4>>2];i=o[a>>2]}d=d+1|0;if(d>>>0<r[i+24>>2]){continue}break}}ve(o[c+6856>>2]);b=o[a>>2];o[b+44>>2]=13;o[b+48>>2]=1056964608;o[b+36>>2]=0;o[b+40>>2]=1;o[b+28>>2]=16;o[b+32>>2]=44100;o[b+20>>2]=0;o[b+24>>2]=2;o[b+12>>2]=1;o[b+16>>2]=0;o[b+4>>2]=0;o[b+8>>2]=1;h=o[a>>2];b=h;o[b+592>>2]=0;o[b+596>>2]=0;o[b+556>>2]=0;o[b+560>>2]=0;o[b+564>>2]=0;o[b+568>>2]=0;o[b+572>>2]=0;o[b+576>>2]=0;o[b+580>>2]=0;o[b+584>>2]=0;o[b+600>>2]=0;o[b+604>>2]=0;b=o[a+4>>2];o[b+7248>>2]=0;o[b+7252>>2]=0;o[b+7048>>2]=0;i=b+7256|0;o[i>>2]=0;o[i+4>>2]=0;i=b+7264|0;o[i>>2]=0;o[i+4>>2]=0;i=b+7272|0;o[i>>2]=0;o[i+4>>2]=0;i=b+7280|0;o[i>>2]=0;o[i+4>>2]=0;o[b+7288>>2]=0;o[h+632>>2]=0;o[h+636>>2]=0;c=o[a>>2];r:{if(o[c>>2]!=1){break r}o[c+16>>2]=1;o[c+20>>2]=0;_a(a,10777);c=o[a>>2];if(o[c>>2]!=1){break r}o[c+576>>2]=0;o[c+580>>2]=5;o[c+564>>2]=0;o[c+568>>2]=0;o[c+556>>2]=8;o[c+560>>2]=0}if(!e){o[c>>2]=1}c=!e}N=f+32|0;return c|0}function $b(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,q=0,s=0;Ee(e,0,c,0);a:{if(Q){break a}h=u(c,e);Ee(d,0,h,0);if(Q){break a}g=o[a+88>>2];l=u(d,h);b:{if(r[a+92>>2]>=l>>>0){f=g;break b}f=ea(g,l);c:{if(!f){X(g);f=da(l);o[a+88>>2]=f;if(f){break c}o[a+92>>2]=0;return 0}o[a+88>>2]=f}o[a+92>>2]=l}d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{g=u(e,100)+c|0;if((g|0)<=300){p:{switch(g+ -101|0){case 3:break h;case 5:break i;case 7:break j;case 2:case 4:case 6:break e;case 0:break f;case 1:break g;default:break p}}switch(g+ -201|0){case 0:break k;case 1:break l;case 3:break m;case 5:break n;case 7:break o;default:break e}}q:{r:{s:{switch(g+ -401|0){default:switch(g+ -301|0){case 0:break q;case 1:break r;default:break e};case 7:if(!d){break d}s=o[b+28>>2];i=o[b+24>>2];q=o[b+20>>2];h=o[b+16>>2];k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){j=c<<2;o[f>>2]=o[j+b>>2];o[f+4>>2]=o[e+j>>2];o[f+8>>2]=o[g+j>>2];o[f+12>>2]=o[k+j>>2];o[f+16>>2]=o[h+j>>2];o[f+20>>2]=o[j+q>>2];o[f+24>>2]=o[i+j>>2];o[f+28>>2]=o[j+s>>2];f=f+32|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d;case 5:if(!d){break d}q=o[b+20>>2];h=o[b+16>>2];k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){i=c<<2;o[f>>2]=o[i+b>>2];o[f+4>>2]=o[e+i>>2];o[f+8>>2]=o[g+i>>2];o[f+12>>2]=o[i+k>>2];o[f+16>>2]=o[h+i>>2];o[f+20>>2]=o[i+q>>2];f=f+24|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d;case 3:if(!d){break d}k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){h=c<<2;o[f>>2]=o[h+b>>2];o[f+4>>2]=o[e+h>>2];o[f+8>>2]=o[g+h>>2];o[f+12>>2]=o[h+k>>2];f=f+16|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d;case 1:if(!d){break d}g=o[b+4>>2];e=o[b>>2];b=0;while(1){c=b<<2;o[f>>2]=o[c+e>>2];o[f+4>>2]=o[c+g>>2];f=f+8|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}break d;case 0:break s;case 2:case 4:case 6:break e}}if(!d){break d}c=o[b>>2];b=0;while(1){o[f>>2]=o[c+(b<<2)>>2];f=f+4|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}break d}if(!d){break d}c=0;while(1){e=c<<2;g=o[e+o[b>>2]>>2];m[f|0]=g;m[f+2|0]=g>>>16;m[f+1|0]=g>>>8;e=o[e+o[b+4>>2]>>2];m[f+3|0]=e;m[f+5|0]=e>>>16;m[f+4|0]=e>>>8;f=f+6|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}c=0;while(1){e=o[o[b>>2]+(c<<2)>>2];m[f|0]=e;m[f+2|0]=e>>>16;m[f+1|0]=e>>>8;f=f+3|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}s=o[b+28>>2];i=o[b+24>>2];q=o[b+20>>2];h=o[b+16>>2];k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){j=c<<2;n[f>>1]=o[j+b>>2];n[f+2>>1]=o[e+j>>2];n[f+4>>1]=o[g+j>>2];n[f+6>>1]=o[k+j>>2];n[f+8>>1]=o[h+j>>2];n[f+10>>1]=o[j+q>>2];n[f+12>>1]=o[i+j>>2];n[f+14>>1]=o[j+s>>2];f=f+16|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}q=o[b+20>>2];h=o[b+16>>2];k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){i=c<<2;n[f>>1]=o[i+b>>2];n[f+2>>1]=o[e+i>>2];n[f+4>>1]=o[g+i>>2];n[f+6>>1]=o[i+k>>2];n[f+8>>1]=o[h+i>>2];n[f+10>>1]=o[i+q>>2];f=f+12|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}k=o[b+12>>2];g=o[b+8>>2];e=o[b+4>>2];b=o[b>>2];c=0;while(1){h=c<<2;n[f>>1]=o[h+b>>2];n[f+2>>1]=o[e+h>>2];n[f+4>>1]=o[g+h>>2];n[f+6>>1]=o[h+k>>2];f=f+8|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}g=o[b+4>>2];e=o[b>>2];b=0;while(1){c=b<<2;n[f>>1]=o[c+e>>2];n[f+2>>1]=o[c+g>>2];f=f+4|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}break d}if(!d){break d}c=o[b>>2];b=0;while(1){n[f>>1]=o[c+(b<<2)>>2];f=f+2|0;b=b+1|0;if((d|0)!=(b|0)){continue}break}break d}if(!d){break d}e=0;while(1){c=e<<2;m[f|0]=o[c+o[b>>2]>>2];m[f+1|0]=o[c+o[b+4>>2]>>2];m[f+2|0]=o[c+o[b+8>>2]>>2];m[f+3|0]=o[c+o[b+12>>2]>>2];m[f+4|0]=o[c+o[b+16>>2]>>2];m[f+5|0]=o[c+o[b+20>>2]>>2];m[f+6|0]=o[c+o[b+24>>2]>>2];m[f+7|0]=o[c+o[b+28>>2]>>2];f=f+8|0;e=e+1|0;if((e|0)!=(d|0)){continue}break}break d}if(!d){break d}e=0;while(1){c=e<<2;m[f|0]=o[c+o[b>>2]>>2];m[f+1|0]=o[c+o[b+4>>2]>>2];m[f+2|0]=o[c+o[b+8>>2]>>2];m[f+3|0]=o[c+o[b+12>>2]>>2];m[f+4|0]=o[c+o[b+16>>2]>>2];m[f+5|0]=o[c+o[b+20>>2]>>2];f=f+6|0;e=e+1|0;if((e|0)!=(d|0)){continue}break}break d}if(!d){break d}e=0;while(1){c=e<<2;m[f|0]=o[c+o[b>>2]>>2];m[f+1|0]=o[c+o[b+4>>2]>>2];m[f+2|0]=o[c+o[b+8>>2]>>2];m[f+3|0]=o[c+o[b+12>>2]>>2];f=f+4|0;e=e+1|0;if((e|0)!=(d|0)){continue}break}break d}if(!d){break d}c=0;while(1){e=c<<2;m[f|0]=o[e+o[b>>2]>>2];m[f+1|0]=o[e+o[b+4>>2]>>2];f=f+2|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}if(!d){break d}c=0;while(1){m[f|0]=o[o[b>>2]+(c<<2)>>2];f=f+1|0;c=c+1|0;if((d|0)!=(c|0)){continue}break}break d}t:{switch(e+ -1|0){case 3:if(!c|!d){break d}g=0;while(1){e=0;while(1){o[f>>2]=o[o[(e<<2)+b>>2]+(g<<2)>>2];f=f+4|0;e=e+1|0;if((e|0)!=(c|0)){continue}break}g=g+1|0;if((g|0)!=(d|0)){continue}break}break d;case 2:if(!c|!d){break d}while(1){e=0;while(1){g=o[o[(e<<2)+b>>2]+(k<<2)>>2];m[f|0]=g;m[f+2|0]=g>>>16;m[f+1|0]=g>>>8;f=f+3|0;e=e+1|0;if((e|0)!=(c|0)){continue}break}k=k+1|0;if((k|0)!=(d|0)){continue}break}break d;case 1:if(!c|!d){break d}g=0;while(1){e=0;while(1){n[f>>1]=o[o[(e<<2)+b>>2]+(g<<2)>>2];f=f+2|0;e=e+1|0;if((e|0)!=(c|0)){continue}break}g=g+1|0;if((g|0)!=(d|0)){continue}break}break d;case 0:break t;default:break d}}if(!c|!d){break d}g=0;while(1){e=0;while(1){m[f|0]=o[o[(e<<2)+b>>2]+(g<<2)>>2];f=f+1|0;e=e+1|0;if((e|0)!=(c|0)){continue}break}g=g+1|0;if((g|0)!=(d|0)){continue}break}}c=o[a+80>>2];b=c+l|0;o[a+80>>2]=b;d=o[a+88>>2];if(b>>>0<c>>>0){o[a+84>>2]=o[a+84>>2]+1}e=64-(c&63)|0;b=(a-e|0)- -64|0;u:{if(l>>>0<e>>>0){ca(b,d,l);break u}ca(b,d,e);c=a- -64|0;Ra(c,a);f=d+e|0;b=l-e|0;if(b>>>0>=64){while(1){e=p[f+4|0]|p[f+5|0]<<8|(p[f+6|0]<<16|p[f+7|0]<<24);d=p[f|0]|p[f+1|0]<<8|(p[f+2|0]<<16|p[f+3|0]<<24);m[a|0]=d;m[a+1|0]=d>>>8;m[a+2|0]=d>>>16;m[a+3|0]=d>>>24;m[a+4|0]=e;m[a+5|0]=e>>>8;m[a+6|0]=e>>>16;m[a+7|0]=e>>>24;e=p[f+60|0]|p[f+61|0]<<8|(p[f+62|0]<<16|p[f+63|0]<<24);d=p[f+56|0]|p[f+57|0]<<8|(p[f+58|0]<<16|p[f+59|0]<<24);m[a+56|0]=d;m[a+57|0]=d>>>8;m[a+58|0]=d>>>16;m[a+59|0]=d>>>24;m[a+60|0]=e;m[a+61|0]=e>>>8;m[a+62|0]=e>>>16;m[a+63|0]=e>>>24;e=p[f+52|0]|p[f+53|0]<<8|(p[f+54|0]<<16|p[f+55|0]<<24);d=p[f+48|0]|p[f+49|0]<<8|(p[f+50|0]<<16|p[f+51|0]<<24);m[a+48|0]=d;m[a+49|0]=d>>>8;m[a+50|0]=d>>>16;m[a+51|0]=d>>>24;m[a+52|0]=e;m[a+53|0]=e>>>8;m[a+54|0]=e>>>16;m[a+55|0]=e>>>24;e=p[f+44|0]|p[f+45|0]<<8|(p[f+46|0]<<16|p[f+47|0]<<24);d=p[f+40|0]|p[f+41|0]<<8|(p[f+42|0]<<16|p[f+43|0]<<24);m[a+40|0]=d;m[a+41|0]=d>>>8;m[a+42|0]=d>>>16;m[a+43|0]=d>>>24;m[a+44|0]=e;m[a+45|0]=e>>>8;m[a+46|0]=e>>>16;m[a+47|0]=e>>>24;e=p[f+36|0]|p[f+37|0]<<8|(p[f+38|0]<<16|p[f+39|0]<<24);d=p[f+32|0]|p[f+33|0]<<8|(p[f+34|0]<<16|p[f+35|0]<<24);m[a+32|0]=d;m[a+33|0]=d>>>8;m[a+34|0]=d>>>16;m[a+35|0]=d>>>24;m[a+36|0]=e;m[a+37|0]=e>>>8;m[a+38|0]=e>>>16;m[a+39|0]=e>>>24;e=p[f+28|0]|p[f+29|0]<<8|(p[f+30|0]<<16|p[f+31|0]<<24);d=p[f+24|0]|p[f+25|0]<<8|(p[f+26|0]<<16|p[f+27|0]<<24);m[a+24|0]=d;m[a+25|0]=d>>>8;m[a+26|0]=d>>>16;m[a+27|0]=d>>>24;m[a+28|0]=e;m[a+29|0]=e>>>8;m[a+30|0]=e>>>16;m[a+31|0]=e>>>24;e=p[f+20|0]|p[f+21|0]<<8|(p[f+22|0]<<16|p[f+23|0]<<24);d=p[f+16|0]|p[f+17|0]<<8|(p[f+18|0]<<16|p[f+19|0]<<24);m[a+16|0]=d;m[a+17|0]=d>>>8;m[a+18|0]=d>>>16;m[a+19|0]=d>>>24;m[a+20|0]=e;m[a+21|0]=e>>>8;m[a+22|0]=e>>>16;m[a+23|0]=e>>>24;e=p[f+12|0]|p[f+13|0]<<8|(p[f+14|0]<<16|p[f+15|0]<<24);d=p[f+8|0]|p[f+9|0]<<8|(p[f+10|0]<<16|p[f+11|0]<<24);m[a+8|0]=d;m[a+9|0]=d>>>8;m[a+10|0]=d>>>16;m[a+11|0]=d>>>24;m[a+12|0]=e;m[a+13|0]=e>>>8;m[a+14|0]=e>>>16;m[a+15|0]=e>>>24;Ra(c,a);f=f- -64|0;b=b+ -64|0;if(b>>>0>63){continue}break}}ca(a,f,b)}f=1}return f}function _d(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;a:{if(d>>>0>=13){if((b|0)<1){break a}s=d+ -13|0;while(1){B=0;C=0;z=0;A=0;x=0;y=0;v=0;w=0;t=0;q=0;m=0;k=0;p=0;j=0;n=0;h=0;r=0;l=0;i=0;d=0;b:{switch(s|0){case 19:B=u(o[((g<<2)+f|0)+ -128>>2],o[c+124>>2]);case 18:C=u(o[((g<<2)+f|0)+ -124>>2],o[c+120>>2])+B|0;case 17:z=u(o[((g<<2)+f|0)+ -120>>2],o[c+116>>2])+C|0;case 16:A=u(o[((g<<2)+f|0)+ -116>>2],o[c+112>>2])+z|0;case 15:x=u(o[((g<<2)+f|0)+ -112>>2],o[c+108>>2])+A|0;case 14:y=u(o[((g<<2)+f|0)+ -108>>2],o[c+104>>2])+x|0;case 13:v=u(o[((g<<2)+f|0)+ -104>>2],o[c+100>>2])+y|0;case 12:w=u(o[((g<<2)+f|0)+ -100>>2],o[c+96>>2])+v|0;case 11:t=u(o[((g<<2)+f|0)+ -96>>2],o[c+92>>2])+w|0;case 10:q=u(o[((g<<2)+f|0)+ -92>>2],o[c+88>>2])+t|0;case 9:m=u(o[((g<<2)+f|0)+ -88>>2],o[c+84>>2])+q|0;case 8:k=u(o[((g<<2)+f|0)+ -84>>2],o[c+80>>2])+m|0;case 7:p=u(o[((g<<2)+f|0)+ -80>>2],o[c+76>>2])+k|0;case 6:j=u(o[((g<<2)+f|0)+ -76>>2],o[c+72>>2])+p|0;case 5:n=u(o[((g<<2)+f|0)+ -72>>2],o[c+68>>2])+j|0;case 4:h=u(o[((g<<2)+f|0)+ -68>>2],o[c+64>>2])+n|0;case 3:r=u(o[((g<<2)+f|0)+ -64>>2],o[c+60>>2])+h|0;case 2:l=u(o[((g<<2)+f|0)+ -60>>2],o[c+56>>2])+r|0;case 1:i=u(o[((g<<2)+f|0)+ -56>>2],o[c+52>>2])+l|0;case 0:d=(g<<2)+f|0;d=((((((((((((u(o[d+ -52>>2],o[c+48>>2])+i|0)+u(o[d+ -48>>2],o[c+44>>2])|0)+u(o[d+ -44>>2],o[c+40>>2])|0)+u(o[d+ -40>>2],o[c+36>>2])|0)+u(o[d+ -36>>2],o[c+32>>2])|0)+u(o[d+ -32>>2],o[c+28>>2])|0)+u(o[d+ -28>>2],o[c+24>>2])|0)+u(o[d+ -24>>2],o[c+20>>2])|0)+u(o[d+ -20>>2],o[c+16>>2])|0)+u(o[d+ -16>>2],o[c+12>>2])|0)+u(o[d+ -12>>2],o[c+8>>2])|0)+u(o[d+ -8>>2],o[c+4>>2])|0)+u(o[d+ -4>>2],o[c>>2])|0;break;default:break b}}i=g<<2;o[i+f>>2]=o[a+i>>2]+(d>>e);g=g+1|0;if((g|0)!=(b|0)){continue}break}break a}if(d>>>0>=9){if(d>>>0>=11){if((d|0)!=12){if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];j=o[f+ -32>>2];p=o[f+ -36>>2];k=o[f+ -40>>2];m=o[f+ -44>>2];D=o[c>>2];E=o[c+4>>2];B=o[c+8>>2];C=o[c+12>>2];z=o[c+16>>2];A=o[c+20>>2];x=o[c+24>>2];y=o[c+28>>2];v=o[c+32>>2];w=o[c+36>>2];t=o[c+40>>2];c=0;while(1){s=k;m=u(k,w)+u(m,t)|0;k=p;m=m+u(v,k)|0;p=j;m=u(j,y)+m|0;j=n;m=m+u(x,j)|0;n=h;m=u(h,A)+m|0;h=r;m=m+u(z,h)|0;r=l;m=u(l,C)+m|0;l=i;q=u(i,B)+m|0;i=d;m=c<<2;q=u(d,E)+q|0;d=g;g=o[m+a>>2]+(q+u(D,d)>>e)|0;o[f+m>>2]=g;m=s;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];j=o[f+ -32>>2];p=o[f+ -36>>2];k=o[f+ -40>>2];m=o[f+ -44>>2];q=o[f+ -48>>2];F=o[c>>2];G=o[c+4>>2];D=o[c+8>>2];E=o[c+12>>2];B=o[c+16>>2];C=o[c+20>>2];z=o[c+24>>2];A=o[c+28>>2];x=o[c+32>>2];y=o[c+36>>2];v=o[c+40>>2];w=o[c+44>>2];c=0;while(1){s=m;q=u(m,v)+u(q,w)|0;m=k;q=u(k,y)+q|0;k=p;q=q+u(x,k)|0;p=j;q=u(j,A)+q|0;j=n;q=q+u(z,j)|0;n=h;q=u(h,C)+q|0;h=r;q=q+u(B,h)|0;r=l;q=u(l,E)+q|0;l=i;t=u(i,D)+q|0;i=d;q=c<<2;t=u(d,G)+t|0;d=g;g=o[q+a>>2]+(t+u(F,d)>>e)|0;o[f+q>>2]=g;q=s;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=10){if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];j=o[f+ -32>>2];p=o[f+ -36>>2];z=o[c>>2];A=o[c+4>>2];x=o[c+8>>2];y=o[c+12>>2];v=o[c+16>>2];w=o[c+20>>2];t=o[c+24>>2];q=o[c+28>>2];s=o[c+32>>2];c=0;while(1){k=j;p=u(j,q)+u(p,s)|0;j=n;p=p+u(t,j)|0;n=h;p=u(h,w)+p|0;h=r;p=p+u(v,h)|0;r=l;p=u(l,y)+p|0;l=i;m=u(i,x)+p|0;i=d;p=c<<2;m=u(d,A)+m|0;d=g;g=o[p+a>>2]+(m+u(z,d)>>e)|0;o[f+p>>2]=g;p=k;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];j=o[f+ -32>>2];p=o[f+ -36>>2];k=o[f+ -40>>2];B=o[c>>2];C=o[c+4>>2];z=o[c+8>>2];A=o[c+12>>2];x=o[c+16>>2];y=o[c+20>>2];v=o[c+24>>2];w=o[c+28>>2];t=o[c+32>>2];q=o[c+36>>2];c=0;while(1){m=p;k=u(t,m)+u(k,q)|0;p=j;k=u(j,w)+k|0;j=n;k=k+u(v,j)|0;n=h;k=u(h,y)+k|0;h=r;k=k+u(x,h)|0;r=l;k=u(l,A)+k|0;l=i;s=u(i,z)+k|0;i=d;k=c<<2;s=u(d,C)+s|0;d=g;g=o[k+a>>2]+(s+u(B,d)>>e)|0;o[f+k>>2]=g;k=m;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=5){if(d>>>0>=7){if((d|0)!=8){if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];v=o[c>>2];w=o[c+4>>2];t=o[c+8>>2];q=o[c+12>>2];s=o[c+16>>2];m=o[c+20>>2];k=o[c+24>>2];c=0;while(1){j=h;n=u(h,m)+u(k,n)|0;h=r;n=n+u(s,h)|0;r=l;n=u(l,q)+n|0;l=i;p=u(i,t)+n|0;i=d;n=c<<2;p=u(d,w)+p|0;d=g;g=o[n+a>>2]+(p+u(v,d)>>e)|0;o[f+n>>2]=g;n=j;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];n=o[f+ -28>>2];j=o[f+ -32>>2];x=o[c>>2];y=o[c+4>>2];v=o[c+8>>2];w=o[c+12>>2];t=o[c+16>>2];q=o[c+20>>2];s=o[c+24>>2];m=o[c+28>>2];c=0;while(1){p=n;j=u(s,n)+u(j,m)|0;n=h;j=u(h,q)+j|0;h=r;j=j+u(t,h)|0;r=l;j=u(l,w)+j|0;l=i;k=u(i,v)+j|0;i=d;j=c<<2;k=u(d,y)+k|0;d=g;g=o[j+a>>2]+(k+u(x,d)>>e)|0;o[f+j>>2]=g;j=p;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=6){if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];s=o[c>>2];m=o[c+4>>2];k=o[c+8>>2];p=o[c+12>>2];j=o[c+16>>2];c=0;while(1){h=l;r=u(p,h)+u(j,r)|0;l=i;n=u(i,k)+r|0;i=d;r=c<<2;n=u(d,m)+n|0;d=g;g=o[r+a>>2]+(n+u(s,d)>>e)|0;o[f+r>>2]=g;r=h;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];r=o[f+ -20>>2];h=o[f+ -24>>2];t=o[c>>2];q=o[c+4>>2];s=o[c+8>>2];m=o[c+12>>2];k=o[c+16>>2];p=o[c+20>>2];c=0;while(1){n=r;h=u(k,n)+u(h,p)|0;r=l;h=u(l,m)+h|0;l=i;j=u(i,s)+h|0;i=d;h=c<<2;j=u(d,q)+j|0;d=g;g=o[h+a>>2]+(j+u(t,d)>>e)|0;o[f+h>>2]=g;h=n;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=3){if((d|0)!=4){if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];j=o[c>>2];n=o[c+4>>2];h=o[c+8>>2];c=0;while(1){l=d;r=c<<2;i=u(d,n)+u(i,h)|0;d=g;g=o[r+a>>2]+(i+u(j,d)>>e)|0;o[f+r>>2]=g;i=l;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];i=o[f+ -12>>2];l=o[f+ -16>>2];k=o[c>>2];p=o[c+4>>2];j=o[c+8>>2];n=o[c+12>>2];c=0;while(1){r=i;h=u(i,j)+u(l,n)|0;i=d;l=c<<2;h=u(d,p)+h|0;d=g;g=o[l+a>>2]+(h+u(k,d)>>e)|0;o[f+l>>2]=g;l=r;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=2){if((b|0)<1){break a}g=o[f+ -4>>2];i=o[c>>2];c=0;while(1){d=c<<2;g=o[d+a>>2]+(u(g,i)>>e)|0;o[d+f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}g=o[f+ -4>>2];d=o[f+ -8>>2];h=o[c>>2];r=o[c+4>>2];c=0;while(1){i=g;l=c<<2;g=o[l+a>>2]+(u(g,h)+u(d,r)>>e)|0;o[f+l>>2]=g;d=i;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function be(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0;a:{if(d>>>0>=13){if((b|0)<1){break a}B=d+ -13|0;while(1){s=0;w=0;v=0;y=0;x=0;A=0;z=0;C=0;t=0;r=0;q=0;p=0;n=0;m=0;l=0;k=0;j=0;i=0;h=0;d=0;b:{switch(B|0){case 19:s=u(o[((g<<2)+a|0)+ -128>>2],o[c+124>>2]);case 18:w=u(o[((g<<2)+a|0)+ -124>>2],o[c+120>>2])+s|0;case 17:v=u(o[((g<<2)+a|0)+ -120>>2],o[c+116>>2])+w|0;case 16:y=u(o[((g<<2)+a|0)+ -116>>2],o[c+112>>2])+v|0;case 15:x=u(o[((g<<2)+a|0)+ -112>>2],o[c+108>>2])+y|0;case 14:A=u(o[((g<<2)+a|0)+ -108>>2],o[c+104>>2])+x|0;case 13:z=u(o[((g<<2)+a|0)+ -104>>2],o[c+100>>2])+A|0;case 12:C=u(o[((g<<2)+a|0)+ -100>>2],o[c+96>>2])+z|0;case 11:t=u(o[((g<<2)+a|0)+ -96>>2],o[c+92>>2])+C|0;case 10:r=u(o[((g<<2)+a|0)+ -92>>2],o[c+88>>2])+t|0;case 9:q=u(o[((g<<2)+a|0)+ -88>>2],o[c+84>>2])+r|0;case 8:p=u(o[((g<<2)+a|0)+ -84>>2],o[c+80>>2])+q|0;case 7:n=u(o[((g<<2)+a|0)+ -80>>2],o[c+76>>2])+p|0;case 6:m=u(o[((g<<2)+a|0)+ -76>>2],o[c+72>>2])+n|0;case 5:l=u(o[((g<<2)+a|0)+ -72>>2],o[c+68>>2])+m|0;case 4:k=u(o[((g<<2)+a|0)+ -68>>2],o[c+64>>2])+l|0;case 3:j=u(o[((g<<2)+a|0)+ -64>>2],o[c+60>>2])+k|0;case 2:i=u(o[((g<<2)+a|0)+ -60>>2],o[c+56>>2])+j|0;case 1:h=u(o[((g<<2)+a|0)+ -56>>2],o[c+52>>2])+i|0;case 0:d=(g<<2)+a|0;d=((((((((((((u(o[d+ -52>>2],o[c+48>>2])+h|0)+u(o[d+ -48>>2],o[c+44>>2])|0)+u(o[d+ -44>>2],o[c+40>>2])|0)+u(o[d+ -40>>2],o[c+36>>2])|0)+u(o[d+ -36>>2],o[c+32>>2])|0)+u(o[d+ -32>>2],o[c+28>>2])|0)+u(o[d+ -28>>2],o[c+24>>2])|0)+u(o[d+ -24>>2],o[c+20>>2])|0)+u(o[d+ -20>>2],o[c+16>>2])|0)+u(o[d+ -16>>2],o[c+12>>2])|0)+u(o[d+ -12>>2],o[c+8>>2])|0)+u(o[d+ -8>>2],o[c+4>>2])|0)+u(o[d+ -4>>2],o[c>>2])|0;break;default:break b}}h=g<<2;o[h+f>>2]=o[a+h>>2]-(d>>e);g=g+1|0;if((g|0)!=(b|0)){continue}break}break a}if(d>>>0>=9){if(d>>>0>=11){if((d|0)!=12){if((b|0)<1){break a}q=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];k=o[a+ -28>>2];l=o[a+ -32>>2];m=o[a+ -36>>2];n=o[a+ -40>>2];r=o[a+ -44>>2];t=o[c>>2];s=o[c+4>>2];w=o[c+8>>2];v=o[c+12>>2];y=o[c+16>>2];x=o[c+20>>2];A=o[c+24>>2];z=o[c+28>>2];C=o[c+32>>2];B=o[c+36>>2];E=o[c+40>>2];c=0;while(1){p=n;n=m;m=l;l=k;k=j;j=i;i=h;h=d;d=g;g=q;D=c<<2;q=o[D+a>>2];o[f+D>>2]=q-((((((((((u(p,B)+u(r,E)|0)+u(n,C)|0)+u(m,z)|0)+u(l,A)|0)+u(k,x)|0)+u(j,y)|0)+u(i,v)|0)+u(h,w)|0)+u(d,s)|0)+u(g,t)>>e);r=p;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}r=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];k=o[a+ -28>>2];l=o[a+ -32>>2];m=o[a+ -36>>2];n=o[a+ -40>>2];p=o[a+ -44>>2];t=o[a+ -48>>2];s=o[c>>2];w=o[c+4>>2];v=o[c+8>>2];y=o[c+12>>2];x=o[c+16>>2];A=o[c+20>>2];z=o[c+24>>2];C=o[c+28>>2];B=o[c+32>>2];E=o[c+36>>2];D=o[c+40>>2];G=o[c+44>>2];c=0;while(1){q=p;p=n;n=m;m=l;l=k;k=j;j=i;i=h;h=d;d=g;g=r;F=c<<2;r=o[F+a>>2];o[f+F>>2]=r-(((((((((((u(q,D)+u(t,G)|0)+u(p,E)|0)+u(n,B)|0)+u(m,C)|0)+u(l,z)|0)+u(k,A)|0)+u(j,x)|0)+u(i,y)|0)+u(h,v)|0)+u(d,w)|0)+u(g,s)>>e);t=q;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=10){if((b|0)<1){break a}n=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];k=o[a+ -28>>2];l=o[a+ -32>>2];p=o[a+ -36>>2];r=o[c>>2];q=o[c+4>>2];t=o[c+8>>2];s=o[c+12>>2];w=o[c+16>>2];v=o[c+20>>2];y=o[c+24>>2];x=o[c+28>>2];A=o[c+32>>2];c=0;while(1){m=l;l=k;k=j;j=i;i=h;h=d;d=g;g=n;z=c<<2;n=o[z+a>>2];o[f+z>>2]=n-((((((((u(m,x)+u(p,A)|0)+u(l,y)|0)+u(k,v)|0)+u(j,w)|0)+u(i,s)|0)+u(h,t)|0)+u(d,q)|0)+u(g,r)>>e);p=m;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}p=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];k=o[a+ -28>>2];l=o[a+ -32>>2];m=o[a+ -36>>2];q=o[a+ -40>>2];r=o[c>>2];t=o[c+4>>2];s=o[c+8>>2];w=o[c+12>>2];v=o[c+16>>2];y=o[c+20>>2];x=o[c+24>>2];A=o[c+28>>2];z=o[c+32>>2];C=o[c+36>>2];c=0;while(1){n=m;m=l;l=k;k=j;j=i;i=h;h=d;d=g;g=p;B=c<<2;p=o[B+a>>2];o[f+B>>2]=p-(((((((((u(n,z)+u(q,C)|0)+u(m,A)|0)+u(l,x)|0)+u(k,y)|0)+u(j,v)|0)+u(i,w)|0)+u(h,s)|0)+u(d,t)|0)+u(g,r)>>e);q=n;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=5){if(d>>>0>=7){if((d|0)!=8){if((b|0)<1){break a}l=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];m=o[a+ -28>>2];n=o[c>>2];p=o[c+4>>2];r=o[c+8>>2];q=o[c+12>>2];t=o[c+16>>2];s=o[c+20>>2];w=o[c+24>>2];c=0;while(1){k=j;j=i;i=h;h=d;d=g;g=l;v=c<<2;l=o[v+a>>2];o[f+v>>2]=l-((((((u(k,s)+u(m,w)|0)+u(j,t)|0)+u(i,q)|0)+u(h,r)|0)+u(d,p)|0)+u(g,n)>>e);m=k;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}m=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];j=o[a+ -24>>2];k=o[a+ -28>>2];n=o[a+ -32>>2];p=o[c>>2];r=o[c+4>>2];q=o[c+8>>2];t=o[c+12>>2];s=o[c+16>>2];w=o[c+20>>2];v=o[c+24>>2];y=o[c+28>>2];c=0;while(1){l=k;k=j;j=i;i=h;h=d;d=g;g=m;x=c<<2;m=o[x+a>>2];o[f+x>>2]=m-(((((((u(l,v)+u(n,y)|0)+u(k,w)|0)+u(j,s)|0)+u(i,t)|0)+u(h,q)|0)+u(d,r)|0)+u(g,p)>>e);n=l;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=6){if((b|0)<1){break a}j=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];k=o[a+ -20>>2];l=o[c>>2];m=o[c+4>>2];n=o[c+8>>2];p=o[c+12>>2];r=o[c+16>>2];c=0;while(1){i=h;h=d;d=g;g=j;q=c<<2;j=o[q+a>>2];o[f+q>>2]=j-((((u(i,p)+u(k,r)|0)+u(h,n)|0)+u(d,m)|0)+u(g,l)>>e);k=i;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}k=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];h=o[a+ -16>>2];i=o[a+ -20>>2];l=o[a+ -24>>2];m=o[c>>2];n=o[c+4>>2];p=o[c+8>>2];r=o[c+12>>2];q=o[c+16>>2];t=o[c+20>>2];c=0;while(1){j=i;i=h;h=d;d=g;g=k;s=c<<2;k=o[s+a>>2];o[f+s>>2]=k-(((((u(j,q)+u(l,t)|0)+u(i,r)|0)+u(h,p)|0)+u(d,n)|0)+u(g,m)>>e);l=j;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if(d>>>0>=3){if((d|0)!=4){if((b|0)<1){break a}h=o[a+ -4>>2];g=o[a+ -8>>2];i=o[a+ -12>>2];j=o[c>>2];k=o[c+4>>2];l=o[c+8>>2];c=0;while(1){d=g;g=h;m=c<<2;h=o[m+a>>2];o[f+m>>2]=h-((u(d,k)+u(i,l)|0)+u(g,j)>>e);i=d;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}i=o[a+ -4>>2];g=o[a+ -8>>2];d=o[a+ -12>>2];j=o[a+ -16>>2];k=o[c>>2];l=o[c+4>>2];m=o[c+8>>2];n=o[c+12>>2];c=0;while(1){h=d;d=g;g=i;p=c<<2;i=o[p+a>>2];o[f+p>>2]=i-(((u(h,m)+u(j,n)|0)+u(d,l)|0)+u(g,k)>>e);j=h;c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((d|0)!=2){if((b|0)<1){break a}g=o[a+ -4>>2];d=o[c>>2];c=0;while(1){h=u(d,g);i=c<<2;g=o[i+a>>2];o[f+i>>2]=g-(h>>e);c=c+1|0;if((c|0)!=(b|0)){continue}break}break a}if((b|0)<1){break a}d=o[a+ -4>>2];h=o[a+ -8>>2];i=o[c>>2];j=o[c+4>>2];c=0;while(1){g=d;k=c<<2;d=o[k+a>>2];o[f+k>>2]=d-(u(g,i)+u(h,j)>>e);h=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function $(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,O=0,P=0,R=0,S=0,T=0,U=0,V=0,W=0,X=0,Y=0;n=N-96|0;N=n;w=c;k=g;v=(k&131071)<<15|f>>>17;j=i&65535;r=j;p=h;k=h;B=k<<15|g>>>17;q=(e^i)&-2147483648;k=e&65535;m=k;u=d;E=k;k=j;C=(k&131071)<<15|h>>>17;F=i>>>16&32767;O=e>>>16&32767;a:{b:{if(O+ -1>>>0<=32765){j=0;if(F+ -1>>>0<32766){break b}}l=e&2147483647;j=l;k=d;if(!(!d&(j|0)==2147418112?!(b|c):(j|0)==2147418112&d>>>0<0|j>>>0<2147418112)){y=d;q=e|32768;break a}l=i&2147483647;e=l;d=h;if(!(!d&(e|0)==2147418112?!(f|g):(e|0)==2147418112&d>>>0<0|e>>>0<2147418112)){y=h;q=i|32768;b=f;c=g;break a}if(!(b|k|(j^2147418112|c))){if(!(d|f|(e|g))){q=2147450880;b=0;c=0;break a}q=q|2147418112;b=0;c=0;break a}if(!(d|f|(e^2147418112|g))){d=b|k;e=c|j;b=0;c=0;if(!(d|e)){q=2147450880;break a}q=q|2147418112;break a}if(!(b|k|(c|j))){b=0;c=0;break a}if(!(d|f|(e|g))){b=0;c=0;break a}if((j|0)==65535|j>>>0<65535){i=b;j=c;d=!(m|u);h=d<<6;k=x(d?b:u)+32|0;b=x(d?c:m);b=h+((b|0)==32?k:b)|0;ia(n+80|0,i,j,u,m,b+ -15|0);u=o[n+88>>2];w=o[n+84>>2];E=o[n+92>>2];s=16-b|0;b=o[n+80>>2]}j=s;if(e>>>0>65535){break b}c=!(p|r);d=c<<6;e=x(c?f:p)+32|0;c=x(c?g:r);c=d+((c|0)==32?e:c)|0;h=c;ia(n- -64|0,f,g,p,r,c+ -15|0);f=o[n+76>>2];c=f;i=o[n+68>>2];g=i;e=o[n+72>>2];d=e;B=d<<15|g>>>17;d=g;f=o[n+64>>2];v=(d&131071)<<15|f>>>17;C=(c&131071)<<15|e>>>17;j=(s-h|0)+16|0}s=j;d=v;r=0;i=Ee(d,0,b,r);c=Q;D=c;z=f<<15&-32768;p=w;f=Ee(z,0,p,0);e=f+i|0;l=Q+c|0;l=e>>>0<f>>>0?l+1|0:l;c=e;f=0;g=Ee(b,r,z,G);e=f+g|0;j=Q+c|0;j=e>>>0<g>>>0?j+1|0:j;v=e;g=j;Y=(c|0)==(j|0)&e>>>0<f>>>0|j>>>0<c>>>0;R=Ee(d,A,p,P);J=Q;w=u;f=Ee(z,G,u,0);e=f+R|0;m=Q+J|0;m=e>>>0<f>>>0?m+1|0:m;S=e;h=Ee(B,0,b,r);e=e+h|0;f=Q+m|0;K=e;f=e>>>0<h>>>0?f+1|0:f;u=f;h=f;f=(l|0)==(D|0)&c>>>0<i>>>0|l>>>0<D>>>0;e=l;c=e+K|0;j=f+h|0;D=c;j=c>>>0<e>>>0?j+1|0:j;e=j;h=c;U=Ee(d,A,w,T);L=Q;c=z;H=E|65536;z=t;f=Ee(c,G,H,t);c=f+U|0;j=Q+L|0;j=c>>>0<f>>>0?j+1|0:j;V=c;k=Ee(p,P,B,W);c=c+k|0;t=j;f=j+Q|0;f=c>>>0<k>>>0?f+1|0:f;M=c;I=C&2147483647|-2147483648;c=Ee(b,r,I,0);b=M+c|0;r=f;k=f+Q|0;G=b;c=b>>>0<c>>>0?k+1|0:k;j=e+b|0;f=0;b=f+h|0;if(b>>>0<f>>>0){j=j+1|0}E=b;C=j;f=j;h=b+Y|0;if(h>>>0<b>>>0){f=f+1|0}i=f;s=(s+(F+O|0)|0)+ -16383|0;f=Ee(w,T,B,W);b=Q;l=0;k=Ee(d,A,H,z);d=k+f|0;j=Q+b|0;j=d>>>0<k>>>0?j+1|0:j;A=d;k=d;d=j;j=(b|0)==(d|0)&k>>>0<f>>>0|d>>>0<b>>>0;f=Ee(I,X,p,P);b=f+k|0;k=Q+d|0;k=b>>>0<f>>>0?k+1|0:k;p=b;f=b;b=k;d=(d|0)==(b|0)&f>>>0<A>>>0|b>>>0<d>>>0;f=j+d|0;if(f>>>0<d>>>0){l=1}k=f;d=b;f=l;F=k;j=0;k=(m|0)==(u|0)&K>>>0<S>>>0|u>>>0<m>>>0;m=k+((m|0)==(J|0)&S>>>0<R>>>0|m>>>0<J>>>0)|0;if(m>>>0<k>>>0){j=1}l=m;m=m+p|0;k=d+j|0;A=m;j=m;k=j>>>0<l>>>0?k+1|0:k;d=k;b=(b|0)==(d|0)&j>>>0<p>>>0|d>>>0<b>>>0;k=F+b|0;if(k>>>0<b>>>0){f=f+1|0}b=k;k=Ee(I,X,H,z);b=b+k|0;j=Q+f|0;j=b>>>0<k>>>0?j+1|0:j;l=b;m=Ee(I,X,w,T);f=Q;p=Ee(B,W,H,z);b=p+m|0;k=Q+f|0;k=b>>>0<p>>>0?k+1|0:k;p=b;b=k;k=(f|0)==(b|0)&p>>>0<m>>>0|b>>>0<f>>>0;f=b+l|0;l=j+k|0;k=f>>>0<b>>>0?l+1|0:l;w=f;j=d+p|0;l=0;b=l+A|0;if(b>>>0<l>>>0){j=j+1|0}m=b;f=b;b=j;d=(d|0)==(b|0)&f>>>0<A>>>0|b>>>0<d>>>0;f=w+d|0;if(f>>>0<d>>>0){k=k+1|0}p=f;l=b;j=0;f=(t|0)==(r|0)&M>>>0<V>>>0|r>>>0<t>>>0;t=f+((t|0)==(L|0)&V>>>0<U>>>0|t>>>0<L>>>0)|0;if(t>>>0<f>>>0){j=1}f=t+((c|0)==(r|0)&G>>>0<M>>>0|c>>>0<r>>>0)|0;d=c;c=d+m|0;l=f+l|0;l=c>>>0<d>>>0?l+1|0:l;t=c;d=c;c=l;b=(b|0)==(c|0)&d>>>0<m>>>0|c>>>0<b>>>0;d=b+p|0;if(d>>>0<b>>>0){k=k+1|0}b=c;j=k;k=d;f=0;d=(e|0)==(C|0)&E>>>0<D>>>0|C>>>0<e>>>0;e=d+((e|0)==(u|0)&D>>>0<K>>>0|e>>>0<u>>>0)|0;if(e>>>0<d>>>0){f=1}d=e+t|0;l=b+f|0;l=d>>>0<e>>>0?l+1|0:l;b=d;e=l;b=(c|0)==(e|0)&b>>>0<t>>>0|e>>>0<c>>>0;c=k+b|0;if(c>>>0<b>>>0){j=j+1|0}b=c;c=j;c:{if(c&65536){s=s+1|0;break c}m=g>>>31|0;j=c<<1|b>>>31;b=b<<1|e>>>31;c=j;j=e<<1|d>>>31;d=d<<1|i>>>31;e=j;k=v;j=g<<1|k>>>31;v=k<<1;g=j;k=i<<1|h>>>31;h=h<<1|m;i=k}if((s|0)>=32767){q=q|2147418112;b=0;c=0;break a}d:{if((s|0)<=0){f=1-s|0;if(f>>>0<=127){k=s+127|0;ia(n+48|0,v,g,h,i,k);ia(n+32|0,d,e,b,c,k);Ja(n+16|0,v,g,h,i,f);Ja(n,d,e,b,c,f);v=(o[n+48>>2]|o[n+56>>2])!=0|(o[n+52>>2]|o[n+60>>2])!=0|(o[n+32>>2]|o[n+16>>2]);g=o[n+36>>2]|o[n+20>>2];h=o[n+40>>2]|o[n+24>>2];i=o[n+44>>2]|o[n+28>>2];d=o[n>>2];e=o[n+4>>2];c=o[n+12>>2];b=o[n+8>>2];break d}b=0;c=0;break a}c=c&65535|s<<16}y=b|y;q=c|q;if(!(!h&(i|0)==-2147483648?!(g|v):(i|0)>-1?1:0)){l=q;m=e;b=d+1|0;if(b>>>0<1){m=m+1|0}c=m;d=(e|0)==(c|0)&b>>>0<d>>>0|c>>>0<e>>>0;e=d+y|0;if(e>>>0<d>>>0){l=l+1|0}y=e;q=l;break a}if(h|v|(i^-2147483648|g)){b=d;c=e;break a}m=q;j=e;b=d&1;c=b+d|0;if(c>>>0<b>>>0){j=j+1|0}b=c;c=j;d=(e|0)==(c|0)&b>>>0<d>>>0|c>>>0<e>>>0;e=d+y|0;if(e>>>0<d>>>0){m=m+1|0}y=e;q=m}o[a>>2]=b;o[a+4>>2]=c;o[a+8>>2]=y;o[a+12>>2]=q;N=n+96|0}function Oa(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,s=0;i=N-48|0;N=i;a:{b:{g=o[a>>2];if(!o[g+12>>2]){break b}d=o[a+4>>2];d=$b(d+7060|0,d+4|0,o[g+24>>2],o[g+36>>2],o[g+28>>2]+7>>>3|0);g=o[a>>2];if(d){break b}o[g>>2]=8;b=0;break a}d=o[g+576>>2];if(b){l=0}else{b=ke(o[g+36>>2]);g=o[a>>2];e=o[g+580>>2];l=b>>>0<e>>>0?b:e}j=o[g+36>>2];o[i+8>>2]=j;o[i+12>>2]=o[g+32>>2];b=o[g+24>>2];o[i+20>>2]=0;o[i+16>>2]=b;b=o[g+28>>2];o[i+28>>2]=0;o[i+24>>2]=b;h=o[a+4>>2];o[i+32>>2]=o[h+7056>>2];n=d>>>0<l>>>0?d:l;c:{d:{e:{f:{g:{h:{i:{if(!o[g+16>>2]){k=1;break i}if(!o[g+20>>2]|!o[h+6864>>2]){break i}k=1;e=1;if(o[h+6868>>2]){break h}}j:{if(!o[g+24>>2]){d=0;break j}while(1){p=(f<<2)+h|0;d=0;e=0;k:{if(!j){break k}s=o[p+4>>2];b=0;while(1){l:{d=o[(b<<2)+s>>2]|d;m=d&1;b=b+1|0;if(b>>>0>=j>>>0){break l}if(!m){continue}}break}b=0;e=0;if(!d){break k}e=0;if(m){break k}while(1){b=b+1|0;e=d&2;d=d>>1;if(!e){continue}break}m=0;e=0;if(!b){break k}while(1){d=(m<<2)+s|0;o[d>>2]=o[d>>2]>>b;m=m+1|0;if((m|0)!=(j|0)){continue}break}e=b}j=u(f,584)+h|0;b=o[g+28>>2];d=e>>>0>b>>>0?b:e;o[j+624>>2]=d;o[j+916>>2]=d;o[p+216>>2]=b-d;f=f+1|0;d=o[g+24>>2];if(f>>>0>=d>>>0){break j}j=o[g+36>>2];continue}}b=1;if(k){break g}j=o[g+36>>2];e=0}m=o[h+36>>2];d=0;f=0;m:{if(!j){break m}b=0;while(1){n:{b=o[(f<<2)+m>>2]|b;k=b&1;f=f+1|0;if(f>>>0>=j>>>0){break n}if(!k){continue}}break}f=0;if(k|!b){break m}while(1){f=f+1|0;k=b&2;b=b>>1;if(!k){continue}break}b=0;if(!f){f=0;break m}while(1){k=(b<<2)+m|0;o[k>>2]=o[k>>2]>>f;b=b+1|0;if((j|0)!=(b|0)){continue}break}}b=o[g+28>>2];f=f>>>0>b>>>0?b:f;o[h+5296>>2]=f;o[h+5588>>2]=f;o[h+248>>2]=b-f;f=o[g+36>>2];o:{if(!f){break o}j=o[h+40>>2];b=0;while(1){p:{d=o[j+(b<<2)>>2]|d;k=d&1;b=b+1|0;if(b>>>0>=f>>>0){break p}if(!k){continue}}break}b=0;if(!d){d=0;break o}if(k){d=0;break o}while(1){b=b+1|0;k=d&2;d=d>>1;if(!k){continue}break}d=0;if(!b){break o}while(1){k=j+(d<<2)|0;o[k>>2]=o[k>>2]>>b;d=d+1|0;if((f|0)!=(d|0)){continue}break}d=b}b=o[g+28>>2];d=d>>>0>b>>>0?b:d;o[h+5880>>2]=d;o[h+6172>>2]=d;o[h+252>>2]=(b-d|0)+1;if(e){break f}d=o[g+24>>2];b=0}if(d){d=0;while(1){e=(d<<2)+h|0;g=(d<<3)+h|0;Ua(a,n,l,i+8|0,o[e+216>>2],o[e+4>>2],g+6176|0,g+6640|0,g+256|0,e+6768|0,e+6808|0);h=o[a+4>>2];d=d+1|0;if(d>>>0<r[o[a>>2]+24>>2]){continue}break}}if(b){break e}m=o[h+36>>2]}Ua(a,n,l,i+8|0,o[h+248>>2],m,h+6240|0,h+6704|0,h+320|0,h+6800|0,h+6840|0);b=o[a+4>>2];Ua(a,n,l,i+8|0,o[b+252>>2],o[b+40>>2],b+6248|0,b+6712|0,b+328|0,b+6804|0,b+6844|0);d=i;e=o[a+4>>2];q:{if(!(!o[o[a>>2]+20>>2]|!o[e+6864>>2])){b=o[e+6868>>2]?3:0;break q}b=o[e+6844>>2];l=o[e+6808>>2];g=b+l|0;f=l;l=o[e+6812>>2];h=f+l|0;f=g>>>0<h>>>0;l=b+l|0;g=f?g:h;h=l>>>0<g>>>0;b=b+o[e+6840>>2]>>>0<(h?l:g)>>>0?3:h?2:f}o[d+20>>2]=b;if(!Tb(i+8|0,o[e+6856>>2])){o[o[a>>2]>>2]=7;b=0;break a}r:{s:{switch(b|0){default:d=o[a+4>>2];j=0;b=0;f=0;e=0;break r;case 0:d=o[a+4>>2];e=d+336|0;b=e+u(o[d+6768>>2],292)|0;j=(e+u(o[d+6772>>2],292)|0)+584|0;f=o[d+216>>2];e=o[d+220>>2];break r;case 1:d=o[a+4>>2];b=(d+u(o[d+6768>>2],292)|0)+336|0;j=(u(o[d+6804>>2],292)+d|0)+5592|0;f=o[d+216>>2];e=o[d+252>>2];break r;case 2:d=o[a+4>>2];j=(d+u(o[d+6772>>2],292)|0)+920|0;b=(u(o[d+6804>>2],292)+d|0)+5592|0;f=o[d+252>>2];e=o[d+220>>2];break r;case 3:break s}}d=o[a+4>>2];e=d+5008|0;b=e+u(o[d+6800>>2],292)|0;j=(e+u(o[d+6804>>2],292)|0)+584|0;f=o[d+248>>2];e=o[d+252>>2]}if(!Wa(a,o[i+8>>2],f,b,o[d+6856>>2])){break d}if(!Wa(a,o[i+8>>2],e,j,o[o[a+4>>2]+6856>>2])){break d}b=o[a>>2];break c}d=Tb(i+8|0,o[h+6856>>2]);b=o[a>>2];if(d){if(!o[b+24>>2]){break c}d=0;while(1){b=o[a+4>>2];e=b+(d<<2)|0;if(!Wa(a,o[i+8>>2],o[e+216>>2],((b+u(d,584)|0)+u(o[e+6768>>2],292)|0)+336|0,o[b+6856>>2])){break d}d=d+1|0;b=o[a>>2];if(d>>>0<r[b+24>>2]){continue}break}break c}o[b>>2]=7}b=0;break a}if(o[b+20>>2]){b=o[a+4>>2];d=o[b+6864>>2]+1|0;o[b+6864>>2]=d>>>0<r[b+6860>>2]?d:0}d=o[a+4>>2];o[d+6868>>2]=o[i+20>>2];d=o[d+6856>>2];e=o[d+16>>2]&7;b=1;t:{if(!e){break t}b=Ca(d,8-e|0)}if(!b){o[o[a>>2]>>2]=8;b=0;break a}u:{if(ue(o[o[a+4>>2]+6856>>2],i+8|0)){if(_(o[o[a+4>>2]+6856>>2],q[i+8>>1],o[1404])){break u}}o[o[a>>2]>>2]=8;b=0;break a}b=0;if(!Fa(a,o[o[a>>2]+36>>2],c)){break a}b=o[a+4>>2];o[b+7052>>2]=0;o[b+7056>>2]=o[b+7056>>2]+1;c=b+6920|0;d=c;e=d;b=o[d+4>>2];a=o[o[a>>2]+36>>2];c=a+o[d>>2]|0;if(c>>>0<a>>>0){b=b+1|0}o[e>>2]=c;o[d+4>>2]=b;b=1}N=i+48|0;return b}function Bc(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,q=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;f=N-432|0;N=f;g=o[b+4>>2];a:{if(g>>>0<r[b+104>>2]){o[b+4>>2]=g+1;h=p[g|0];break a}h=ga(b)}b:{c:{while(1){d:{if((h|0)!=48){if((h|0)!=46){break b}g=o[b+4>>2];if(g>>>0>=r[b+104>>2]){break d}o[b+4>>2]=g+1;h=p[g|0];break c}g=o[b+4>>2];if(g>>>0<r[b+104>>2]){y=1;o[b+4>>2]=g+1;h=p[g|0]}else{y=1;h=ga(b)}continue}break}h=ga(b)}x=1;if((h|0)!=48){break b}while(1){g=o[b+4>>2];e:{if(g>>>0<r[b+104>>2]){o[b+4>>2]=g+1;h=p[g|0];break e}h=ga(b)}n=n+ -1|0;g=u+ -1|0;if((g|0)!=-1){n=n+1|0}u=g;if((h|0)==48){continue}break}y=1}g=1073676288;while(1){f:{z=h|32;g:{h:{A=h+ -48|0;if(A>>>0<10){break h}if(z+ -97>>>0>5?(h|0)!=46:0){break f}if((h|0)!=46){break h}if(x){break f}x=1;u=l;n=i;break g}h=(h|0)>57?z+ -87|0:A;i:{if((i|0)<0?1:(i|0)<=0?l>>>0>7?0:1:0){q=h+(q<<4)|0;break i}if((i|0)<0?1:(i|0)<=0?l>>>0>28?0:1:0){ka(f+48|0,h);$(f+32|0,v,w,m,g,0,0,0,1073414144);v=o[f+32>>2];w=o[f+36>>2];m=o[f+40>>2];g=o[f+44>>2];$(f+16|0,v,w,m,g,o[f+48>>2],o[f+52>>2],o[f+56>>2],o[f+60>>2]);ja(f,j,k,s,t,o[f+16>>2],o[f+20>>2],o[f+24>>2],o[f+28>>2]);s=o[f+8>>2];t=o[f+12>>2];j=o[f>>2];k=o[f+4>>2];break i}if(!h|D){break i}$(f+80|0,v,w,m,g,0,0,0,1073610752);ja(f- -64|0,j,k,s,t,o[f+80>>2],o[f+84>>2],o[f+88>>2],o[f+92>>2]);s=o[f+72>>2];t=o[f+76>>2];D=1;j=o[f+64>>2];k=o[f+68>>2]}l=l+1|0;if(l>>>0<1){i=i+1|0}y=1}h=o[b+4>>2];if(h>>>0<r[b+104>>2]){o[b+4>>2]=h+1;h=p[h|0]}else{h=ga(b)}continue}break}j:{k:{if(!y){if(!o[b+104>>2]){break k}c=o[b+4>>2];o[b+4>>2]=c+ -1;o[b+4>>2]=c+ -2;if(!x){break k}o[b+4>>2]=c+ -3;break k}if((i|0)<0?1:(i|0)<=0?l>>>0>7?0:1:0){m=l;g=i;while(1){q=q<<4;m=m+1|0;if(m>>>0<1){g=g+1|0}if((m|0)!=8|g){continue}break}}l:{if((h&-33)==80){m=lb(b);h=Q;g=h;if(m|(g|0)!=-2147483648){break l}m=0;g=0;if(!o[b+104>>2]){break l}o[b+4>>2]=o[b+4>>2]+ -1;break l}m=0;g=0;if(!o[b+104>>2]){break l}o[b+4>>2]=o[b+4>>2]+ -1}if(!q){sa(f+112|0,+(e|0)*0);j=o[f+112>>2];k=o[f+116>>2];c=o[f+120>>2];b=o[f+124>>2];break j}b=x?n:i;i=x?u:l;n=b<<2|i>>>30;b=m+(i<<2)|0;i=g+n|0;i=b>>>0<m>>>0?i+1|0:i;b=b+ -32|0;g=i+ -1|0;l=b;i=b>>>0<4294967264?g+1|0:g;if((i|0)>0?1:(i|0)>=0?b>>>0<=0-d>>>0?0:1:0){o[2896]=68;ka(f+160|0,e);$(f+144|0,o[f+160>>2],o[f+164>>2],o[f+168>>2],o[f+172>>2],-1,-1,-1,2147418111);$(f+128|0,o[f+144>>2],o[f+148>>2],o[f+152>>2],o[f+156>>2],-1,-1,-1,2147418111);j=o[f+128>>2];k=o[f+132>>2];c=o[f+136>>2];b=o[f+140>>2];break j}b=d+ -226|0;h=l>>>0<b>>>0?0:1;b=b>>31;if((i|0)>(b|0)?1:(i|0)>=(b|0)?h:0){if((q|0)>-1){while(1){ja(f+416|0,j,k,s,t,0,0,0,-1073807360);h=Jb(j,k,s,t,1073610752);g=(h|0)<0;b=g;ja(f+400|0,j,k,s,t,b?j:o[f+416>>2],b?k:o[f+420>>2],b?s:o[f+424>>2],b?t:o[f+428>>2]);i=i+ -1|0;b=l+ -1|0;if((b|0)!=-1){i=i+1|0}l=b;s=o[f+408>>2];t=o[f+412>>2];j=o[f+400>>2];k=o[f+404>>2];q=q<<1|(h|0)>-1;if((q|0)>-1){continue}break}}g=l;b=d;h=(g-b|0)+32|0;i=i-((b>>31)+(g>>>0<b>>>0)|0)|0;b=h;i=b>>>0<32?i+1|0:i;c=((i|0)<0?1:(i|0)<=0?b>>>0>=c>>>0?0:1:0)?(b|0)>0?b:0:c;m:{if((c|0)>=113){ka(f+384|0,e);u=o[f+392>>2];n=o[f+396>>2];v=o[f+384>>2];w=o[f+388>>2];d=0;b=0;break m}sa(f+352|0,ua(1,144-c|0));ka(f+336|0,e);v=o[f+336>>2];w=o[f+340>>2];u=o[f+344>>2];n=o[f+348>>2];Fb(f+368|0,o[f+352>>2],o[f+356>>2],o[f+360>>2],o[f+364>>2],v,w,u,n);B=o[f+376>>2];C=o[f+380>>2];d=o[f+372>>2];b=o[f+368>>2]}c=!(q&1)&((za(j,k,s,t,0,0,0,0)|0)!=0&(c|0)<32);Ba(f+320|0,c+q|0);$(f+304|0,v,w,u,n,o[f+320>>2],o[f+324>>2],o[f+328>>2],o[f+332>>2]);ja(f+272|0,o[f+304>>2],o[f+308>>2],o[f+312>>2],o[f+316>>2],b,d,B,C);$(f+288|0,c?0:j,c?0:k,c?0:s,c?0:t,v,w,u,n);ja(f+256|0,o[f+288>>2],o[f+292>>2],o[f+296>>2],o[f+300>>2],o[f+272>>2],o[f+276>>2],o[f+280>>2],o[f+284>>2]);Xa(f+240|0,o[f+256>>2],o[f+260>>2],o[f+264>>2],o[f+268>>2],b,d,B,C);e=o[f+240>>2];d=o[f+244>>2];c=o[f+248>>2];b=o[f+252>>2];if(!za(e,d,c,b,0,0,0,0)){o[2896]=68}mb(f+224|0,e,d,c,b,l);j=o[f+224>>2];k=o[f+228>>2];c=o[f+232>>2];b=o[f+236>>2];break j}o[2896]=68;ka(f+208|0,e);$(f+192|0,o[f+208>>2],o[f+212>>2],o[f+216>>2],o[f+220>>2],0,0,0,65536);$(f+176|0,o[f+192>>2],o[f+196>>2],o[f+200>>2],o[f+204>>2],0,0,0,65536);j=o[f+176>>2];k=o[f+180>>2];c=o[f+184>>2];b=o[f+188>>2];break j}sa(f+96|0,+(e|0)*0);j=o[f+96>>2];k=o[f+100>>2];c=o[f+104>>2];b=o[f+108>>2]}o[a>>2]=j;o[a+4>>2]=k;o[a+8>>2]=c;o[a+12>>2]=b;N=f+432|0}function Ua(a,b,c,d,e,f,g,h,i,j,k){var m=0,n=0,p=0,q=0,w=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,O=0,P=0,Q=0,R=v(0),S=0,T=0,U=0,V=0,W=0,X=0,Y=0,Z=v(0),_=0,$=0,aa=0,ba=0,da=0,ea=0;q=N-576|0;N=q;G=o[(r[o[a>>2]+28>>2]>16?5644:5640)>>2];n=o[d>>2];a:{b:{if(o[o[a+4>>2]+7256>>2]){m=-1;if(n>>>0>3){break b}}y=o[g>>2];o[y+4>>2]=f;o[y>>2]=1;m=o[y+288>>2]+(o[1416]+(o[1415]+(o[1414]+u(e,n)|0)|0)|0)|0;n=o[d>>2];if(n>>>0<4){break a}}p=o[a+4>>2];y=n+ -4|0;c:{if(((x(y|1)^31)+e|0)+4>>>0<=32){p=l[o[p+7224>>2]](f+16|0,y,q+416|0)|0;break c}p=l[o[p+7228>>2]](f+16|0,y,q+416|0)|0}d:{e:{f:{g:{w=o[a+4>>2];if(o[w+7248>>2]|s[q+420>>2]!=v(0)){break g}n=1;z=o[f>>2];y=o[d>>2];if(y>>>0<=1){break f}while(1){if((z|0)!=o[(n<<2)+f>>2]){break g}n=n+1|0;if(n>>>0<y>>>0){continue}break}break f}n=o[a>>2];if(!o[w+7252>>2]){y=m;break e}y=-1;if((m|0)!=-1){y=m;break d}if(!o[n+556>>2]){break e}y=m;break d}a=o[g+4>>2];o[a+4>>2]=z;o[a>>2]=0;a=o[a+288>>2]+(o[1416]+(o[1415]+(o[1414]+e|0)|0)|0)|0;A=a>>>0<m>>>0;m=A?a:m;break a}m=o[n+568>>2];B=m?0:p;p=m?4:p;m=o[d>>2];K=p>>>0<m>>>0?p:m+ -1|0;if(B>>>0>K>>>0){break d}O=G+ -1|0;P=o[1416];L=o[1415];Q=o[1414];Z=v(e>>>0);while(1){n=B<<2;R=s[n+(q+416|0)>>2];if(!(R>=Z)){M=!A;z=M<<2;S=o[z+h>>2];D=o[g+z>>2];T=o[o[a>>2]+572>>2];m=o[a+4>>2];p=o[m+6852>>2];w=o[m+6848>>2];m=f+n|0;n=o[d>>2]-B|0;z=o[i+z>>2];ne(m,n,B,z);o[D+36>>2]=z;o[D+12>>2]=S;o[D>>2]=2;o[D+4>>2]=0;U=R>v(0);H=o[a+4>>2];E=B;I=+R+.5;h:{if(I<4294967296&I>=0){m=~~I>>>0;break h}m=0}m=U?m+1|0:1;w=Ab(H,z,w,p,n,E,m>>>0<G>>>0?m:O,G,b,c,e,T,D+4|0);o[D+16>>2]=B;if(B){p=D+20|0;m=0;while(1){n=m<<2;o[n+p>>2]=o[f+n>>2];m=m+1|0;if((B|0)!=(m|0)){continue}break}}m=o[D+288>>2]+(P+(L+(Q+(w+u(e,B)|0)|0)|0)|0)|0;n=m>>>0<y>>>0;A=n?M:A;y=n?m:y}B=B+1|0;if(B>>>0<=K>>>0){continue}break}n=o[a>>2]}p=o[n+556>>2];if(!p){m=y;break a}m=o[d>>2];p=p>>>0<m>>>0?p:m+ -1|0;o[q+12>>2]=p;if(!p){m=y;break a}if(!o[n+40>>2]){m=y;break a}X=33-e|0;_=G+ -1|0;$=o[1413];aa=o[1412];ba=o[1416];D=o[1415];da=o[1414];I=+(e>>>0);K=e>>>0<18;O=e>>>0>16;P=e>>>0>17;while(1){n=o[a+4>>2];Yd(f,o[(n+(V<<2)|0)+84>>2],o[n+212>>2],m);m=o[a+4>>2];l[o[m+7232>>2]](o[m+212>>2],o[d>>2],o[q+12>>2]+1|0,q+272|0);i:{if(s[q+272>>2]==v(0)){break i}ce(q+272|0,q+12|0,o[a+4>>2]+7628|0,q+16|0);w=1;n=o[q+12>>2];z=o[a>>2];if(!o[z+568>>2]){m=q;n=ee(m+16|0,n,o[d>>2],(o[z+564>>2]?5:o[z+560>>2])+e|0);o[m+12>>2]=n;w=n}m=o[d>>2];if(n>>>0>=m>>>0){n=m+ -1|0;o[q+12>>2]=n}if(w>>>0>n>>>0){break i}while(1){j:{L=w+ -1|0;F=de(t[(q+16|0)+(L<<3)>>3],m-w|0);if(F>=I){break j}m=F>0;F=F+.5;k:{if(F<4294967296&F>=0){p=~~F>>>0;break k}p=0}p=m?p+1|0:1;m=p>>>0<G>>>0;n=o[a>>2];l:{if(o[n+564>>2]){E=5;H=15;if(P){break l}z=(x(w)^-32)+X|0;if(z>>>0>14){break l}H=z>>>0>5?z:5;break l}H=o[n+560>>2];E=H}Q=m?p:_;W=(w<<2)+f|0;m=x(w);M=m^31;Y=(m^-32)+X|0;while(1){B=o[d>>2];p=!A;m=p<<2;T=o[m+h>>2];C=o[g+m>>2];J=o[i+m>>2];U=o[n+572>>2];n=o[a+4>>2];S=o[n+6852>>2];z=o[n+6848>>2];m=0;ea=A;A=(n+(L<<7)|0)+7628|0;n=K?Y>>>0>E>>>0?E:Y:E;if(!$d(A,w,n,q+448|0,q+444|0)){A=B-w|0;B=e+n|0;m:{if(B+M>>>0<=32){m=o[a+4>>2];if(!(n>>>0>16|O)){l[o[m+7244>>2]](W,A,q+448|0,w,o[q+444>>2],J);break m}l[o[m+7236>>2]](W,A,q+448|0,w,o[q+444>>2],J);break m}l[o[o[a+4>>2]+7240>>2]](W,A,q+448|0,w,o[q+444>>2],J)}o[C>>2]=3;o[C+4>>2]=0;o[C+284>>2]=J;o[C+12>>2]=T;A=Ab(o[a+4>>2],J,z,S,A,w,Q,G,b,c,e,U,C+4|0);o[C+20>>2]=n;o[C+16>>2]=w;o[C+24>>2]=o[q+444>>2];ca(C+28|0,q+448|0,128);m=0;if(w){while(1){z=m<<2;o[(z+C|0)+156>>2]=o[f+z>>2];m=m+1|0;if((w|0)!=(m|0)){continue}break}}m=((o[C+288>>2]+((((A+u(w,B)|0)+da|0)+D|0)+ba|0)|0)+aa|0)+$|0}n=(m|0)!=0&m>>>0<y>>>0;A=n?p:ea;y=n?m:y;E=E+1|0;if(E>>>0>H>>>0){break j}n=o[a>>2];continue}}w=w+1|0;if(w>>>0>r[q+12>>2]){break i}m=o[d>>2];continue}}V=V+1|0;if(V>>>0<r[o[a>>2]+40>>2]){m=o[d>>2];continue}break}m=y}if((m|0)==-1){a=o[d>>2];b=o[(A<<2)+g>>2];o[b+4>>2]=f;o[b>>2]=1;m=o[b+288>>2]+(o[1416]+(o[1415]+(o[1414]+u(a,e)|0)|0)|0)|0}o[j>>2]=A;o[k>>2]=m;N=q+576|0}function Ra(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=0;l=o[b+16>>2];i=o[b+32>>2];m=o[b+48>>2];n=o[b+36>>2];p=o[b+52>>2];q=o[b+4>>2];g=o[b+20>>2];h=o[a+4>>2];j=o[b>>2];B=o[a>>2];r=o[a+12>>2];k=o[a+8>>2];c=h+He(((j+B|0)+(r^(r^k)&h)|0)+ -680876936|0,7)|0;s=o[b+12>>2];t=o[b+8>>2];e=He(((q+r|0)+(c&(h^k)^k)|0)+ -389564586|0,12)+c|0;d=He(((t+k|0)+(e&(c^h)^h)|0)+606105819|0,17)+e|0;f=He(((h+s|0)+(c^d&(c^e))|0)+ -1044525330|0,22)+d|0;c=He(((c+l|0)+(e^f&(d^e))|0)+ -176418897|0,7)+f|0;u=o[b+28>>2];v=o[b+24>>2];e=He(((e+g|0)+(d^c&(d^f))|0)+1200080426|0,12)+c|0;d=He(((d+v|0)+(f^e&(c^f))|0)+ -1473231341|0,17)+e|0;f=He(((f+u|0)+(c^d&(c^e))|0)+ -45705983|0,22)+d|0;c=He(((c+i|0)+(e^f&(d^e))|0)+1770035416|0,7)+f|0;w=o[b+44>>2];x=o[b+40>>2];e=He(((e+n|0)+(d^c&(d^f))|0)+ -1958414417|0,12)+c|0;d=He(((x+d|0)+(f^e&(c^f))|0)+ -42063|0,17)+e|0;f=He(((f+w|0)+(c^d&(c^e))|0)+ -1990404162|0,22)+d|0;c=He(((c+m|0)+(e^f&(d^e))|0)+1804603682|0,7)+f|0;y=o[b+60>>2];A=c+q|0;z=o[b+56>>2];e=He(((e+p|0)+(d^c&(d^f))|0)+ -40341101|0,12)+c|0;b=He(((z+d|0)+(f^e&(c^f))|0)+ -1502002290|0,17)+e|0;c=He(((f+y|0)+(c^b&(c^e))|0)+1236535329|0,22)+b|0;d=He((A+((b^c)&e^b)|0)+ -165796510|0,5)+c|0;f=b+w|0;b=He(((e+v|0)+(c^b&(c^d))|0)+ -1069501632|0,9)+d|0;e=He((f+(d^c&(b^d))|0)+643717713|0,14)+b|0;c=He(((c+j|0)+(b^d&(b^e))|0)+ -373897302|0,20)+e|0;d=He(((d+g|0)+((e^c)&b^e)|0)+ -701558691|0,5)+c|0;b=He(((b+x|0)+(c^e&(c^d))|0)+38016083|0,9)+d|0;e=He(((e+y|0)+(d^c&(b^d))|0)+ -660478335|0,14)+b|0;c=He(((c+l|0)+(b^d&(b^e))|0)+ -405537848|0,20)+e|0;d=He(((d+n|0)+((e^c)&b^e)|0)+568446438|0,5)+c|0;f=e+s|0;e=He(((b+z|0)+(c^e&(c^d))|0)+ -1019803690|0,9)+d|0;f=He((f+(d^(e^d)&c)|0)+ -187363961|0,14)+e|0;c=He(((c+i|0)+(e^(e^f)&d)|0)+1163531501|0,20)+f|0;b=He(((d+p|0)+((f^c)&e^f)|0)+ -1444681467|0,5)+c|0;d=He(((e+t|0)+(c^f&(b^c))|0)+ -51403784|0,9)+b|0;e=He(((f+u|0)+(b^c&(d^b))|0)+1735328473|0,14)+d|0;A=d+i|0;f=d^e;c=He(((c+m|0)+(d^f&b)|0)+ -1926607734|0,20)+e|0;d=He(((b+g|0)+(c^f)|0)+ -378558|0,4)+c|0;b=He((A+(c^e^d)|0)+ -2022574463|0,11)+d|0;e=He(((e+w|0)+(b^(c^d))|0)+1839030562|0,16)+b|0;c=He(((c+z|0)+(e^(b^d))|0)+ -35309556|0,23)+e|0;d=He(((d+q|0)+(c^(b^e))|0)+ -1530992060|0,4)+c|0;b=He(((b+l|0)+(d^(c^e))|0)+1272893353|0,11)+d|0;e=He(((e+u|0)+(b^(c^d))|0)+ -155497632|0,16)+b|0;c=He(((c+x|0)+(e^(b^d))|0)+ -1094730640|0,23)+e|0;d=He(((d+p|0)+(c^(b^e))|0)+681279174|0,4)+c|0;b=He(((b+j|0)+(d^(c^e))|0)+ -358537222|0,11)+d|0;e=He(((e+s|0)+(b^(c^d))|0)+ -722521979|0,16)+b|0;c=He(((c+v|0)+(e^(b^d))|0)+76029189|0,23)+e|0;d=He(((d+n|0)+(c^(b^e))|0)+ -640364487|0,4)+c|0;b=He(((b+m|0)+(d^(c^e))|0)+ -421815835|0,11)+d|0;f=d+j|0;j=b^d;d=He(((e+y|0)+(b^(c^d))|0)+530742520|0,16)+b|0;e=He(((c+t|0)+(j^d)|0)+ -995338651|0,23)+d|0;c=He((f+((e|b^-1)^d)|0)+ -198630844|0,6)+e|0;f=e+g|0;g=d+z|0;d=He(((b+u|0)+(e^(c|d^-1))|0)+1126891415|0,10)+c|0;e=He((g+(c^(d|e^-1))|0)+ -1416354905|0,15)+d|0;b=He((f+((e|c^-1)^d)|0)+ -57434055|0,21)+e|0;f=e+x|0;g=d+s|0;d=He(((c+m|0)+(e^(b|d^-1))|0)+1700485571|0,6)+b|0;e=He((g+(b^(d|e^-1))|0)+ -1894986606|0,10)+d|0;c=He((f+((e|b^-1)^d)|0)+ -1051523|0,15)+e|0;f=e+y|0;i=d+i|0;d=He(((b+q|0)+(e^(c|d^-1))|0)+ -2054922799|0,21)+c|0;e=He((i+(c^(d|e^-1))|0)+1873313359|0,6)+d|0;b=He((f+((e|c^-1)^d)|0)+ -30611744|0,10)+e|0;c=He(((c+v|0)+(e^(b|d^-1))|0)+ -1560198380|0,15)+b|0;d=He(((d+p|0)+(b^(c|e^-1))|0)+1309151649|0,21)+c|0;e=He(((e+l|0)+((d|b^-1)^c)|0)+ -145523070|0,6)+d|0;o[a>>2]=e+B;b=He(((b+w|0)+(d^(e|c^-1))|0)+ -1120210379|0,10)+e|0;o[a+12>>2]=b+r;c=He(((c+t|0)+(e^(b|d^-1))|0)+718787259|0,15)+b|0;o[a+8>>2]=c+k;C=a,D=He(((d+n|0)+(b^(c|e^-1))|0)+ -343485551|0,21)+(c+h|0)|0,o[C+4>>2]=D}function Ab(a,b,c,d,e,f,g,h,i,j,k,m,n){var p=0,q=0,s=0,t=0,v=0,w=0,y=0,z=0,A=0,B=0,C=0,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=0,O=0,P=0,Q=0,R=0,S=0,T=0;G=e+f|0;p=je(j,G,f);D=p>>>0>i>>>0?i:p;l[o[a+7220>>2]](b,c,e,f,D,p,k);a:{if(!m){break a}k=0;i=0;if((p|0)>=0){i=1<<p;B=i>>>0>1?i:1;E=G>>>p|0;while(1){A=0;j=s;y=0;t=(z<<2)+d|0;b:{c:{q=z?0:f;w=E-q|0;if(!w){break c}while(1){v=o[(j<<2)+b>>2];A=v>>31^v|A;j=j+1|0;y=y+1|0;if((w|0)!=(y|0)){continue}break}s=(s+E|0)-q|0;if(!A){break c}j=(x(A)^31)+2|0;break b}j=1}o[t>>2]=j;z=z+1|0;if((B|0)!=(z|0)){continue}break}}if((p|0)<=(D|0)){break a}b=p;while(1){b=b+ -1|0;j=0;while(1){s=(k<<2)+d|0;v=o[s>>2];s=o[s+4>>2];o[(i<<2)+d>>2]=v>>>0>s>>>0?v:s;i=i+1|0;k=k+2|0;j=j+1|0;if(!(j>>>b)){continue}break}if((b|0)>(D|0)){continue}break}}d:{if((p|0)<(D|0)){z=0;o[n+4>>2]=0;A=0;b=6;break d}H=o[1407];S=H+(u(g+1|0,e)-(e>>>1|0)|0)|0;N=h+ -1|0;O=o[1409]+o[1408]|0;E=o[1406]+o[1405]|0;T=g+ -1|0;z=0;A=0;while(1){e:{C=p;P=!A;i=u(P,12)+a|0;b=i+11724|0;ab(b,p>>>0>6?p:6);Q=(I<<2)+d|0;F=(I<<3)+c|0;R=o[i+11728>>2];J=o[b>>2];f:{if(p){K=G>>>C|0;if(K>>>0<=f>>>0){break e}y=0;L=0;j=E;if(!m){while(1){v=K-(y?0:f)|0;b=F+(y<<3)|0;q=o[b+4>>2];t=o[b>>2];g:{if(!q&t>>>0>=268435457|q>>>0>0){b=v;k=0;i=0;h:{if((q|0)==16777216&t>>>0>0|q>>>0>16777216){s=b;p=0;break h}s=b;p=0;w=b>>>25|0;B=b<<7;if((q|0)==(w|0)&B>>>0>=t>>>0|w>>>0>q>>>0){break h}while(1){i=i+8|0;p=k;w=p<<15|b>>>17;B=b<<15;k=p<<8|b>>>24;s=b<<8;b=s;p=k;if((q|0)==(w|0)&B>>>0<t>>>0|w>>>0<q>>>0){continue}break}}if((p|0)==(q|0)&s>>>0>=t>>>0|p>>>0>q>>>0){break g}while(1){i=i+1|0;b=s;w=p<<1|b>>>31;s=b<<1;b=s;p=w;if((q|0)==(p|0)&b>>>0<t>>>0|p>>>0<q>>>0){continue}break}break g}i=0;k=v;b=t;if(k<<3>>>0<b>>>0){while(1){i=i+4|0;p=k<<7;k=k<<4;if(p>>>0<b>>>0){continue}break}}if(k>>>0>=b>>>0){break g}while(1){i=i+1|0;k=k<<1;if(k>>>0<b>>>0){continue}break}}k=i>>>0<h>>>0?i:N;b=k+ -1|0;p=b&31;b=((H-(v>>>1|0)|0)+u(v,k+1|0)|0)+(k?32<=(b&63)>>>0?q>>>p|0:((1<<p)-1&q)<<32-p|t>>>p:t<<1)|0;L=(b|0)==-1?L:k;o[J+(y<<2)>>2]=L;j=b+j|0;y=y+1|0;if(!(y>>>C)){continue}break f}}while(1){v=K-(y?0:f)|0;b=F+(y<<3)|0;q=o[b+4>>2];t=o[b>>2];i:{j:{if(!q&t>>>0>=268435457|q>>>0>0){b=v;k=0;i=0;if((q|0)==16777216&t>>>0>0|q>>>0>16777216){break j}s=b;p=0;w=b>>>25|0;B=b<<7;if((q|0)==(w|0)&B>>>0>=t>>>0|w>>>0>q>>>0){break j}while(1){i=i+8|0;b=p;k=s;w=b<<15|k>>>17;B=k<<15;s=b<<8;b=k;k=s|b>>>24;b=b<<8;s=b;p=k;if((q|0)==(w|0)&B>>>0<t>>>0|w>>>0<q>>>0){continue}break}break j}i=0;k=v;b=t;if(k<<3>>>0<b>>>0){while(1){i=i+4|0;p=k<<7;k=k<<4;if(p>>>0<b>>>0){continue}break}}if(k>>>0>=b>>>0){break i}while(1){i=i+1|0;k=k<<1;if(k>>>0<b>>>0){continue}break}break i}if((k|0)==(q|0)&b>>>0>=t>>>0|k>>>0>q>>>0){break i}while(1){i=i+1|0;w=k<<1|b>>>31;b=b<<1;k=w;if((q|0)==(k|0)&b>>>0<t>>>0|k>>>0<q>>>0){continue}break}}p=y<<2;b=o[p+Q>>2];w=b;k=u(b,v)+O|0;s=i>>>0<h>>>0?i:N;i=(H-(v>>>1|0)|0)+u(v,s+1|0)|0;b=s+ -1|0;v=b&31;b=i+(s?32<=(b&63)>>>0?q>>>v|0:((1<<v)-1&q)<<32-v|t>>>v:t<<1)|0;i=k>>>0>b>>>0;o[p+R>>2]=i?0:w;o[p+J>>2]=i?s:0;j=(i?b:k)+j|0;y=y+1|0;if(!(y>>>C)){continue}break}break f}k=o[F+4>>2];b=T;p=b&31;j=o[F>>2];i=(g?32<=(b&63)>>>0?k>>>p|0:((1<<p)-1&k)<<32-p|j>>>p:j<<1)+S|0;k=(i|0)==-1?0:g;if(m){j=o[Q>>2];b=u(j,e)+O|0;p=b>>>0>i>>>0;o[R>>2]=p?0:j;k=p?k:0;i=p?i:b}o[J>>2]=k;j=i+E|0}b=M+ -1>>>0<j>>>0;z=b?z:C;A=b?A:P;M=b?M:j;p=C+ -1|0;I=(1<<C)+I|0;if((C|0)>(D|0)){continue}}break}o[n+4>>2]=z;b=z>>>0>6?z:6}d=o[n+8>>2];ab(d,b);b=u(A,12)+a|0;c=1<<z;a=c<<2;ca(o[d>>2],o[b+11724>>2],a);if(m){ca(o[d+4>>2],o[b+11728>>2],a)}c=c>>>0>1?c:1;b=o[1410];a=o[d>>2];i=0;k:{while(1){if(r[a+(i<<2)>>2]<b>>>0){i=i+1|0;if((c|0)!=(i|0)){continue}break k}break}o[n>>2]=1}return M}function _a(a,b){var c=0,d=0,e=0,f=0,g=v(0),h=v(0),i=0,j=v(0),k=0,l=0;d=o[a>>2];a:{if(o[d>>2]!=1){break a}o[d+40>>2]=0;while(1){b:{c:{d:{e:{f:{g:{h:{i:{j:{k:{l:{m:{n:{o:{k=Ha(b,59);p:{if(k){e=k-b|0;break p}e=Ga(b)}l=(e|0)!=8;if(!l){if(ha(10584,b,8)){break o}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=0;break b}q:{switch(e+ -6|0){case 1:break l;case 0:break m;case 20:break n;case 7:break q;default:break k}}f=1;if(ha(10593,b,13)){break j}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=1;break b}f=0;if(ha(10607,b,8)){break j}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=2;break b}f=0;if(ha(10616,b,26)){break j}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=3;break b}if(ha(10643,b,6)){break b}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=4;break b}if(ha(10650,b,7)){break i}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=5;break b}f=0;if(e>>>0<8){break h}}if(ha(10658,b,6)){break g}h=v(oa(b+6|0));if(h>v(0)^1|h<=v(.5)^1){break b}b=o[a>>2];s[((o[b+40>>2]<<4)+b|0)+48>>2]=h;b=o[a>>2];e=o[b+40>>2];o[b+40>>2]=e+1;o[(b+(e<<4)|0)+44>>2]=6;break b}if(ha(10665,b,7)){break f}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=7;break b}r:{switch(e+ -4|0){case 0:break r;case 1:break d;default:break b}}if(ha(10673,b,4)){break b}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=8;break b}if(!f){break e}if(ha(10678,b,13)){break e}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=9;break b}if(ha(10692,b,7)){break b}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=10;break b}s:{if((e|0)!=9){break s}if(ha(10700,b,9)){break s}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=11;break b}if(!l){if(!ha(10710,b,8)){o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=12;break b}if(ha(10719,b,6)){break b}break c}if(!ha(10719,b,6)){break c}if(e>>>0<16){break b}if(!ha(10726,b,14)){i=oa(b+14|0);t:{if(w(i)<2147483648){e=~~i;break t}e=-2147483648}c=Ha(b,47);g=v(.10000000149011612);u:{if(!c){break u}d=c+1|0;g=v(.9900000095367432);if(!(v(oa(d))<v(.9900000095367432))){break u}g=v(oa(d))}b=Ha(c?c+1|0:b,47);h=v(.20000000298023224);v:{if(!b){break v}h=v(oa(b+1|0))}b=o[a>>2];f=o[b+40>>2];if((e|0)<=1){s[((f<<4)+b|0)+48>>2]=h;b=o[a>>2];e=o[b+40>>2];o[b+40>>2]=e+1;o[(b+(e<<4)|0)+44>>2]=13;break b}if(e+f>>>0>31){break b}j=v(v(v(1)/v(v(1)-g))+v(-1));g=v(j+v(e|0));c=0;while(1){s[((f<<4)+b|0)+48>>2]=h;b=o[a>>2];s[((o[b+40>>2]<<4)+b|0)+52>>2]=v(c|0)/g;b=o[a>>2];c=c+1|0;s[((o[b+40>>2]<<4)+b|0)+56>>2]=v(j+v(c|0))/g;b=o[a>>2];d=o[b+40>>2];f=d+1|0;o[b+40>>2]=f;o[((d<<4)+b|0)+44>>2]=14;if((c|0)!=(e|0)){continue}break}break b}if(e>>>0<17){break b}if(ha(10741,b,15)){break b}i=oa(b+15|0);w:{if(w(i)<2147483648){e=~~i;break w}e=-2147483648}h=v(.20000000298023224);c=Ha(b,47);g=v(.20000000298023224);x:{if(!c){break x}d=c+1|0;g=v(.9900000095367432);if(!(v(oa(d))<v(.9900000095367432))){break x}g=v(oa(d))}b=Ha(c?c+1|0:b,47);if(b){h=v(oa(b+1|0))}b=o[a>>2];f=o[b+40>>2];if((e|0)<=1){s[((f<<4)+b|0)+48>>2]=h;b=o[a>>2];e=o[b+40>>2];o[b+40>>2]=e+1;o[(b+(e<<4)|0)+44>>2]=13;break b}if(e+f>>>0>31){break b}j=v(v(v(1)/v(v(1)-g))+v(-1));g=v(j+v(e|0));c=0;while(1){s[((f<<4)+b|0)+48>>2]=h;b=o[a>>2];s[((o[b+40>>2]<<4)+b|0)+52>>2]=v(c|0)/g;b=o[a>>2];c=c+1|0;s[((o[b+40>>2]<<4)+b|0)+56>>2]=v(j+v(c|0))/g;b=o[a>>2];d=o[b+40>>2];f=d+1|0;o[b+40>>2]=f;o[((d<<4)+b|0)+44>>2]=15;if((c|0)!=(e|0)){continue}break}break b}if(ha(10757,b,5)){break b}o[d+40>>2]=c+1;o[((c<<4)+d|0)+44>>2]=16;break b}h=v(oa(b+6|0));if(h>=v(0)^1|h<=v(1)^1){break b}b=o[a>>2];s[((o[b+40>>2]<<4)+b|0)+48>>2]=h;b=o[a>>2];e=o[b+40>>2];o[b+40>>2]=e+1;o[(b+(e<<4)|0)+44>>2]=13}d=o[a>>2];c=o[d+40>>2];if(k){b=k+1|0;if((c|0)!=32){continue}}break}f=1;if(c){break a}o[d+40>>2]=1;o[d+44>>2]=13;o[d+48>>2]=1056964608}return f}function zd(){var a=0,b=0,c=0,d=0;b=qa(1,8);if(!b){return 0}a=qa(1,1032);o[b>>2]=a;a:{if(!a){break a}d=qa(1,11856);o[b+4>>2]=d;if(!d){X(a);break a}a=qa(1,20);d=o[b+4>>2];o[d+6856>>2]=a;if(!a){X(d);X(o[b>>2]);break a}o[d+7296>>2]=0;a=o[b>>2];o[a+44>>2]=13;o[a+48>>2]=1056964608;o[a+36>>2]=0;o[a+40>>2]=1;o[a+28>>2]=16;o[a+32>>2]=44100;o[a+20>>2]=0;o[a+24>>2]=2;o[a+12>>2]=1;o[a+16>>2]=0;o[a+4>>2]=0;o[a+8>>2]=1;a=o[b>>2];o[a+592>>2]=0;o[a+596>>2]=0;o[a+556>>2]=0;o[a+560>>2]=0;o[a+564>>2]=0;o[a+568>>2]=0;o[a+572>>2]=0;o[a+576>>2]=0;o[a+580>>2]=0;o[a+584>>2]=0;o[a+600>>2]=0;o[a+604>>2]=0;d=o[b+4>>2];c=d;o[c+7248>>2]=0;o[c+7252>>2]=0;o[c+7048>>2]=0;c=c+7256|0;o[c>>2]=0;o[c+4>>2]=0;c=d+7264|0;o[c>>2]=0;o[c+4>>2]=0;c=d+7272|0;o[c>>2]=0;o[c+4>>2]=0;c=d+7280|0;o[c>>2]=0;o[c+4>>2]=0;o[d+7288>>2]=0;o[a+632>>2]=0;o[a+636>>2]=0;a=o[b>>2];b:{if(o[a>>2]!=1){break b}o[a+16>>2]=1;o[a+20>>2]=0;_a(b,10777);a=o[b>>2];if(o[a>>2]!=1){break b}o[a+576>>2]=0;o[a+580>>2]=5;o[a+564>>2]=0;o[a+568>>2]=0;o[a+556>>2]=8;o[a+560>>2]=0}a=o[b+4>>2];o[a+11848>>2]=0;o[a+6176>>2]=a+336;a=o[b+4>>2];o[a+6180>>2]=a+628;a=o[b+4>>2];o[a+6184>>2]=a+920;a=o[b+4>>2];o[a+6188>>2]=a+1212;a=o[b+4>>2];o[a+6192>>2]=a+1504;a=o[b+4>>2];o[a+6196>>2]=a+1796;a=o[b+4>>2];o[a+6200>>2]=a+2088;a=o[b+4>>2];o[a+6204>>2]=a+2380;a=o[b+4>>2];o[a+6208>>2]=a+2672;a=o[b+4>>2];o[a+6212>>2]=a+2964;a=o[b+4>>2];o[a+6216>>2]=a+3256;a=o[b+4>>2];o[a+6220>>2]=a+3548;a=o[b+4>>2];o[a+6224>>2]=a+3840;a=o[b+4>>2];o[a+6228>>2]=a+4132;a=o[b+4>>2];o[a+6232>>2]=a+4424;a=o[b+4>>2];o[a+6236>>2]=a+4716;a=o[b+4>>2];o[a+6240>>2]=a+5008;a=o[b+4>>2];o[a+6244>>2]=a+5300;a=o[b+4>>2];o[a+6248>>2]=a+5592;a=o[b+4>>2];o[a+6252>>2]=a+5884;a=o[b+4>>2];o[a+6640>>2]=a+6256;a=o[b+4>>2];o[a+6644>>2]=a+6268;a=o[b+4>>2];o[a+6648>>2]=a+6280;a=o[b+4>>2];o[a+6652>>2]=a+6292;a=o[b+4>>2];o[a+6656>>2]=a+6304;a=o[b+4>>2];o[a+6660>>2]=a+6316;a=o[b+4>>2];o[a+6664>>2]=a+6328;a=o[b+4>>2];o[a+6668>>2]=a+6340;a=o[b+4>>2];o[a+6672>>2]=a+6352;a=o[b+4>>2];o[a+6676>>2]=a+6364;a=o[b+4>>2];o[a+6680>>2]=a+6376;a=o[b+4>>2];o[a+6684>>2]=a+6388;a=o[b+4>>2];o[a+6688>>2]=a+6400;a=o[b+4>>2];o[a+6692>>2]=a+6412;a=o[b+4>>2];o[a+6696>>2]=a+6424;a=o[b+4>>2];o[a+6700>>2]=a+6436;a=o[b+4>>2];o[a+6704>>2]=a+6448;a=o[b+4>>2];o[a+6708>>2]=a+6460;a=o[b+4>>2];o[a+6712>>2]=a+6472;a=o[b+4>>2];o[a+6716>>2]=a+6484;a=o[b+4>>2]+6256|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6268|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6280|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6292|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6304|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6316|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6328|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6340|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6352|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6364|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6376|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6388|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6400|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6412|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6424|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6436|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6448|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6460|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6472|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+6484|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+11724|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;a=o[b+4>>2]+11736|0;o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0;o[o[b>>2]>>2]=1;return b|0}X(b);return 0}function ja(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0;l=N-112|0;N=l;n=h;m=i&2147483647;k=c+ -1|0;j=b+ -1|0;if((j|0)!=-1){k=k+1|0}p=j;s=(j|0)==-1&(k|0)==-1;q=e&2147483647;j=q;r=d;k=(c|0)==(k|0)&p>>>0<b>>>0|k>>>0<c>>>0;p=d+k|0;if(p>>>0<k>>>0){j=j+1|0}k=p+ -1|0;j=j+ -1|0;j=(k|0)!=-1?j+1|0:j;a:{b:{if(!((k|0)==-1&(j|0)==2147418111?s:j>>>0>2147418111)){k=g+ -1|0;j=f+ -1|0;if((j|0)!=-1){k=k+1|0}p=j;s=(j|0)!=-1|(k|0)!=-1;j=m;k=(g|0)==(k|0)&p>>>0<f>>>0|k>>>0<g>>>0;p=k+n|0;if(p>>>0<k>>>0){j=j+1|0}k=p+ -1|0;j=j+ -1|0;j=(k|0)!=-1?j+1|0:j;if((k|0)==-1&(j|0)==2147418111?s:(j|0)==2147418111&(k|0)!=-1|j>>>0<2147418111){break b}}if(!(!r&(q|0)==2147418112?!(b|c):(q|0)==2147418112&r>>>0<0|q>>>0<2147418112)){h=d;i=e|32768;f=b;g=c;break a}if(!(!n&(m|0)==2147418112?!(f|g):(m|0)==2147418112&n>>>0<0|m>>>0<2147418112)){i=i|32768;break a}if(!(b|r|(q^2147418112|c))){j=d;d=!(b^f|d^h|(c^g|e^i^-2147483648));h=d?0:j;i=d?2147450880:e;f=d?0:b;g=d?0:c;break a}if(!(f|n|(m^2147418112|g))){break a}if(!(b|r|(c|q))){if(f|n|(g|m)){break a}f=b&f;g=c&g;h=d&h;i=e&i;break a}if(f|n|(g|m)){break b}f=b;g=c;h=d;i=e;break a}j=(n|0)==(r|0)&(m|0)==(q|0)?(c|0)==(g|0)&f>>>0>b>>>0|g>>>0>c>>>0:(m|0)==(q|0)&n>>>0>r>>>0|m>>>0>q>>>0;q=j?f:b;k=j?g:c;n=j?i:e;r=n;p=j?h:d;n=n&65535;e=j?e:i;t=e;d=j?d:h;s=e>>>16&32767;m=r>>>16&32767;if(!m){e=!(n|p);h=e<<6;i=x(e?q:p)+32|0;e=x(e?k:n);e=h+((e|0)==32?i:e)|0;ia(l+96|0,q,k,p,n,e+ -15|0);p=o[l+104>>2];n=o[l+108>>2];q=o[l+96>>2];m=16-e|0;k=o[l+100>>2]}f=j?b:f;g=j?c:g;b=d;c=t&65535;if(s){b=c}else{h=b;d=!(b|c);e=d<<6;i=x(d?f:b)+32|0;b=x(d?g:c);b=e+((b|0)==32?i:b)|0;ia(l+80|0,f,g,h,c,b+ -15|0);s=16-b|0;f=o[l+80>>2];g=o[l+84>>2];d=o[l+88>>2];b=o[l+92>>2]}c=d;j=b<<3|c>>>29;h=c<<3|g>>>29;i=j|524288;b=p;d=n<<3|b>>>29;e=b<<3|k>>>29;p=d;n=r^t;b=f;j=g<<3|b>>>29;b=b<<3;c=j;f=m-s|0;d=b;c:{if(!f){break c}if(f>>>0>127){h=0;i=0;j=0;d=1;break c}ia(l- -64|0,b,c,h,i,128-f|0);Ja(l+48|0,b,c,h,i,f);h=o[l+56>>2];i=o[l+60>>2];j=o[l+52>>2];d=o[l+48>>2]|((o[l+64>>2]|o[l+72>>2])!=0|(o[l+68>>2]|o[l+76>>2])!=0)}g=j;p=p|524288;b=q;j=k<<3|b>>>29;c=b<<3;d:{if((n|0)<-1?1:(n|0)<=-1?1:0){n=d;b=c-d|0;q=e-h|0;d=(g|0)==(j|0)&c>>>0<d>>>0|j>>>0<g>>>0;f=q-d|0;c=j-((c>>>0<n>>>0)+g|0)|0;g=(p-((e>>>0<h>>>0)+i|0)|0)-(q>>>0<d>>>0)|0;if(!(b|f|(c|g))){f=0;g=0;h=0;i=0;break a}if(g>>>0>524287){break d}h=b;d=!(f|g);e=d<<6;i=x(d?b:f)+32|0;b=x(d?c:g);b=e+((b|0)==32?i:b)|0;b=b+ -12|0;ia(l+32|0,h,c,f,g,b);m=m-b|0;f=o[l+40>>2];g=o[l+44>>2];b=o[l+32>>2];c=o[l+36>>2];break d}j=g+j|0;b=d;c=b+c|0;if(c>>>0<b>>>0){j=j+1|0}b=c;c=j;g=(g|0)==(c|0)&b>>>0<d>>>0|c>>>0<g>>>0;k=i+p|0;d=e+h|0;if(d>>>0<e>>>0){k=k+1|0}f=d;e=g+d|0;d=k;d=e>>>0<f>>>0?d+1|0:d;f=e;g=d;if(!(d&1048576)){break d}b=b&1|((c&1)<<31|b>>>1);c=f<<31|c>>>1;m=m+1|0;f=(g&1)<<31|f>>>1;g=g>>>1|0}h=0;k=r&-2147483648;if((m|0)>=32767){i=k|2147418112;f=0;g=0;break a}e=0;e:{if((m|0)>0){e=m;break e}ia(l+16|0,b,c,f,g,m+127|0);Ja(l,b,c,f,g,1-m|0);b=o[l>>2]|((o[l+16>>2]|o[l+24>>2])!=0|(o[l+20>>2]|o[l+28>>2])!=0);c=o[l+4>>2];f=o[l+8>>2];g=o[l+12>>2]}m=(c&7)<<29|b>>>3;d=f<<29|c>>>3;j=d;n=b&7;b=n>>>0>4;c=b+m|0;if(c>>>0<b>>>0){j=j+1|0}i=c;b=c;c=j;b=(d|0)==(c|0)&b>>>0<m>>>0|c>>>0<d>>>0;d=h|((g&7)<<29|f>>>3);j=k|g>>>3&65535|e<<16;b=d+b|0;if(b>>>0<d>>>0){j=j+1|0}d=b;e=(n|0)==4;b=e?i&1:0;k=j;h=d;e=0;d=e+c|0;f=b+i|0;if(f>>>0<b>>>0){d=d+1|0}c=f;g=d;b=(e|0)==(d|0)&c>>>0<b>>>0|d>>>0<e>>>0;c=h+b|0;if(c>>>0<b>>>0){k=k+1|0}h=c;i=k}o[a>>2]=f;o[a+4>>2]=g;o[a+8>>2]=h;o[a+12>>2]=i;N=l+112|0}function Nc(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,v=0,x=0,y=0,z=0;h=N-560|0;N=h;f=c;c=(c+ -3|0)/24|0;r=(c|0)>0?c:0;k=f+u(r,-24)|0;m=o[1901];i=d+ -1|0;if((m+i|0)>=0){f=d+m|0;c=r-i|0;while(1){t[(h+320|0)+(g<<3)>>3]=(c|0)<0?0:+o[(c<<2)+7616>>2];c=c+1|0;g=g+1|0;if((f|0)!=(g|0)){continue}break}}n=k+ -24|0;f=0;g=(m|0)>0?m:0;l=(d|0)<1;while(1){a:{if(l){e=0;break a}j=f+i|0;c=0;e=0;while(1){e=e+t[(c<<3)+a>>3]*t[(h+320|0)+(j-c<<3)>>3];c=c+1|0;if((d|0)!=(c|0)){continue}break}}t[(f<<3)+h>>3]=e;c=(f|0)==(g|0);f=f+1|0;if(!c){continue}break}y=47-k|0;s=48-k|0;z=k+ -25|0;f=m;b:{while(1){e=t[(f<<3)+h>>3];c=0;g=f;j=(f|0)<1;if(!j){while(1){l=(h+480|0)+(c<<2)|0;p=e;e=e*5.960464477539063e-8;c:{if(w(e)<2147483648){i=~~e;break c}i=-2147483648}e=+(i|0);p=p+e*-16777216;d:{if(w(p)<2147483648){i=~~p;break d}i=-2147483648}o[l>>2]=i;g=g+ -1|0;e=t[(g<<3)+h>>3]+e;c=c+1|0;if((f|0)!=(c|0)){continue}break}}e=ua(e,n);e=e+A(e*.125)*-8;e:{if(w(e)<2147483648){l=~~e;break e}l=-2147483648}e=e- +(l|0);f:{g:{h:{v=(n|0)<1;i:{if(!v){g=(f<<2)+h|0;i=o[g+476>>2];c=i>>s;q=g;g=i-(c<<s)|0;o[q+476>>2]=g;l=c+l|0;i=g>>y;break i}if(n){break h}i=o[((f<<2)+h|0)+476>>2]>>23}if((i|0)<1){break f}break g}i=2;if(!!(e>=.5)){break g}i=0;break f}c=0;g=0;if(!j){while(1){q=(h+480|0)+(c<<2)|0;x=o[q>>2];j=16777215;j:{k:{if(g){break k}j=16777216;if(x){break k}g=0;break j}o[q>>2]=j-x;g=1}c=c+1|0;if((f|0)!=(c|0)){continue}break}}l:{if(v){break l}m:{switch(z|0){case 0:c=(f<<2)+h|0;o[c+476>>2]=o[c+476>>2]&8388607;break l;case 1:break m;default:break l}}c=(f<<2)+h|0;o[c+476>>2]=o[c+476>>2]&4194303}l=l+1|0;if((i|0)!=2){break f}e=1-e;i=2;if(!g){break f}e=e-ua(1,n)}if(e==0){g=0;n:{c=f;if((c|0)<=(m|0)){break n}while(1){c=c+ -1|0;g=o[(h+480|0)+(c<<2)>>2]|g;if((c|0)>(m|0)){continue}break}if(!g){break n}k=n;while(1){k=k+ -24|0;f=f+ -1|0;if(!o[(h+480|0)+(f<<2)>>2]){continue}break}break b}c=1;while(1){g=c;c=c+1|0;if(!o[(h+480|0)+(m-g<<2)>>2]){continue}break}g=f+g|0;while(1){i=d+f|0;f=f+1|0;t[(h+320|0)+(i<<3)>>3]=o[(r+f<<2)+7616>>2];c=0;e=0;if((d|0)>=1){while(1){e=e+t[(c<<3)+a>>3]*t[(h+320|0)+(i-c<<3)>>3];c=c+1|0;if((d|0)!=(c|0)){continue}break}}t[(f<<3)+h>>3]=e;if((f|0)<(g|0)){continue}break}f=g;continue}break}e=ua(e,0-n|0);o:{if(!!(e>=16777216)){d=(h+480|0)+(f<<2)|0;p=e;e=e*5.960464477539063e-8;p:{if(w(e)<2147483648){c=~~e;break p}c=-2147483648}e=p+ +(c|0)*-16777216;q:{if(w(e)<2147483648){a=~~e;break q}a=-2147483648}o[d>>2]=a;f=f+1|0;break o}if(w(e)<2147483648){c=~~e}else{c=-2147483648}k=n}o[(h+480|0)+(f<<2)>>2]=c}e=ua(1,k);r:{if((f|0)<=-1){break r}c=f;while(1){t[(c<<3)+h>>3]=e*+o[(h+480|0)+(c<<2)>>2];e=e*5.960464477539063e-8;a=(c|0)>0;c=c+ -1|0;if(a){continue}break}j=0;if((f|0)<0){break r}a=(m|0)>0?m:0;g=f;while(1){d=a>>>0<j>>>0?a:j;k=f-g|0;c=0;e=0;while(1){e=e+t[(c<<3)+10384>>3]*t[(c+g<<3)+h>>3];n=(c|0)!=(d|0);c=c+1|0;if(n){continue}break}t[(h+160|0)+(k<<3)>>3]=e;g=g+ -1|0;c=(f|0)!=(j|0);j=j+1|0;if(c){continue}break}}e=0;if((f|0)>=0){c=f;while(1){e=e+t[(h+160|0)+(c<<3)>>3];a=(c|0)>0;c=c+ -1|0;if(a){continue}break}}t[b>>3]=i?-e:e;e=t[h+160>>3]-e;c=1;if((f|0)>=1){while(1){e=e+t[(h+160|0)+(c<<3)>>3];a=(c|0)!=(f|0);c=c+1|0;if(a){continue}break}}t[b+8>>3]=i?-e:e;N=h+560|0;return l&7}function X(a){a=a|0;var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;a:{if(!a){break a}d=a+ -8|0;c=o[a+ -4>>2];a=c&-8;f=d+a|0;b:{if(c&1){break b}if(!(c&3)){break a}c=o[d>>2];d=d-c|0;if(d>>>0<r[2901]){break a}a=a+c|0;if(o[2902]!=(d|0)){if(c>>>0<=255){e=o[d+8>>2];c=c>>>3|0;b=o[d+12>>2];if((b|0)==(e|0)){i=11588,j=o[2897]&He(-2,c),o[i>>2]=j;break b}o[e+12>>2]=b;o[b+8>>2]=e;break b}h=o[d+24>>2];c=o[d+12>>2];c:{if((d|0)!=(c|0)){b=o[d+8>>2];o[b+12>>2]=c;o[c+8>>2]=b;break c}d:{e=d+20|0;b=o[e>>2];if(b){break d}e=d+16|0;b=o[e>>2];if(b){break d}c=0;break c}while(1){g=e;c=b;e=c+20|0;b=o[e>>2];if(b){continue}e=c+16|0;b=o[c+16>>2];if(b){continue}break}o[g>>2]=0}if(!h){break b}e=o[d+28>>2];b=(e<<2)+11892|0;e:{if(o[b>>2]==(d|0)){o[b>>2]=c;if(c){break e}i=11592,j=o[2898]&He(-2,e),o[i>>2]=j;break b}o[h+(o[h+16>>2]==(d|0)?16:20)>>2]=c;if(!c){break b}}o[c+24>>2]=h;b=o[d+16>>2];if(b){o[c+16>>2]=b;o[b+24>>2]=c}b=o[d+20>>2];if(!b){break b}o[c+20>>2]=b;o[b+24>>2]=c;break b}c=o[f+4>>2];if((c&3)!=3){break b}o[2899]=a;o[f+4>>2]=c&-2;o[d+4>>2]=a|1;o[a+d>>2]=a;return}if(f>>>0<=d>>>0){break a}c=o[f+4>>2];if(!(c&1)){break a}f:{if(!(c&2)){if(o[2903]==(f|0)){o[2903]=d;a=o[2900]+a|0;o[2900]=a;o[d+4>>2]=a|1;if(o[2902]!=(d|0)){break a}o[2899]=0;o[2902]=0;return}if(o[2902]==(f|0)){o[2902]=d;a=o[2899]+a|0;o[2899]=a;o[d+4>>2]=a|1;o[a+d>>2]=a;return}a=(c&-8)+a|0;g:{if(c>>>0<=255){b=o[f+8>>2];c=c>>>3|0;e=o[f+12>>2];if((b|0)==(e|0)){i=11588,j=o[2897]&He(-2,c),o[i>>2]=j;break g}o[b+12>>2]=e;o[e+8>>2]=b;break g}h=o[f+24>>2];c=o[f+12>>2];h:{if((f|0)!=(c|0)){b=o[f+8>>2];o[b+12>>2]=c;o[c+8>>2]=b;break h}i:{e=f+20|0;b=o[e>>2];if(b){break i}e=f+16|0;b=o[e>>2];if(b){break i}c=0;break h}while(1){g=e;c=b;e=c+20|0;b=o[e>>2];if(b){continue}e=c+16|0;b=o[c+16>>2];if(b){continue}break}o[g>>2]=0}if(!h){break g}e=o[f+28>>2];b=(e<<2)+11892|0;j:{if(o[b>>2]==(f|0)){o[b>>2]=c;if(c){break j}i=11592,j=o[2898]&He(-2,e),o[i>>2]=j;break g}o[h+(o[h+16>>2]==(f|0)?16:20)>>2]=c;if(!c){break g}}o[c+24>>2]=h;b=o[f+16>>2];if(b){o[c+16>>2]=b;o[b+24>>2]=c}b=o[f+20>>2];if(!b){break g}o[c+20>>2]=b;o[b+24>>2]=c}o[d+4>>2]=a|1;o[a+d>>2]=a;if(o[2902]!=(d|0)){break f}o[2899]=a;return}o[f+4>>2]=c&-2;o[d+4>>2]=a|1;o[a+d>>2]=a}if(a>>>0<=255){a=a>>>3|0;c=(a<<3)+11628|0;b=o[2897];a=1<<a;k:{if(!(b&a)){o[2897]=a|b;a=c;break k}a=o[c+8>>2]}o[c+8>>2]=d;o[a+12>>2]=d;o[d+12>>2]=c;o[d+8>>2]=a;return}o[d+16>>2]=0;o[d+20>>2]=0;f=d;e=a>>>8|0;b=0;l:{if(!e){break l}b=31;if(a>>>0>16777215){break l}c=e;e=e+1048320>>>16&8;b=c<<e;h=b+520192>>>16&4;b=b<<h;g=b+245760>>>16&2;b=(b<<g>>>15|0)-(g|(e|h))|0;b=(b<<1|a>>>b+21&1)+28|0}o[f+28>>2]=b;g=(b<<2)+11892|0;m:{n:{e=o[2898];c=1<<b;o:{if(!(e&c)){o[2898]=c|e;o[g>>2]=d;o[d+24>>2]=g;break o}e=a<<((b|0)==31?0:25-(b>>>1|0)|0);c=o[g>>2];while(1){b=c;if((o[c+4>>2]&-8)==(a|0)){break n}c=e>>>29|0;e=e<<1;g=b+(c&4)|0;c=o[g+16>>2];if(c){continue}break}o[g+16>>2]=d;o[d+24>>2]=b}o[d+12>>2]=d;o[d+8>>2]=d;break m}a=o[b+8>>2];o[a+12>>2]=d;o[b+8>>2]=d;o[d+24>>2]=0;o[d+12>>2]=b;o[d+8>>2]=a}a=o[2905]+ -1|0;o[2905]=a;if(a){break a}d=12044;while(1){a=o[d>>2];d=a+8|0;if(a){continue}break}o[2905]=-1}}function Db(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;f=a+b|0;a:{b:{c=o[a+4>>2];if(c&1){break b}if(!(c&3)){break a}c=o[a>>2];b=c+b|0;a=a-c|0;if((a|0)!=o[2902]){if(c>>>0<=255){e=c>>>3|0;c=o[a+8>>2];d=o[a+12>>2];if((d|0)==(c|0)){i=11588,j=o[2897]&He(-2,e),o[i>>2]=j;break b}o[c+12>>2]=d;o[d+8>>2]=c;break b}h=o[a+24>>2];c=o[a+12>>2];c:{if((c|0)!=(a|0)){d=o[a+8>>2];o[d+12>>2]=c;o[c+8>>2]=d;break c}d:{d=a+20|0;e=o[d>>2];if(e){break d}d=a+16|0;e=o[d>>2];if(e){break d}c=0;break c}while(1){g=d;c=e;d=c+20|0;e=o[d>>2];if(e){continue}d=c+16|0;e=o[c+16>>2];if(e){continue}break}o[g>>2]=0}if(!h){break b}d=o[a+28>>2];e=(d<<2)+11892|0;e:{if(o[e>>2]==(a|0)){o[e>>2]=c;if(c){break e}i=11592,j=o[2898]&He(-2,d),o[i>>2]=j;break b}o[h+(o[h+16>>2]==(a|0)?16:20)>>2]=c;if(!c){break b}}o[c+24>>2]=h;d=o[a+16>>2];if(d){o[c+16>>2]=d;o[d+24>>2]=c}d=o[a+20>>2];if(!d){break b}o[c+20>>2]=d;o[d+24>>2]=c;break b}c=o[f+4>>2];if((c&3)!=3){break b}o[2899]=b;o[f+4>>2]=c&-2;o[a+4>>2]=b|1;o[f>>2]=b;return}c=o[f+4>>2];f:{if(!(c&2)){if(o[2903]==(f|0)){o[2903]=a;b=o[2900]+b|0;o[2900]=b;o[a+4>>2]=b|1;if(o[2902]!=(a|0)){break a}o[2899]=0;o[2902]=0;return}if(o[2902]==(f|0)){o[2902]=a;b=o[2899]+b|0;o[2899]=b;o[a+4>>2]=b|1;o[a+b>>2]=b;return}b=(c&-8)+b|0;g:{if(c>>>0<=255){e=c>>>3|0;c=o[f+8>>2];d=o[f+12>>2];if((d|0)==(c|0)){i=11588,j=o[2897]&He(-2,e),o[i>>2]=j;break g}o[c+12>>2]=d;o[d+8>>2]=c;break g}h=o[f+24>>2];c=o[f+12>>2];h:{if((f|0)!=(c|0)){d=o[f+8>>2];o[d+12>>2]=c;o[c+8>>2]=d;break h}i:{d=f+20|0;e=o[d>>2];if(e){break i}d=f+16|0;e=o[d>>2];if(e){break i}c=0;break h}while(1){g=d;c=e;d=c+20|0;e=o[d>>2];if(e){continue}d=c+16|0;e=o[c+16>>2];if(e){continue}break}o[g>>2]=0}if(!h){break g}d=o[f+28>>2];e=(d<<2)+11892|0;j:{if(o[e>>2]==(f|0)){o[e>>2]=c;if(c){break j}i=11592,j=o[2898]&He(-2,d),o[i>>2]=j;break g}o[h+(o[h+16>>2]==(f|0)?16:20)>>2]=c;if(!c){break g}}o[c+24>>2]=h;d=o[f+16>>2];if(d){o[c+16>>2]=d;o[d+24>>2]=c}d=o[f+20>>2];if(!d){break g}o[c+20>>2]=d;o[d+24>>2]=c}o[a+4>>2]=b|1;o[a+b>>2]=b;if(o[2902]!=(a|0)){break f}o[2899]=b;return}o[f+4>>2]=c&-2;o[a+4>>2]=b|1;o[a+b>>2]=b}if(b>>>0<=255){c=b>>>3|0;b=(c<<3)+11628|0;d=o[2897];c=1<<c;k:{if(!(d&c)){o[2897]=c|d;c=b;break k}c=o[b+8>>2]}o[b+8>>2]=a;o[c+12>>2]=a;o[a+12>>2]=b;o[a+8>>2]=c;return}o[a+16>>2]=0;o[a+20>>2]=0;d=a;e=b>>>8|0;c=0;l:{if(!e){break l}c=31;if(b>>>0>16777215){break l}g=e+1048320>>>16&8;e=e<<g;c=e+520192>>>16&4;f=e<<c;e=f+245760>>>16&2;c=(f<<e>>>15|0)-(e|(c|g))|0;c=(c<<1|b>>>c+21&1)+28|0}o[d+28>>2]=c;e=(c<<2)+11892|0;m:{d=o[2898];g=1<<c;n:{if(!(d&g)){o[2898]=d|g;o[e>>2]=a;break n}d=b<<((c|0)==31?0:25-(c>>>1|0)|0);c=o[e>>2];while(1){e=c;if((o[c+4>>2]&-8)==(b|0)){break m}c=d>>>29|0;d=d<<1;g=e+(c&4)|0;c=o[g+16>>2];if(c){continue}break}o[g+16>>2]=a}o[a+24>>2]=e;o[a+12>>2]=a;o[a+8>>2]=a;return}b=o[e+8>>2];o[b+12>>2]=a;o[e+8>>2]=a;o[a+24>>2]=0;o[a+12>>2]=e;o[a+8>>2]=b}}function hb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,n=0,q=0,s=0,t=0,v=0;d=Ga(o[2720]);a:{if(!_(b,o[a+4>>2],o[1391])){break a}if(!_(b,o[a>>2],o[1392])){break a}c=o[a+8>>2];c=o[a>>2]==4?(c+d|0)-o[a+16>>2]|0:c;e=o[1393];if(c>>>e){break a}if(!_(b,c,e)){break a}b:{c:{d:{e:{f:{g:{h:{switch(o[a>>2]){case 3:if(!o[a+16>>2]){break b}e=o[1367];g=o[1366];h=o[1365];c=0;break g;case 0:if(!_(b,o[a+16>>2],o[1356])){break a}if(!_(b,o[a+20>>2],o[1357])){break a}if(!_(b,o[a+24>>2],o[1358])){break a}if(!_(b,o[a+28>>2],o[1359])){break a}if(!_(b,o[a+32>>2],o[1360])){break a}if(!_(b,o[a+36>>2]+ -1|0,o[1361])){break a}if(!_(b,o[a+40>>2]+ -1|0,o[1362])){break a}if(!Da(b,o[a+48>>2],o[a+52>>2],o[1363])){break a}if(ma(b,a+56|0,16)){break b}break a;case 1:if(Ca(b,o[a+8>>2]<<3)){break b}break a;case 6:break d;case 5:break e;case 4:break f;case 2:break h;default:break c}}c=o[1364]>>>3|0;if(!ma(b,a+16|0,c)){break a}if(ma(b,o[a+20>>2],o[a+8>>2]-c|0)){break b}break a}while(1){d=u(c,24);f=d+o[a+20>>2]|0;if(!Da(b,o[f>>2],o[f+4>>2],h)){break a}f=d+o[a+20>>2]|0;if(!Da(b,o[f+8>>2],o[f+12>>2],g)){break a}if(!_(b,o[(d+o[a+20>>2]|0)+16>>2],e)){break a}c=c+1|0;if(c>>>0<r[a+16>>2]){continue}break}break b}if(!bb(b,d)){break a}if(!ma(b,o[2720],d)){break a}if(!bb(b,o[a+24>>2])){break a}if(!o[a+24>>2]){break b}c=0;while(1){d=c<<3;if(!bb(b,o[d+o[a+28>>2]>>2])){break a}d=d+o[a+28>>2]|0;if(!ma(b,o[d+4>>2],o[d>>2])){break a}c=c+1|0;if(c>>>0<r[a+24>>2]){continue}break}break b}if(!ma(b,a+16|0,o[1378]>>>3|0)){break a}if(!Da(b,o[a+152>>2],o[a+156>>2],o[1379])){break a}if(!_(b,o[a+160>>2]!=0,o[1380])){break a}if(!Ca(b,o[1381])){break a}if(!_(b,o[a+164>>2],o[1382])){break a}if(!o[a+164>>2]){break b}g=o[1373]>>>3|0;h=o[1370];f=o[1369];j=o[1368];k=o[1377];l=o[1376];n=o[1375];q=o[1374];s=o[1372];t=o[1371];e=0;while(1){d=o[a+168>>2]+(e<<5)|0;if(!Da(b,o[d>>2],o[d+4>>2],t)){break a}if(!_(b,p[d+8|0],s)){break a}if(!ma(b,d+9|0,g)){break a}if(!_(b,m[d+22|0]&1,q)){break a}if(!_(b,p[d+22|0]>>>1&1,n)){break a}if(!Ca(b,l)){break a}if(!_(b,p[d+23|0],k)){break a}i:{if(!p[d+23|0]){break i}c=0;while(1){i=o[d+24>>2]+(c<<4)|0;if(!Da(b,o[i>>2],o[i+4>>2],j)){return 0}if(!_(b,p[i+8|0],f)){return 0}if(Ca(b,h)){c=c+1|0;if(c>>>0>=p[d+23|0]){break i}continue}break}return 0}e=e+1|0;if(e>>>0<r[a+164>>2]){continue}break}break b}if(!_(b,o[a+16>>2],o[1383])){break a}c=Ga(o[a+20>>2]);if(!_(b,c,o[1384])){break a}if(!ma(b,o[a+20>>2],c)){break a}c=Ga(o[a+24>>2]);if(!_(b,c,o[1385])){break a}if(!ma(b,o[a+24>>2],c)){break a}if(!_(b,o[a+28>>2],o[1386])){break a}if(!_(b,o[a+32>>2],o[1387])){break a}if(!_(b,o[a+36>>2],o[1388])){break a}if(!_(b,o[a+40>>2],o[1389])){break a}if(!_(b,o[a+44>>2],o[1390])){break a}if(ma(b,o[a+48>>2],o[a+44>>2])){break b}break a}if(!ma(b,o[a+16>>2],o[a+8>>2])){break a}}v=1}return v}function Rd(a,b,c,d,e,f,g,h,i){var j=0,k=0,n=0,q=0,r=0;j=N-96|0;N=j;a:{b:{if(o[a+384>>2]){o[j+72>>2]=0;o[j+76>>2]=0;o[j+80>>2]=0;o[j+84>>2]=0;o[j+88>>2]=0;o[j+92>>2]=0;o[j+64>>2]=0;o[j+68>>2]=0;k=o[a+396>>2];n=d;q=o[a+392>>2];r=d+q|0;if(r>>>0<q>>>0){k=k+1|0}o[j+80>>2]=r;o[j+84>>2]=k;c:{d:{if(o[a+388>>2]){if((c|0)!=38){break c}m[j|0]=p[7536];c=o[2721];c=p[c|0]|p[c+1|0]<<8|(p[c+2|0]<<16|p[c+3|0]<<24);m[j+5|0]=1;m[j+6|0]=0;m[j+1|0]=c;m[j+2|0]=c>>>8;m[j+3|0]=c>>>16;m[j+4|0]=c>>>24;k=o[a+4>>2];c=p[5409]|p[5410]<<8|(p[5411]<<16|p[5412]<<24);m[j+9|0]=c;m[j+10|0]=c>>>8;m[j+11|0]=c>>>16;m[j+12|0]=c>>>24;m[j+8|0]=k;m[j+7|0]=k>>>8;c=p[b+34|0]|p[b+35|0]<<8|(p[b+36|0]<<16|p[b+37|0]<<24);k=p[b+30|0]|p[b+31|0]<<8|(p[b+32|0]<<16|p[b+33|0]<<24);m[j+43|0]=k;m[j+44|0]=k>>>8;m[j+45|0]=k>>>16;m[j+46|0]=k>>>24;m[j+47|0]=c;m[j+48|0]=c>>>8;m[j+49|0]=c>>>16;m[j+50|0]=c>>>24;c=p[b+28|0]|p[b+29|0]<<8|(p[b+30|0]<<16|p[b+31|0]<<24);k=p[b+24|0]|p[b+25|0]<<8|(p[b+26|0]<<16|p[b+27|0]<<24);m[j+37|0]=k;m[j+38|0]=k>>>8;m[j+39|0]=k>>>16;m[j+40|0]=k>>>24;m[j+41|0]=c;m[j+42|0]=c>>>8;m[j+43|0]=c>>>16;m[j+44|0]=c>>>24;c=p[b+20|0]|p[b+21|0]<<8|(p[b+22|0]<<16|p[b+23|0]<<24);k=p[b+16|0]|p[b+17|0]<<8|(p[b+18|0]<<16|p[b+19|0]<<24);m[j+29|0]=k;m[j+30|0]=k>>>8;m[j+31|0]=k>>>16;m[j+32|0]=k>>>24;m[j+33|0]=c;m[j+34|0]=c>>>8;m[j+35|0]=c>>>16;m[j+36|0]=c>>>24;c=p[b+12|0]|p[b+13|0]<<8|(p[b+14|0]<<16|p[b+15|0]<<24);k=p[b+8|0]|p[b+9|0]<<8|(p[b+10|0]<<16|p[b+11|0]<<24);m[j+21|0]=k;m[j+22|0]=k>>>8;m[j+23|0]=k>>>16;m[j+24|0]=k>>>24;m[j+25|0]=c;m[j+26|0]=c>>>8;m[j+27|0]=c>>>16;m[j+28|0]=c>>>24;c=p[b+4|0]|p[b+5|0]<<8|(p[b+6|0]<<16|p[b+7|0]<<24);b=p[b|0]|p[b+1|0]<<8|(p[b+2|0]<<16|p[b+3|0]<<24);m[j+13|0]=b;m[j+14|0]=b>>>8;m[j+15|0]=b>>>16;m[j+16|0]=b>>>24;m[j+17|0]=c;m[j+18|0]=c>>>8;m[j+19|0]=c>>>16;m[j+20|0]=c>>>24;o[j+68>>2]=51;o[j+72>>2]=1;o[j+64>>2]=j;o[a+388>>2]=0;break d}o[j+68>>2]=c;o[j+64>>2]=b}if(f){o[j+76>>2]=1}b=a+8|0;if(xc(b,j- -64|0)){break c}c=a+368|0;if(!d){while(1){if(!rb(b,c,1)){break b}if(l[g](h,o[a+368>>2],o[a+372>>2],0,e,i)){break c}if(!l[g](h,o[a+376>>2],o[a+380>>2],0,e,i)){continue}break c}}while(1){if(!uc(b,c)){break b}if(l[g](h,o[a+368>>2],o[a+372>>2],0,e,i)){break c}if(!l[g](h,o[a+376>>2],o[a+380>>2],0,e,i)){continue}break}}g=1;break a}g=1;if(d|e|(c|0)!=4|(p[b|0]|p[b+1|0]<<8|(p[b+2|0]<<16|p[b+3|0]<<24))!=(p[5409]|p[5410]<<8|(p[5411]<<16|p[5412]<<24))){break a}o[a+384>>2]=1;n=d}b=a;d=b;c=o[b+396>>2];a=n+o[b+392>>2]|0;if(a>>>0<n>>>0){c=c+1|0}o[d+392>>2]=a;o[b+396>>2]=c;g=0}N=j+96|0;return g}function Oc(a,b){var c=0,d=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0;k=N-48|0;N=k;h(+a);j=e(1)|0;d=e(0)|0;a:{b:{i=j;j=i;l=i&2147483647;c:{if(l>>>0<=1074752122){if((j&1048575)==598523){break c}if(l>>>0<=1073928572){if((i|0)>0?1:(i|0)>=0?d>>>0<0?0:1:0){a=a+ -1.5707963267341256;c=a+ -6.077100506506192e-11;t[b>>3]=c;t[b+8>>3]=a-c+ -6.077100506506192e-11;d=1;break a}a=a+1.5707963267341256;c=a+6.077100506506192e-11;t[b>>3]=c;t[b+8>>3]=a-c+6.077100506506192e-11;d=-1;break a}if((i|0)>0?1:(i|0)>=0?d>>>0<0?0:1:0){a=a+ -3.1415926534682512;c=a+ -1.2154201013012384e-10;t[b>>3]=c;t[b+8>>3]=a-c+ -1.2154201013012384e-10;d=2;break a}a=a+3.1415926534682512;c=a+1.2154201013012384e-10;t[b>>3]=c;t[b+8>>3]=a-c+1.2154201013012384e-10;d=-2;break a}if(l>>>0<=1075594811){if(l>>>0<=1075183036){if((l|0)==1074977148){break c}if((i|0)>0?1:(i|0)>=0?d>>>0<0?0:1:0){a=a+ -4.712388980202377;c=a+ -1.8231301519518578e-10;t[b>>3]=c;t[b+8>>3]=a-c+ -1.8231301519518578e-10;d=3;break a}a=a+4.712388980202377;c=a+1.8231301519518578e-10;t[b>>3]=c;t[b+8>>3]=a-c+1.8231301519518578e-10;d=-3;break a}if((l|0)==1075388923){break c}if((i|0)>0?1:(i|0)>=0?d>>>0<0?0:1:0){a=a+ -6.2831853069365025;c=a+ -2.430840202602477e-10;t[b>>3]=c;t[b+8>>3]=a-c+ -2.430840202602477e-10;d=4;break a}a=a+6.2831853069365025;c=a+2.430840202602477e-10;t[b>>3]=c;t[b+8>>3]=a-c+2.430840202602477e-10;d=-4;break a}if(l>>>0>1094263290){break b}}n=a*.6366197723675814+6755399441055744+ -6755399441055744;c=a+n*-1.5707963267341256;m=n*6.077100506506192e-11;a=c-m;t[b>>3]=a;h(+a);d=e(1)|0;e(0)|0;i=l>>>20|0;j=(i-(d>>>20&2047)|0)<17;if(w(n)<2147483648){d=~~n}else{d=-2147483648}d:{if(j){break d}m=c;a=n*6.077100506303966e-11;c=c-a;m=n*2.0222662487959506e-21-(m-c-a);a=c-m;t[b>>3]=a;j=i;h(+a);i=e(1)|0;e(0)|0;if((j-(i>>>20&2047)|0)<50){break d}m=c;a=n*2.0222662487111665e-21;c=c-a;m=n*8.4784276603689e-32-(m-c-a);a=c-m;t[b>>3]=a}t[b+8>>3]=c-a-m;break a}if(l>>>0>=2146435072){a=a-a;t[b>>3]=a;t[b+8>>3]=a;d=0;break a}f(0,d|0);f(1,i&1048575|1096810496);a=+g();d=0;j=1;while(1){p=(k+16|0)+(d<<3)|0;if(w(a)<2147483648){d=~~a}else{d=-2147483648}c=+(d|0);t[p>>3]=c;a=(a-c)*16777216;d=1;p=j&1;j=0;if(p){continue}break}t[k+32>>3]=a;e:{if(a!=0){d=2;break e}j=1;while(1){d=j;j=d+ -1|0;if(t[(k+16|0)+(d<<3)>>3]==0){continue}break}}d=Nc(k+16|0,k,(l>>>20|0)+ -1046|0,d+1|0);a=t[k>>3];if((i|0)<-1?1:(i|0)<=-1?1:0){t[b>>3]=-a;t[b+8>>3]=-t[k+8>>3];d=0-d|0;break a}t[b>>3]=a;i=o[k+12>>2];o[b+8>>2]=o[k+8>>2];o[b+12>>2]=i}N=k+48|0;return d}function vc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,q=0,r=0;e=-1;a:{b:{if(!a){break b}g=o[a>>2];if(!g){break b}d=o[b>>2];k=p[d+5|0];f=o[b+12>>2];l=o[b+8>>2];i=p[d+26|0];n=p[d+18|0]|p[d+19|0]<<8|(p[d+20|0]<<16|p[d+21|0]<<24);j=p[d+14|0]|p[d+15|0]<<8|(p[d+16|0]<<16|p[d+17|0]<<24);q=p[d+6|0]|p[d+7|0]<<8|(p[d+8|0]<<16|p[d+9|0]<<24);r=p[d+10|0]|p[d+11|0]<<8|(p[d+12|0]<<16|p[d+13|0]<<24);m=p[d+4|0];c=o[a+36>>2];b=o[a+12>>2];if(b){h=o[a+8>>2]-b|0;o[a+8>>2]=h;if(h){pa(g,b+g|0,h)}o[a+12>>2]=0}if(c){b=a;g=o[a+28>>2]-c|0;if(g){h=o[a+16>>2];pa(h,h+(c<<2)|0,g<<2);g=o[a+20>>2];pa(g,g+(c<<3)|0,o[a+28>>2]-c<<3);h=o[a+28>>2]-c|0}else{h=0}o[b+28>>2]=h;o[a+36>>2]=0;o[a+32>>2]=o[a+32>>2]-c}if((j|0)!=o[a+336>>2]|m){break b}if(Hb(a,i+1|0)){break b}h=k&1;g=o[a+340>>2];c:{if((g|0)==(n|0)){break c}c=o[a+32>>2];j=o[a+28>>2];if((c|0)<(j|0)){e=o[a+8>>2];m=o[a+16>>2];b=c;while(1){e=e-p[m+(b<<2)|0]|0;b=b+1|0;if((b|0)<(j|0)){continue}break}o[a+8>>2]=e}o[a+28>>2]=c;if((g|0)==-1){break c}b=c+1|0;o[a+28>>2]=b;o[o[a+16>>2]+(c<<2)>>2]=1024;o[a+32>>2]=b}g=k&2;e=0;d:{if(!h){break d}b=o[a+28>>2];if(o[(o[a+16>>2]+(b<<2)|0)+ -4>>2]!=1024?(b|0)>=1:0){break d}g=0;if(!i){break d}b=0;while(1){e=b+1|0;b=p[(b+d|0)+27|0];f=f-b|0;l=b+l|0;if((b|0)!=255){break d}b=e;if((i|0)!=(b|0)){continue}break}e=i}if(f){c=o[a+4>>2];b=o[a+8>>2];e:{if((c-f|0)>(b|0)){c=o[a>>2];break e}if((c|0)>(2147483647-f|0)){break a}b=c+f|0;b=(b|0)<2147482623?b+1024|0:b;c=ea(o[a>>2],b);if(!c){break a}o[a>>2]=c;o[a+4>>2]=b;b=o[a+8>>2]}ca(b+c|0,l,f);o[a+8>>2]=o[a+8>>2]+f}l=k&4;f:{if((e|0)>=(i|0)){break f}k=o[a+20>>2];h=o[a+16>>2];c=o[a+28>>2];b=h+(c<<2)|0;f=p[(d+e|0)+27|0];o[b>>2]=f;j=k+(c<<3)|0;o[j>>2]=-1;o[j+4>>2]=-1;if(g){o[b>>2]=f|256}b=c+1|0;o[a+28>>2]=b;e=e+1|0;g:{if((f|0)==255){c=-1;break g}o[a+32>>2]=b}if((e|0)!=(i|0)){while(1){g=p[(d+e|0)+27|0];o[h+(b<<2)>>2]=g;f=k+(b<<3)|0;o[f>>2]=-1;o[f+4>>2]=-1;f=b+1|0;o[a+28>>2]=f;e=e+1|0;if((g|0)!=255){o[a+32>>2]=f;c=b}b=f;if((e|0)!=(i|0)){continue}break}}if((c|0)==-1){break f}b=o[a+20>>2]+(c<<3)|0;o[b>>2]=q;o[b+4>>2]=r}h:{if(!l){break h}o[a+328>>2]=1;b=o[a+28>>2];if((b|0)<1){break h}b=(o[a+16>>2]+(b<<2)|0)+ -4|0;o[b>>2]=o[b>>2]|512}o[a+340>>2]=n+1;e=0}return e}b=o[a>>2];if(b){X(b)}b=o[a+16>>2];if(b){X(b)}b=o[a+20>>2];if(b){X(b)}fa(a,360);return-1}function Rc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;e=N-48|0;N=e;k=o[2644];l=o[2641];while(1){c=o[b+4>>2];a:{if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break a}c=ga(b)}if((c|0)==32|c+ -9>>>0<5){continue}break}g=1;b:{c:{switch(c+ -43|0){case 0:case 2:break c;default:break b}}g=(c|0)==45?-1:1;c=o[b+4>>2];if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break b}c=ga(b)}d:{e:{f:{while(1){if(m[d+10484|0]==(c|32)){g:{if(d>>>0>6){break g}c=o[b+4>>2];if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break g}c=ga(b)}d=d+1|0;if((d|0)!=8){continue}break f}break}if((d|0)!=3){if((d|0)==8){break f}if(d>>>0<4){break e}if((d|0)==8){break f}}c=o[b+104>>2];if(c){o[b+4>>2]=o[b+4>>2]+ -1}if(d>>>0<4){break f}while(1){if(c){o[b+4>>2]=o[b+4>>2]+ -1}d=d+ -1|0;if(d>>>0>3){continue}break}}Sc(e,v(v(g|0)*v(F)));h=o[e+8>>2];f=o[e+12>>2];i=o[e>>2];j=o[e+4>>2];break d}h:{i:{j:{if(d){break j}d=0;while(1){if(m[d+10493|0]!=(c|32)){break j}k:{if(d>>>0>1){break k}c=o[b+4>>2];if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break k}c=ga(b)}d=d+1|0;if((d|0)!=3){continue}break}break i}l:{switch(d|0){case 0:m:{if((c|0)!=48){break m}d=o[b+4>>2];n:{if(d>>>0<r[b+104>>2]){o[b+4>>2]=d+1;d=p[d|0];break n}d=ga(b)}if((d&-33)==88){Bc(e+16|0,b,l,k,g);h=o[e+24>>2];f=o[e+28>>2];i=o[e+16>>2];j=o[e+20>>2];break d}if(!o[b+104>>2]){break m}o[b+4>>2]=o[b+4>>2]+ -1}Dc(e+32|0,b,c,l,k,g);h=o[e+40>>2];f=o[e+44>>2];i=o[e+32>>2];j=o[e+36>>2];break d;case 3:break i;default:break l}}if(o[b+104>>2]){o[b+4>>2]=o[b+4>>2]+ -1}break h}o:{c=o[b+4>>2];p:{if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break p}c=ga(b)}if((c|0)==40){d=1;break o}f=2147450880;if(!o[b+104>>2]){break d}o[b+4>>2]=o[b+4>>2]+ -1;break d}while(1){q:{c=o[b+4>>2];r:{if(c>>>0<r[b+104>>2]){o[b+4>>2]=c+1;c=p[c|0];break r}c=ga(b)}if(!(c+ -48>>>0<10|c+ -65>>>0<26|(c|0)==95)){if(c+ -97>>>0>=26){break q}}d=d+1|0;continue}break}f=2147450880;if((c|0)==41){break d}c=o[b+104>>2];if(c){o[b+4>>2]=o[b+4>>2]+ -1}if(!d){break d}while(1){d=d+ -1|0;if(c){o[b+4>>2]=o[b+4>>2]+ -1}if(d){continue}break}break d}o[2896]=28;o[b+112>>2]=0;o[b+116>>2]=0;c=o[b+8>>2];d=c-o[b+4>>2]|0;o[b+120>>2]=d;o[b+124>>2]=d>>31;o[b+104>>2]=c}o[a>>2]=i;o[a+4>>2]=j;o[a+8>>2]=h;o[a+12>>2]=f;N=e+48|0}function Fa(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,q=0,r=0,s=0,t=0,v=0,w=0,x=0;f=N-16|0;N=f;d=cb(o[o[a+4>>2]+6856>>2],f+4|0,f);h=o[a>>2];a:{b:{if(!d){o[h>>2]=8;break b}c:{if(!o[h+4>>2]){break c}h=o[a+4>>2];o[h+11804>>2]=o[f+4>>2];o[h+11812>>2]=o[f>>2];if(!o[h+11756>>2]){o[h+11760>>2]=1;break c}if(Ob(o[h+11752>>2])){break c}b=o[o[a+4>>2]+6856>>2];o[b+12>>2]=0;o[b+16>>2]=0;a=o[a>>2];if(o[a>>2]==4){break a}o[a>>2]=3;break a}h=o[f>>2];r=o[f+4>>2];o[f+8>>2]=0;o[f+12>>2]=0;d:{e:{d=o[a+4>>2];e=o[d+7272>>2];if(!e){break e}if((l[e](a,f+8|0,o[d+7288>>2])|0)!=1){break e}break d}f:{if(b){break f}g:{switch(p[r|0]&127){case 0:e=o[f+12>>2];d=o[a>>2];o[d+608>>2]=o[f+8>>2];o[d+612>>2]=e;break f;case 3:break g;default:break f}}d=o[a>>2];if(o[d+616>>2]|o[d+620>>2]){break f}e=o[f+12>>2];o[d+616>>2]=o[f+8>>2];o[d+620>>2]=e}j=o[a+4>>2];i=o[j+7048>>2];h:{if(!i){break h}g=o[a>>2];e=g;d=o[e+628>>2];e=o[e+624>>2];n=d;if(!(e|d)){break h}s=o[i>>2];if(!s){break h}k=o[j+7292>>2];if(k>>>0>=s>>>0){break h}q=o[j+7316>>2];d=q;t=o[j+7312>>2];v=o[g+36>>2];g=v;m=t+g|0;if(m>>>0<g>>>0){d=d+1|0}g=m+ -1|0;d=d+ -1|0;d=(g|0)!=-1?d+1|0:d;w=g;x=o[i+4>>2];while(1){m=u(k,24)+x|0;i=m;g=o[i>>2];i=o[i+4>>2];if((d|0)==(i|0)&g>>>0>w>>>0|i>>>0>d>>>0){break h}if((i|0)==(q|0)&g>>>0>=t>>>0|i>>>0>q>>>0){o[m>>2]=t;o[m+4>>2]=q;i=o[f+8>>2];g=o[f+12>>2];o[m+16>>2]=v;o[m+8>>2]=i-e;o[m+12>>2]=g-(n+(i>>>0<e>>>0)|0)}k=k+1|0;o[j+7292>>2]=k;if((k|0)!=(s|0)){continue}break}}i:{if(o[j+7260>>2]){c=Rd(o[a>>2]+632|0,r,h,b,o[j+7056>>2],c,o[j+7276>>2],a,o[j+7288>>2]);break i}c=l[o[j+7276>>2]](a,r,h,b,o[j+7056>>2],o[j+7288>>2])|0}if(!c){c=o[a+4>>2];e=c;g=c;d=o[c+7308>>2];n=h+o[c+7304>>2]|0;if(n>>>0<h>>>0){d=d+1|0}o[g+7304>>2]=n;o[e+7308>>2]=d;e=o[c+7316>>2];d=b;n=d+o[c+7312>>2]|0;if(n>>>0<d>>>0){e=e+1|0}o[c+7312>>2]=n;o[c+7316>>2]=e;k=1;h=o[c+7320>>2];d=o[c+7056>>2]+1|0;o[c+7320>>2]=h>>>0>d>>>0?h:d;c=o[o[a+4>>2]+6856>>2];o[c+12>>2]=0;o[c+16>>2]=0;if(!b){break a}b=o[a+4>>2]+6896|0;c=o[b>>2];g=b;b=o[f>>2];o[g>>2]=b>>>0<c>>>0?b:c;c=o[a+4>>2]+6900|0;a=o[c>>2];o[c>>2]=b>>>0>a>>>0?b:a;break a}}o[o[a>>2]>>2]=5;b=o[o[a+4>>2]+6856>>2];o[b+12>>2]=0;o[b+16>>2]=0;o[o[a>>2]>>2]=5}k=0}N=f+16|0;return k}function Tb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0;f=N-16|0;N=f;a:{if(!_(b,o[1394],o[1395])){break a}if(!_(b,0,o[1396])){break a}if(!_(b,o[a+20>>2]!=0,o[1397])){break a}i=16;j=1;d=b;b:{c:{d:{e:{f:{g:{h:{i:{j:{c=o[a>>2];if((c|0)<=2047){if((c|0)<=575){e=1;if((c|0)==192){break b}if((c|0)==256){break g}if((c|0)!=512){break c}e=9;break b}if((c|0)==576){break j}if((c|0)==1024){break f}if((c|0)!=1152){break c}e=3;break b}if((c|0)<=4607){if((c|0)==2048){break e}if((c|0)==2304){break i}if((c|0)!=4096){break c}e=12;break b}if((c|0)<=16383){if((c|0)==4608){break h}if((c|0)!=8192){break c}e=13;break b}if((c|0)==16384){break d}if((c|0)!=32768){break c}e=15;break b}e=2;break b}e=4;break b}e=5;break b}e=8;break b}e=10;break b}e=11;break b}e=14;break b}c=c>>>0<257;i=c?8:16;j=0;e=c?6:7}if(!_(d,e,o[1398])){break a}k:{l:{m:{n:{o:{p:{q:{r:{c=o[a+4>>2];if((c|0)<=44099){if((c|0)<=22049){if((c|0)==8e3){break r}if((c|0)!=16e3){break l}d=5;break k}if((c|0)==22050){break q}if((c|0)==24e3){break p}if((c|0)!=32e3){break l}d=8;break k}if((c|0)<=95999){if((c|0)==44100){break o}if((c|0)==48e3){break n}d=1;if((c|0)==88200){break k}break l}if((c|0)==96e3){break m}if((c|0)!=192e3){if((c|0)!=176400){break l}d=2;break k}d=3;break k}d=4;break k}d=6;break k}d=7;break k}d=9;break k}d=10;break k}d=11;break k}g=(c>>>0)%1e3|0;if(c>>>0<=255e3){d=12;h=12;if(!g){break k}}if(!((c>>>0)%10)){d=14;h=14;break k}d=c>>>0<65536?13:0;h=d}g=0;if(!_(b,d,o[1399])){break a}s:{t:{switch(o[a+12>>2]){case 0:d=o[a+8>>2]+ -1|0;break s;case 1:d=8;break s;case 2:d=9;break s;case 3:break t;default:break s}}d=10}if(!_(b,d,o[1400])){break a}d=b;c=He(o[a+16>>2]+ -8|0,30);if(c>>>0<=4){c=o[(c<<2)+10464>>2]}else{c=0}if(!_(d,c,o[1401])){break a}if(!_(b,0,o[1402])){break a}u:{if(!o[a+20>>2]){if(se(b,o[a+24>>2])){break u}break a}if(!re(b,o[a+24>>2],o[a+28>>2])){break a}}if(!j){if(!_(b,o[a>>2]+ -1|0,i)){break a}}v:{w:{switch(h+ -12|0){case 0:if(_(b,r[a+4>>2]/1e3|0,8)){break v}break a;case 1:if(_(b,o[a+4>>2],16)){break v}break a;case 2:break w;default:break v}}if(!_(b,r[a+4>>2]/10|0,16)){break a}}if(!te(b,f+15|0)){break a}g=(_(b,p[f+15|0],o[1403])|0)!=0}N=f+16|0;return g}function zb(a,b,c,d,e,f,g,h,i){var j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0,u=0,v=0,w=0;j=N-128|0;N=j;a:{b:{c:{if(!za(f,g,h,i,0,0,0,0)){break c}m=Qc(f,g,h,i);u=e>>>16|0;q=u&32767;if((q|0)==32767){break c}if(m){break b}}$(j+16|0,b,c,d,e,f,g,h,i);e=o[j+16>>2];d=o[j+20>>2];c=o[j+24>>2];b=o[j+28>>2];Kb(j,e,d,c,b,e,d,c,b);d=o[j+8>>2];e=o[j+12>>2];h=o[j>>2];i=o[j+4>>2];break a}n=e&65535|q<<16;l=n;k=d;n=h;t=i>>>16&32767;r=i&65535|t<<16;if((za(b,c,k,l,f,g,h,r)|0)<=0){if(za(b,c,k,l,f,g,n,r)){h=b;i=c;break a}$(j+112|0,b,c,d,e,0,0,0,0);d=o[j+120>>2];e=o[j+124>>2];h=o[j+112>>2];i=o[j+116>>2];break a}if(q){i=c;h=b}else{$(j+96|0,b,c,k,l,0,0,0,1081540608);h=o[j+108>>2];l=h;k=o[j+104>>2];q=(h>>>16|0)+ -120|0;i=o[j+100>>2];h=o[j+96>>2]}if(!t){$(j+80|0,f,g,n,r,0,0,0,1081540608);f=o[j+92>>2];r=f;n=o[j+88>>2];t=(f>>>16|0)+ -120|0;g=o[j+84>>2];f=o[j+80>>2]}w=n;m=n;n=k-m|0;l=l&65535|65536;v=r&65535|65536;p=(g|0)==(i|0)&h>>>0<f>>>0|i>>>0<g>>>0;m=(l-(v+(k>>>0<m>>>0)|0)|0)-(n>>>0<p>>>0)|0;s=n-p|0;p=(m|0)>-1?1:0;n=h-f|0;r=i-((h>>>0<f>>>0)+g|0)|0;if((q|0)>(t|0)){while(1){d:{if(p){if(!(n|s|(m|r))){$(j+32|0,b,c,d,e,0,0,0,0);d=o[j+40>>2];e=o[j+44>>2];h=o[j+32>>2];i=o[j+36>>2];break a}k=r>>>31|0;l=0;h=s;p=m<<1|h>>>31;h=h<<1;break d}m=l<<1|k>>>31;k=k<<1;l=m;n=h;r=i;p=0;h=i>>>31|0}k=h|k;i=k;h=w;s=i-h|0;l=l|p;m=l-((i>>>0<h>>>0)+v|0)|0;h=n;p=r<<1|h>>>31;h=h<<1;i=p;p=(g|0)==(i|0)&h>>>0<f>>>0|i>>>0<g>>>0;m=m-(s>>>0<p>>>0)|0;s=s-p|0;p=(m|0)>-1?1:0;n=h-f|0;r=i-((h>>>0<f>>>0)+g|0)|0;q=q+ -1|0;if((q|0)>(t|0)){continue}break}q=t}e:{if(!p){break e}h=n;k=s;i=r;l=m;if(h|k|(i|l)){break e}$(j+48|0,b,c,d,e,0,0,0,0);d=o[j+56>>2];e=o[j+60>>2];h=o[j+48>>2];i=o[j+52>>2];break a}if((l|0)==65535|l>>>0<65535){while(1){d=i>>>31|0;b=0;q=q+ -1|0;m=i<<1|h>>>31;h=h<<1;i=m;p=l<<1|k>>>31;k=k<<1|d;b=b|p;l=b;if((b|0)==65536&k>>>0<0|b>>>0<65536){continue}break}}b=u&32768;if((q|0)<=0){$(j- -64|0,h,i,k,l&65535|(b|q+120)<<16,0,0,0,1065811968);d=o[j+72>>2];e=o[j+76>>2];h=o[j+64>>2];i=o[j+68>>2];break a}d=k;e=l&65535|(b|q)<<16}o[a>>2]=h;o[a+4>>2]=i;o[a+8>>2]=d;o[a+12>>2]=e;N=j+128|0}function xd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0;d=o[a>>2];j=o[d+36>>2];r=j+1|0;a:{b:{k=o[d+24>>2];if(!(!o[d+16>>2]|(k|0)!=2)){while(1){f=o[a+4>>2];if(o[d+4>>2]){d=o[f+11800>>2];e=r-o[f+7052>>2]|0;g=c-i|0;h=e>>>0<g>>>0?e:g;c:{if(!h){break c}if(!k){d=d+h|0;break c}e=i<<1;l=o[f+11768>>2];q=o[f+11764>>2];g=0;while(1){n=d<<2;p=e<<2;o[n+q>>2]=o[p+b>>2];o[l+n>>2]=o[(p|4)+b>>2];d=d+1|0;e=e+2|0;g=g+1|0;if((h|0)!=(g|0)){continue}break}}o[f+11800>>2]=d}e=i>>>0<c>>>0;d=o[f+7052>>2];d:{if(d>>>0>j>>>0|i>>>0>=c>>>0){break d}l=o[f+40>>2];q=o[f+8>>2];n=o[f+36>>2];p=o[f+4>>2];while(1){e=d<<2;h=(m<<2)+b|0;g=o[h>>2];o[e+p>>2]=g;h=o[h+4>>2];o[e+q>>2]=h;o[e+l>>2]=g-h;o[e+n>>2]=g+h>>1;d=d+1|0;m=m+2|0;i=i+1|0;e=i>>>0<c>>>0;if(i>>>0>=c>>>0){break d}if(d>>>0<=j>>>0){continue}break}}o[f+7052>>2]=d;if(d>>>0>j>>>0){h=0;if(!Oa(a,0,0)){break a}d=o[a+4>>2];g=o[d+4>>2];h=g;g=j<<2;o[h>>2]=o[h+g>>2];f=o[d+8>>2];o[f>>2]=o[f+g>>2];f=o[d+36>>2];o[f>>2]=o[f+g>>2];f=o[d+40>>2];o[f>>2]=o[f+g>>2];o[d+7052>>2]=1}if(!e){break b}d=o[a>>2];continue}}while(1){i=o[a+4>>2];if(o[d+4>>2]){g=o[i+11800>>2];d=r-o[i+7052>>2]|0;e=c-f|0;h=d>>>0<e>>>0?d:e;e:{if(!h){break e}if(!k){g=g+h|0;break e}e=u(f,k);l=0;while(1){d=0;while(1){o[o[(i+(d<<2)|0)+11764>>2]+(g<<2)>>2]=o[(e<<2)+b>>2];e=e+1|0;d=d+1|0;if((k|0)!=(d|0)){continue}break}g=g+1|0;l=l+1|0;if((h|0)!=(l|0)){continue}break}}o[i+11800>>2]=g}g=f>>>0<c>>>0;e=o[i+7052>>2];f:{if(e>>>0>j>>>0|f>>>0>=c>>>0){break f}if(k){while(1){d=0;while(1){o[o[(i+(d<<2)|0)+4>>2]+(e<<2)>>2]=o[(m<<2)+b>>2];m=m+1|0;d=d+1|0;if((k|0)!=(d|0)){continue}break}e=e+1|0;f=f+1|0;g=f>>>0<c>>>0;if(f>>>0>=c>>>0){break f}if(e>>>0<=j>>>0){continue}break f}}while(1){e=e+1|0;f=f+1|0;g=f>>>0<c>>>0;if(f>>>0>=c>>>0){break f}if(e>>>0<=j>>>0){continue}break}}o[i+7052>>2]=e;if(e>>>0>j>>>0){d=0;h=d;if(!Oa(a,0,0)){break a}e=o[a+4>>2];if(k){while(1){i=o[(e+(d<<2)|0)+4>>2];o[i>>2]=o[i+(j<<2)>>2];d=d+1|0;if((k|0)!=(d|0)){continue}break}}o[e+7052>>2]=1}if(!g){break b}d=o[a>>2];continue}}h=1}return h|0}function rb(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,q=0,r=0,s=0;a:{if(!a){break a}j=o[a+28>>2];d=(j|0)<255?j:255;if(!d){break a}k=o[a>>2];if(!k){break a}b:{c:{d:{l=o[a+332>>2];if(l){if((j|0)>=1){break d}i=-1;g=-1;d=0;break c}d=(d|0)>0?d:0;while(1){if((d|0)==(f|0)){break c}h=f<<2;e=f+1|0;f=e;if(p[h+o[a+16>>2]|0]==255){continue}break}d=e;break c}e=(d|0)>1?d:1;i=-1;g=-1;d=0;e:{while(1){if(!((f|0)<=4096|(h|0)<=3)){c=1;break e}h=0;q=p[o[a+16>>2]+(d<<2)|0];if((q|0)!=255){r=r+1|0;h=r;g=o[a+20>>2]+(d<<3)|0;i=o[g>>2];g=o[g+4>>2]}f=f+q|0;d=d+1|0;if((e|0)!=(d|0)){continue}break}d=e}e=255;if((d|0)==255){break b}}e=d;if(!c){break a}}o[a+40>>2]=1399285583;n[a+44>>1]=0;h=o[a+16>>2];c=(p[h+1|0]^-1)&1;c=l?c:c|2;m[a+45|0]=c;if(!(!o[a+328>>2]|(e|0)!=(j|0))){m[a+45|0]=c|4}o[a+332>>2]=1;c=g;m[a+53|0]=c>>>24;m[a+52|0]=c>>>16;m[a+51|0]=c>>>8;m[a+50|0]=c;m[a+49|0]=(c&16777215)<<8|i>>>24;m[a+48|0]=(c&65535)<<16|i>>>16;m[a+47|0]=(c&255)<<24|i>>>8;m[a+46|0]=i;c=o[a+336>>2];m[a+54|0]=c;m[a+55|0]=c>>>8;m[a+56|0]=c>>>16;m[a+57|0]=c>>>24;d=o[a+340>>2];if((d|0)==-1){o[a+340>>2]=0;d=0}m[a+66|0]=e;f=0;n[a+62>>1]=0;n[a+64>>1]=0;m[a+61|0]=d>>>24;m[a+60|0]=d>>>16;m[a+59|0]=d>>>8;m[a+58|0]=d;s=1;o[a+340>>2]=d+1;if((e|0)>=1){d=0;while(1){c=o[h+(d<<2)>>2];m[(a+d|0)+67|0]=c;f=(c&255)+f|0;d=d+1|0;if((e|0)!=(d|0)){continue}break}}o[b>>2]=a+40;c=e+27|0;o[a+324>>2]=c;o[b+4>>2]=c;c=o[a+12>>2];o[b+12>>2]=f;o[b+8>>2]=c+k;c=j-e|0;o[a+28>>2]=c;pa(h,h+(e<<2)|0,c<<2);c=o[a+20>>2];pa(c,c+(e<<3)|0,o[a+28>>2]<<3);o[a+12>>2]=o[a+12>>2]+f;if(!b){break a}a=0;m[o[b>>2]+22|0]=0;m[o[b>>2]+23|0]=0;m[o[b>>2]+24|0]=0;m[o[b>>2]+25|0]=0;c=o[b+4>>2];if((c|0)>=1){g=o[b>>2];d=0;while(1){a=o[((p[d+g|0]^a>>>24)<<2)+6512>>2]^a<<8;d=d+1|0;if((c|0)!=(d|0)){continue}break}}c=o[b+12>>2];if((c|0)>=1){g=o[b+8>>2];d=0;while(1){a=o[((p[d+g|0]^a>>>24)<<2)+6512>>2]^a<<8;d=d+1|0;if((c|0)!=(d|0)){continue}break}}m[o[b>>2]+22|0]=a;m[o[b>>2]+23|0]=a>>>8;m[o[b>>2]+24|0]=a>>>16;m[o[b>>2]+25|0]=a>>>24}return s}function $a(a){a=a|0;var b=0,c=0;c=1;if(o[o[a>>2]>>2]!=9){b=o[a+4>>2];_b(b+3732|0,b+3636|0);X(o[o[a+4>>2]+452>>2]);o[o[a+4>>2]+452>>2]=0;b=o[a+4>>2];o[b+252>>2]=0;Ae(o[b+56>>2]);b=o[a+4>>2];c=o[b+60>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+60>>2]=0;b=o[a+4>>2]}c=o[b+3592>>2];if(c){X(c);o[o[a+4>>2]+92>>2]=0;o[o[a+4>>2]+3592>>2]=0;b=o[a+4>>2]}c=o[b- -64>>2];if(c){X(c+ -16|0);o[o[a+4>>2]- -64>>2]=0;b=o[a+4>>2]}c=o[b+3596>>2];if(c){X(c);o[o[a+4>>2]+96>>2]=0;o[o[a+4>>2]+3596>>2]=0;b=o[a+4>>2]}c=o[b+68>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+68>>2]=0;b=o[a+4>>2]}c=o[b+3600>>2];if(c){X(c);o[o[a+4>>2]+100>>2]=0;o[o[a+4>>2]+3600>>2]=0;b=o[a+4>>2]}c=o[b+72>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+72>>2]=0;b=o[a+4>>2]}c=o[b+3604>>2];if(c){X(c);o[o[a+4>>2]+104>>2]=0;o[o[a+4>>2]+3604>>2]=0;b=o[a+4>>2]}c=o[b+76>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+76>>2]=0;b=o[a+4>>2]}c=o[b+3608>>2];if(c){X(c);o[o[a+4>>2]+108>>2]=0;o[o[a+4>>2]+3608>>2]=0;b=o[a+4>>2]}c=o[b+80>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+80>>2]=0;b=o[a+4>>2]}c=o[b+3612>>2];if(c){X(c);o[o[a+4>>2]+112>>2]=0;o[o[a+4>>2]+3612>>2]=0;b=o[a+4>>2]}c=o[b+84>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+84>>2]=0;b=o[a+4>>2]}c=o[b+3616>>2];if(c){X(c);o[o[a+4>>2]+116>>2]=0;o[o[a+4>>2]+3616>>2]=0;b=o[a+4>>2]}c=o[b+88>>2];if(c){X(c+ -16|0);o[o[a+4>>2]+88>>2]=0;b=o[a+4>>2]}c=o[b+3620>>2];if(c){X(c);o[o[a+4>>2]+120>>2]=0;o[o[a+4>>2]+3620>>2]=0;b=o[a+4>>2]}o[b+220>>2]=0;o[b+224>>2]=0;if(o[b>>2]){b=o[a>>2]+32|0;sc(b+368|0);sb(b+8|0);b=o[a+4>>2]}c=o[b+52>>2];if(c){if((c|0)!=o[1887]){Cb(c);b=o[a+4>>2]}o[b+52>>2]=0}c=1;if(o[b+3624>>2]){c=!Pa(b+312|0,b+3732|0,16)}o[b+48>>2]=0;o[b+3632>>2]=0;fa(b+608|0,512);o[b+32>>2]=0;o[b+24>>2]=0;o[b+28>>2]=0;o[b+16>>2]=0;o[b+20>>2]=0;o[b+8>>2]=0;o[b+12>>2]=0;o[b>>2]=0;o[b+4>>2]=0;b=o[a+4>>2];o[b+1124>>2]=0;o[b+608>>2]=1;b=o[a>>2];o[b+28>>2]=0;o[b+32>>2]=1;o[o[a>>2]>>2]=9}return c|0}function oe(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=v(0),m=0,n=0,p=0,q=0,r=0,t=0,u=0,w=0,x=0,y=0,z=0,A=v(0);if(b){f=o[a+ -4>>2];d=o[a+ -8>>2];g=f-d|0;e=o[a+ -12>>2];p=g+(e-d|0)|0;y=p+(((e<<1)-d|0)-o[a+ -16>>2]|0)|0;while(1){d=o[(x<<2)+a>>2];e=d>>31;e=e^d+e;h=e+w|0;if(h>>>0<e>>>0){u=u+1|0}w=h;e=d-f|0;h=e>>31;h=h^e+h;f=h+t|0;if(f>>>0<h>>>0){q=q+1|0}t=f;h=e-g|0;f=h>>31;f=f^f+h;g=f+r|0;if(g>>>0<f>>>0){k=k+1|0}r=g;p=h-p|0;f=p>>31;f=f^f+p;g=f+m|0;if(g>>>0<f>>>0){i=i+1|0}m=g;g=p-y|0;f=g>>31;f=f^f+g;g=f+n|0;if(g>>>0<f>>>0){j=j+1|0}n=g;f=d;g=e;y=p;p=h;x=x+1|0;if((x|0)!=(b|0)){continue}break}}d=(k|0)==(q|0)&t>>>0<r>>>0|q>>>0<k>>>0;e=d?t:r;a=e;d=d?q:k;e=(i|0)==(d|0)&e>>>0<m>>>0|d>>>0<i>>>0;h=e?a:m;d=e?d:i;e=(j|0)==(d|0)&h>>>0<n>>>0|d>>>0<j>>>0;h=e?h:n;d=e?d:j;a=0;a:{if((d|0)==(u|0)&w>>>0<h>>>0|u>>>0<d>>>0){break a}d=(i|0)==(k|0)&r>>>0<m>>>0|k>>>0<i>>>0;e=d?r:m;a=e;d=d?k:i;e=(j|0)==(d|0)&e>>>0<n>>>0|d>>>0<j>>>0;h=e?a:n;d=e?d:j;a=1;if((d|0)==(q|0)&t>>>0<h>>>0|q>>>0<d>>>0){break a}a=(i|0)==(j|0)&m>>>0<n>>>0|i>>>0<j>>>0;d=a;e=d?m:n;a=d?i:j;a=(a|0)==(k|0)&r>>>0<e>>>0|k>>>0<a>>>0?2:d?3:4}g=c;if(u|w){l=v(la((+(w>>>0)+4294967296*+(u>>>0))*.6931471805599453/+(b>>>0))/.6931471805599453)}else{l=v(0)}s[g>>2]=l;g=c;if(q|t){l=v(la((+(t>>>0)+4294967296*+(q>>>0))*.6931471805599453/+(b>>>0))/.6931471805599453)}else{l=v(0)}s[g+4>>2]=l;g=c;if(k|r){l=v(la((+(r>>>0)+4294967296*+(k>>>0))*.6931471805599453/+(b>>>0))/.6931471805599453)}else{l=v(0)}s[g+8>>2]=l;g=c;if(i|m){l=v(la((+(m>>>0)+4294967296*+(i>>>0))*.6931471805599453/+(b>>>0))/.6931471805599453)}else{l=v(0)}s[g+12>>2]=l;if(!(j|n)){s[c+16>>2]=0;return a|0}z=c,A=v(la((+(n>>>0)+4294967296*+(j>>>0))*.6931471805599453/+(b>>>0))/.6931471805599453),s[z+16>>2]=A;return a|0}function _c(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=v(0),n=0,p=v(0),q=0,r=v(0);while(1){m=c;c=v(.05000000074505806);if(m<=v(0)){continue}c=v(.949999988079071);if(m>=v(1)){continue}break}c=v(m*v(.5));p=c;m=v(b|0);d=v(m*d);a:{if(v(w(d))<v(2147483648)){k=~~d;break a}k=-2147483648}d=v(p*v(k|0));b:{if(v(w(d))<v(2147483648)){g=~~d;break b}g=-2147483648}i=(g|0)<1;h=b;d=v(m*e);c:{if(v(w(d))<v(2147483648)){j=~~d;break c}j=-2147483648}c=v(c*v(h-j|0));d:{if(v(w(c))<v(2147483648)){h=~~c;break d}h=-2147483648}if(!((b|0)<1|i)){f=g+ -1>>>0<b+ -1>>>0?g:b;l=+(g|0);i=0;n=1;while(1){q=(i<<2)+a|0,r=v(.5-ba(+(n|0)*3.141592653589793/l)*.5),s[q>>2]=r;n=n+1|0;i=i+1|0;if((i|0)!=(f|0)){continue}break}}i=k-g|0;e:{if((f|0)>=(i|0)|(f|0)>=(b|0)){break e}while(1){o[(f<<2)+a>>2]=1065353216;f=f+1|0;if((f|0)>=(i|0)){break e}if((f|0)<(b|0)){continue}break}}f:{if((f|0)>=(k|0)|(f|0)>=(b|0)){break f}l=+(g|0);while(1){q=(f<<2)+a|0,r=v(.5-ba(+(g|0)*3.141592653589793/l)*.5),s[q>>2]=r;f=f+1|0;if((f|0)>=(k|0)){break f}g=g+ -1|0;if((f|0)<(b|0)){continue}break}}g:{if((f|0)>=(j|0)|(f|0)>=(b|0)){break g}g=f^-1;k=g+j|0;g=b+g|0;fa((f<<2)+a|0,((k>>>0<g>>>0?k:g)<<2)+4|0);while(1){f=f+1|0;if((f|0)>=(j|0)){break g}if((f|0)<(b|0)){continue}break}}j=h+j|0;h:{if((f|0)>=(j|0)|(f|0)>=(b|0)){break h}l=+(h|0);g=1;while(1){q=(f<<2)+a|0,r=v(.5-ba(+(g|0)*3.141592653589793/l)*.5),s[q>>2]=r;f=f+1|0;if((f|0)>=(j|0)){break h}g=g+1|0;if((f|0)<(b|0)){continue}break}}g=b-h|0;i:{if((f|0)>=(g|0)|(f|0)>=(b|0)){break i}while(1){o[(f<<2)+a>>2]=1065353216;f=f+1|0;if((f|0)>=(g|0)){break i}if((f|0)<(b|0)){continue}break}}if((f|0)<(b|0)){l=+(h|0);while(1){q=(f<<2)+a|0,r=v(.5-ba(+(h|0)*3.141592653589793/l)*.5),s[q>>2]=r;h=h+ -1|0;f=f+1|0;if((f|0)!=(b|0)){continue}break}}}function fc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;g=o[a+4>>2];c=g&3;d=g&-8;f=d+a|0;a:{if(!c){c=0;if(b>>>0<256){break a}if(d>>>0>=b+4>>>0){c=a;if(d-b>>>0<=o[3017]<<1>>>0){break a}}return 0}b:{if(d>>>0>=b>>>0){c=d-b|0;if(c>>>0<16){break b}o[a+4>>2]=g&1|b|2;b=a+b|0;o[b+4>>2]=c|3;o[f+4>>2]=o[f+4>>2]|1;Db(b,c);break b}c=0;if(o[2903]==(f|0)){d=d+o[2900]|0;if(d>>>0<=b>>>0){break a}o[a+4>>2]=g&1|b|2;c=a+b|0;b=d-b|0;o[c+4>>2]=b|1;o[2900]=b;o[2903]=c;break b}if(o[2902]==(f|0)){d=d+o[2899]|0;if(d>>>0<b>>>0){break a}c=d-b|0;c:{if(c>>>0>=16){o[a+4>>2]=g&1|b|2;b=a+b|0;o[b+4>>2]=c|1;d=a+d|0;o[d>>2]=c;o[d+4>>2]=o[d+4>>2]&-2;break c}o[a+4>>2]=d|g&1|2;b=a+d|0;o[b+4>>2]=o[b+4>>2]|1;c=0;b=0}o[2902]=b;o[2899]=c;break b}e=o[f+4>>2];if(e&2){break a}h=d+(e&-8)|0;if(h>>>0<b>>>0){break a}j=h-b|0;d:{if(e>>>0<=255){c=o[f+8>>2];e=e>>>3|0;d=o[f+12>>2];if((d|0)==(c|0)){l=11588,m=o[2897]&He(-2,e),o[l>>2]=m;break d}o[c+12>>2]=d;o[d+8>>2]=c;break d}i=o[f+24>>2];d=o[f+12>>2];e:{if((f|0)!=(d|0)){c=o[f+8>>2];o[c+12>>2]=d;o[d+8>>2]=c;break e}f:{c=f+20|0;e=o[c>>2];if(e){break f}c=f+16|0;e=o[c>>2];if(e){break f}d=0;break e}while(1){k=c;d=e;c=d+20|0;e=o[c>>2];if(e){continue}c=d+16|0;e=o[d+16>>2];if(e){continue}break}o[k>>2]=0}if(!i){break d}c=o[f+28>>2];e=(c<<2)+11892|0;g:{if(o[e>>2]==(f|0)){o[e>>2]=d;if(d){break g}l=11592,m=o[2898]&He(-2,c),o[l>>2]=m;break d}o[i+(o[i+16>>2]==(f|0)?16:20)>>2]=d;if(!d){break d}}o[d+24>>2]=i;c=o[f+16>>2];if(c){o[d+16>>2]=c;o[c+24>>2]=d}c=o[f+20>>2];if(!c){break d}o[d+20>>2]=c;o[c+24>>2]=d}if(j>>>0<=15){o[a+4>>2]=g&1|h|2;b=a+h|0;o[b+4>>2]=o[b+4>>2]|1;break b}o[a+4>>2]=g&1|b|2;b=a+b|0;o[b+4>>2]=j|3;c=a+h|0;o[c+4>>2]=o[c+4>>2]|1;Db(b,j)}c=a}return c}function kb(a,b,c,d,e,f,g){var h=0,i=0,j=0;h=N-16|0;N=h;a:{if(!e){break a}b:{switch(l[e](a,b,c,g)|0){case 1:o[o[a>>2]>>2]=5;break a;case 0:break b;default:break a}}e=da(282);o[d>>2]=e;if(!e){o[o[a>>2]>>2]=8;break a}i=27;while(1){o[h+12>>2]=i;b=5;c:{d:{switch(l[f](a,e,h+12|0,g)|0){case 1:b=o[h+12>>2];if(b){break c}b=2;default:o[o[a>>2]>>2]=b;break a;case 3:break a;case 0:break d}}b=o[h+12>>2]}e=b+e|0;i=i-b|0;if(i){continue}break}b=o[d>>2];o[d+4>>2]=p[b+26|0]+27;e:{if(!(m[b+5|0]&1|(p[b|0]|p[b+1|0]<<8|(p[b+2|0]<<16|p[b+3|0]<<24))!=1399285583|((p[b+6|0]|p[b+7|0]<<8|(p[b+8|0]<<16|p[b+9|0]<<24))!=0|(p[b+10|0]|p[b+11|0]<<8|(p[b+12|0]<<16|p[b+13|0]<<24))!=0))){i=p[b+26|0];if(i){break e}}o[o[a>>2]>>2]=2;break a}e=b+27|0;while(1){o[h+12>>2]=i;b=5;f:{g:{switch(l[f](a,e,h+12|0,g)|0){case 1:b=o[h+12>>2];if(b){break f}b=2;default:o[o[a>>2]>>2]=b;break a;case 3:break a;case 0:break g}}b=o[h+12>>2]}e=b+e|0;i=i-b|0;if(i){continue}break}e=0;b=o[d>>2];c=p[b+26|0];h:{if((c|0)!=1){c=c+ -1|0;while(1){if(p[(b+e|0)+27|0]!=255){o[o[a>>2]>>2]=2;break h}e=e+1|0;if(e>>>0<c>>>0){continue}break}}e=p[(b+e|0)+27|0]+u(e,255)|0;o[d+12>>2]=e;i=da(e?e:1);o[d+8>>2]=i;if(!i){o[o[a>>2]>>2]=8;break h}c=h;if(e){while(1){o[h+12>>2]=e;b=5;i:{j:{switch(l[f](a,i,h+12|0,g)|0){case 1:b=o[h+12>>2];if(b){break i}b=2;default:o[o[a>>2]>>2]=b;break h;case 3:break h;case 0:break j}}b=o[h+12>>2]}i=b+i|0;e=e-b|0;if(e){continue}break}b=o[d>>2]}o[c+12>>2]=p[b+22|0]|p[b+23|0]<<8|(p[b+24|0]<<16|p[b+25|0]<<24);tb(d);b=o[d>>2];if(o[h+12>>2]==(p[b+22|0]|p[b+23|0]<<8|(p[b+24|0]<<16|p[b+25|0]<<24))){j=1;break a}o[o[a>>2]>>2]=2}}N=h+16|0;return j}function qc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0;i=N-16|0;N=i;a:{if(o[a+4>>2]<0){break a}e=o[a+12>>2];j=o[a+8>>2]-e|0;c=e+o[a>>2]|0;b:{c:{d:{f=o[a+20>>2];e:{if(!f){if((j|0)<27){break a}if((p[c|0]|p[c+1|0]<<8|(p[c+2|0]<<16|p[c+3|0]<<24))!=1399285583){break e}e=p[c+26|0];f=e+27|0;if((j|0)<(f|0)){break a}if(e){e=o[a+24>>2];while(1){e=p[(c+g|0)+27|0]+e|0;o[a+24>>2]=e;g=g+1|0;if(g>>>0<p[c+26|0]){continue}break}}o[a+20>>2]=f}if((o[a+24>>2]+f|0)>(j|0)){break a}e=p[c+22|0]|p[c+23|0]<<8|(p[c+24|0]<<16|p[c+25|0]<<24);o[i+12>>2]=e;g=0;m[c+22|0]=0;m[c+23|0]=0;m[c+24|0]=0;m[c+25|0]=0;k=o[a+24>>2];h=o[a+20>>2];m[c+22|0]=0;m[c+23|0]=0;m[c+24|0]=0;m[c+25|0]=0;if((h|0)>0){f=0;while(1){d=o[((p[c+f|0]^d>>>24)<<2)+6512>>2]^d<<8;f=f+1|0;if((h|0)!=(f|0)){continue}break}}if((k|0)>0){h=c+h|0;while(1){d=o[((p[g+h|0]^d>>>24)<<2)+6512>>2]^d<<8;g=g+1|0;if((k|0)!=(g|0)){continue}break}}m[c+22|0]=d;m[c+23|0]=d>>>8;m[c+24|0]=d>>>16;m[c+25|0]=d>>>24;if(o[i+12>>2]==(p[c+22|0]|p[c+23|0]<<8|(p[c+24|0]<<16|p[c+25|0]<<24))){break d}m[c+22|0]=e;m[c+23|0]=e>>>8;m[c+24|0]=e>>>16;m[c+25|0]=e>>>24}o[a+20>>2]=0;o[a+24>>2]=0;d=zc(c+1|0,j+ -1|0);if(!d){break c}g=o[a>>2];break b}h=o[a+12>>2];f:{if(!b){f=o[a+24>>2];d=o[a+20>>2];break f}e=h+o[a>>2]|0;o[b>>2]=e;d=o[a+20>>2];o[b+4>>2]=d;o[b+8>>2]=d+e;f=o[a+24>>2];o[b+12>>2]=f}o[a+24>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;d=d+f|0;o[a+12>>2]=h+d;break a}g=o[a>>2];d=g+o[a+8>>2]|0}o[a+12>>2]=d-g;d=c-d|0}N=i+16|0;return d}function Ud(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,m=0,n=0,q=0,r=0,s=0,t=0;i=N-16|0;N=i;k=o[c>>2];o[c>>2]=0;a:{b:{c:{if(!k){break c}m=a+416|0;n=a+368|0;q=a+440|0;r=a+8|0;s=o[2721];t=p[7536];while(1){if(o[a+408>>2]){break c}d:{e:{if(o[a+412>>2]){if(o[a+432>>2]){j=o[a+440>>2];h=o[a+444>>2];f=k-g|0;if(h>>>0>f>>>0){break e}b=ca(b,j,h);o[c>>2]=h+o[c>>2];o[a+432>>2]=0;b=b+h|0;break d}f=wc(r,q);if((f|0)>=1){o[a+432>>2]=1;j=o[a+444>>2];if((j|0)<1){break d}h=o[q>>2];if(p[h|0]!=(t|0)){break d}g=3;if((j|0)<9){break a}f=s;if((p[h+1|0]|p[h+2|0]<<8|(p[h+3|0]<<16|p[h+4|0]<<24))!=(p[f|0]|p[f+1|0]<<8|(p[f+2|0]<<16|p[f+3|0]<<24))){break a}f=p[h+5|0];o[a+396>>2]=f;o[a+400>>2]=p[h+6|0];if((f|0)!=1){g=4;break a}o[a+444>>2]=j+ -9;o[a+440>>2]=h+9;break d}if(f){g=2;break a}o[a+412>>2]=0;break d}f=rc(n,m);if((f|0)>=1){if(o[a+404>>2]){f=o[m>>2];f=p[f+14|0]|p[f+15|0]<<8|(p[f+16|0]<<16|p[f+17|0]<<24);o[a+404>>2]=0;o[a+344>>2]=f;o[a+4>>2]=f}if(vc(r,m)){break d}o[a+432>>2]=0;o[a+412>>2]=1;break d}if(f){g=2;break a}f=k-o[c>>2]|0;f=f>>>0>8192?f:8192;g=tc(n,f);if(!g){g=7;break a}o[i+12>>2]=f;f:{switch((l[8](d,g,i+12|0,e)|0)+ -1|0){case 0:o[a+408>>2]=1;break;case 4:break b;default:break f}}if((pc(n,o[i+12>>2])|0)>=0){break d}g=6;break a}b=ca(b,j,f);o[c>>2]=f+o[c>>2];o[a+440>>2]=f+o[a+440>>2];o[a+444>>2]=o[a+444>>2]-f;b=b+f|0}g=o[c>>2];if(k>>>0>g>>>0){continue}break}}N=i+16|0;return!g&o[a+408>>2]!=0}g=5}N=i+16|0;return g}function Zb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0;g=N-16|0;N=g;m=(c<<2)+b|0;a:{if(!d){p=1;if((c|0)<1){break a}while(1){if(!eb(a,g+8|0)){p=0;break a}c=o[g+8>>2];o[b>>2]=c>>>1^0-(c&1);b=b+4|0;if(b>>>0<m>>>0){continue}break}break a}e=o[a+16>>2];k=o[a+8>>2];b:{if(e>>>0<k>>>0){l=o[a>>2];n=o[a+20>>2];j=o[l+(e<<2)>>2]<<n;c=0;break b}c=1}while(1){c:{d:{e:{f:{if(!c){f=32-n|0;g:{if(b>>>0<m>>>0){q=32-d|0;while(1){c=e;h=f;h:{if(j){h=x(j);i=h;break h}while(1){c=c+1|0;if(c>>>0>=k>>>0){break g}j=o[(c<<2)+l>>2];i=x(j);h=i+h|0;if(!j){continue}break}}e=j<<i<<1;i=e>>>q|0;o[g+8>>2]=h;f=(h^-1)+f&31;i:{if(f>>>0>=d>>>0){j=e<<d;f=f-d|0;e=c;break i}e=c+1|0;if(e>>>0>=k>>>0){break f}c=o[(e<<2)+l>>2];f=f+q|0;j=c<<32-f;i=c>>>f|i}o[g+12>>2]=i;c=h<<d|i;o[b>>2]=c>>>1^0-(c&1);b=b+4|0;if(b>>>0<m>>>0){continue}break}}b=e>>>0<k>>>0;o[a+16>>2]=(b&!f)+e;o[a+20>>2]=32-(f?f:b<<5);p=1;break a}o[a+20>>2]=0;c=e+1|0;o[a+16>>2]=k>>>0>c>>>0?k:c;break d}if(!eb(a,g+8|0)){break a}h=o[g+8>>2]+h|0;o[g+8>>2]=h;i=0;f=0;break e}o[a+16>>2]=e;o[a+20>>2]=0}if(!Y(a,g+12|0,d-f|0)){break a}c=h<<d;e=o[g+12>>2]|i;o[g+12>>2]=e;h=0;c=c|e;o[b>>2]=c>>>1^0-(c&1);l=o[a>>2];e=o[a+16>>2];n=o[a+20>>2];j=o[l+(e<<2)>>2]<<n;k=o[a+8>>2];b=b+4|0;if(e>>>0<k>>>0|b>>>0>=m>>>0){break c}}c=1;continue}c=0;continue}}N=g+16|0;return p}function yd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,s=0,t=0;f=o[a>>2];l=o[f+36>>2];r=l+1|0;e=o[a+4>>2];k=o[f+24>>2];n=l<<2;a:{while(1){d=r-o[e+7052>>2]|0;g=c-h|0;g=d>>>0<g>>>0?d:g;if(o[f+4>>2]){if(k){f=g<<2;d=0;while(1){i=d<<2;ca(o[(i+e|0)+11764>>2]+(o[e+11800>>2]<<2)|0,o[b+i>>2]+(h<<2)|0,f);d=d+1|0;if((k|0)!=(d|0)){continue}break}}e=e+11800|0;o[e>>2]=g+o[e>>2]}if(k){f=g<<2;e=0;d=0;while(1){i=d<<2;m=o[i+b>>2];if(!m){break a}j=i;i=o[a+4>>2];ca(o[(j+i|0)+4>>2]+(o[i+7052>>2]<<2)|0,m+(h<<2)|0,f);d=d+1|0;if((k|0)!=(d|0)){continue}break}}f=o[a>>2];b:{if(o[f+16>>2]){e=o[a+4>>2];if(h>>>0>=c>>>0){break b}d=o[e+7052>>2];if(d>>>0>l>>>0){break b}i=o[e+40>>2];m=o[e+36>>2];s=o[b+4>>2];t=o[b>>2];while(1){p=d<<2;j=h<<2;q=j+t|0;j=j+s|0;o[i+p>>2]=o[q>>2]-o[j>>2];o[m+p>>2]=o[j>>2]+o[q>>2]>>1;h=h+1|0;if(h>>>0>=c>>>0){break b}d=d+1|0;if(d>>>0<=l>>>0){continue}break}break b}h=h+g|0;e=o[a+4>>2]}d=g+o[e+7052>>2]|0;o[e+7052>>2]=d;if(d>>>0>l>>>0){e=0;if(!Oa(a,0,0)){break a}if(k){e=o[a+4>>2];d=0;while(1){g=o[(e+(d<<2)|0)+4>>2];o[g>>2]=o[g+n>>2];d=d+1|0;if((k|0)!=(d|0)){continue}break}}e=o[a+4>>2];f=o[a>>2];if(o[f+16>>2]){d=o[e+36>>2];o[d>>2]=o[d+n>>2];d=o[e+40>>2];o[d>>2]=o[d+n>>2]}o[e+7052>>2]=1}if(h>>>0<c>>>0){continue}break}e=1}return e|0}function Yb(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;i=1;a:{if(!c){break a}l=d+1|0;m=-1<<d;n=-1>>>31-d|0;while(1){g=o[b>>2];k=g<<1^g>>31;g=k>>>d|0;e=l+g|0;b:{c:{f=o[a+16>>2];if(!f){break c}h=e+f|0;if(h>>>0>31){break c}o[a+16>>2]=h;o[a+4>>2]=(k|m)&n|o[a+4>>2]<<e;break b}j=o[a+8>>2];h=o[a+12>>2];d:{if(j>>>0>(h+(g+f|0)|0)+1>>>0){break d}e=h+((e+f|0)+31>>>5|0)|0;if(e>>>0<=j>>>0){break d}h=o[a>>2];i=e;e=e-j&1023;f=i+(e?1024-e|0:0)|0;e:{if(f){i=0;if((f|0)!=(f&1073741823)){break a}j=ea(h,f<<2);if(j){break e}X(h);return 0}j=ea(h,0);i=0;if(!j){break a}}o[a+8>>2]=f;o[a>>2]=j}f:{if(!g){break f}e=o[a+16>>2];if(e){f=o[a+4>>2];h=32-e|0;if(g>>>0<h>>>0){o[a+16>>2]=e+g;o[a+4>>2]=f<<g;break f}e=f<<h;o[a+4>>2]=e;f=o[a+12>>2];o[a+12>>2]=f+1;o[o[a>>2]+(f<<2)>>2]=e<<8&16711680|e<<24|(e>>>8&65280|e>>>24);o[a+16>>2]=0;g=g-h|0}if(g>>>0>=32){e=o[a>>2];while(1){f=o[a+12>>2];o[a+12>>2]=f+1;o[e+(f<<2)>>2]=0;g=g+ -32|0;if(g>>>0>31){continue}break}}if(!g){break f}o[a+16>>2]=g;o[a+4>>2]=0}g=(k|m)&n;e=o[a+4>>2];h=o[a+16>>2];f=32-h|0;if(l>>>0<f>>>0){o[a+16>>2]=h+l;o[a+4>>2]=g|e<<l;break b}h=l-f|0;o[a+16>>2]=h;k=o[a+12>>2];o[a+12>>2]=k+1;e=e<<f|g>>>h;o[o[a>>2]+(k<<2)>>2]=e<<24|e<<8&16711680|(e>>>8&65280|e>>>24);o[a+4>>2]=g}b=b+4|0;c=c+ -1|0;if(c){continue}break}i=1}return i}function yc(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;g=-1;a:{b:{if(!a){break b}h=o[a>>2];if(!h){break b}if(!b){return 0}while(1){j=o[((f<<3)+b|0)+4>>2];if((j|0)<0|(k|0)>(2147483647-j|0)){break b}k=k+j|0;f=f+1|0;if((f|0)!=1){continue}break}j=(k|0)/255|0;f=o[a+12>>2];if(f){i=o[a+8>>2]-f|0;o[a+8>>2]=i;if(i){pa(h,f+h|0,i)}o[a+12>>2]=0}f=o[a+4>>2];if((f-k|0)<=o[a+8>>2]){if((f|0)>(2147483647-k|0)){break a}f=f+k|0;f=(f|0)<2147482623?f+1024|0:f;h=ea(o[a>>2],f);if(!h){break a}o[a>>2]=h;o[a+4>>2]=f}l=j+1|0;if(Hb(a,l)){break b}g=o[a+8>>2];f=0;while(1){i=o[a>>2]+g|0;g=(f<<3)+b|0;ca(i,o[g>>2],o[g+4>>2]);g=o[a+8>>2]+o[g+4>>2]|0;o[a+8>>2]=g;f=f+1|0;if((f|0)!=1){continue}break}h=o[a+28>>2];i=o[a+16>>2];m=i;c:{if((k|0)<=254){g=o[a+20>>2];b=0;break c}g=o[a+20>>2];f=0;while(1){b=f+h|0;o[i+(b<<2)>>2]=255;n=o[a+356>>2];b=(b<<3)+g|0;o[b>>2]=o[a+352>>2];o[b+4>>2]=n;f=f+1|0;if((j|0)!=(f|0)){continue}break}b=j}b=b+h|0;o[m+(b<<2)>>2]=k-u(j,255);b=(b<<3)+g|0;o[b>>2]=d;o[b+4>>2]=e;o[a+352>>2]=d;o[a+356>>2]=e;b=i+(h<<2)|0;o[b>>2]=o[b>>2]|256;o[a+28>>2]=h+l;d=o[a+348>>2];e=o[a+344>>2]+1|0;if(e>>>0<1){d=d+1|0}o[a+344>>2]=e;o[a+348>>2]=d;g=0;if(!c){break b}o[a+328>>2]=1}return g}b=o[a>>2];if(b){X(b)}b=o[a+16>>2];if(b){X(b)}b=o[a+20>>2];if(b){X(b)}fa(a,360);return-1}function lb(a){var b=0,c=0,d=0,e=0,f=0;a:{b:{c:{b=o[a+4>>2];d:{if(b>>>0<r[a+104>>2]){o[a+4>>2]=b+1;b=p[b|0];break d}b=ga(a)}switch(b+ -43|0){case 0:case 2:break b;default:break c}}c=b+ -48|0;break a}f=(b|0)==45;d=o[a+4>>2];e:{if(d>>>0<r[a+104>>2]){o[a+4>>2]=d+1;b=p[d|0];break e}b=ga(a)}c=b+ -48|0;if(!(c>>>0<10|!o[a+104>>2])){o[a+4>>2]=o[a+4>>2]+ -1}}f:{if(c>>>0<10){c=0;while(1){d=u(c,10)+b|0;b=o[a+4>>2];g:{if(b>>>0<r[a+104>>2]){o[a+4>>2]=b+1;b=p[b|0];break g}b=ga(a)}e=b+ -48|0;c=d+ -48|0;if((c|0)<214748364?e>>>0<=9:0){continue}break}d=c;c=c>>31;h:{if(e>>>0>=10){break h}while(1){e=b;b=Ee(d,c,10,0);c=e+b|0;d=Q;d=c>>>0<b>>>0?d+1|0:d;e=c;b=o[a+4>>2];i:{if(b>>>0<r[a+104>>2]){o[a+4>>2]=b+1;b=p[b|0];break i}b=ga(a)}c=d+ -1|0;d=e+ -48|0;if(d>>>0<4294967248){c=c+1|0}e=b+ -48|0;if(e>>>0>9){break h}if((c|0)<21474836?1:(c|0)<=21474836?d>>>0>=2061584302?0:1:0){continue}break}}if(e>>>0<10){while(1){b=o[a+4>>2];j:{if(b>>>0<r[a+104>>2]){o[a+4>>2]=b+1;b=p[b|0];break j}b=ga(a)}if(b+ -48>>>0<10){continue}break}}if(o[a+104>>2]){o[a+4>>2]=o[a+4>>2]+ -1}a=d;d=f?0-a|0:a;c=f?0-(c+(0<a>>>0)|0)|0:c;break f}d=0;c=-2147483648;if(!o[a+104>>2]){break f}o[a+4>>2]=o[a+4>>2]+ -1;Q=-2147483648;return 0}Q=c;return d}function nb(a,b,c,d,e,f){var g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;g=N-16|0;N=g;h=o[o[a+4>>2]+1136>>2];l=o[(f?5644:5640)>>2];m=o[(f?5632:5628)>>2];a:{b:{if(ab(d,c>>>0>6?c:6)){i=c?h>>>c|0:h-b|0;n=o[1409];if(!c){break b}f=0;while(1){if(!Y(o[o[a+4>>2]+56>>2],g+12|0,m)){h=0;break a}j=k<<2;o[j+o[d>>2]>>2]=o[g+12>>2];c:{if(r[g+12>>2]<l>>>0){h=0;o[j+o[d+4>>2]>>2]=0;j=i-(k?0:b)|0;if(!Zb(o[o[a+4>>2]+56>>2],(f<<2)+e|0,j,o[g+12>>2])){break a}f=f+j|0;break c}if(!Y(o[o[a+4>>2]+56>>2],g+12|0,n)){h=0;break a}o[j+o[d+4>>2]>>2]=o[g+12>>2];h=k?0:b;if(h>>>0>=i>>>0){break c}while(1){if(!xa(o[o[a+4>>2]+56>>2],g+8|0,o[g+12>>2])){h=0;break a}o[(f<<2)+e>>2]=o[g+8>>2];f=f+1|0;h=h+1|0;if((i|0)!=(h|0)){continue}break}}h=1;k=k+1|0;if(!(k>>>c)){continue}break}break a}o[o[a>>2]>>2]=8;h=0;break a}h=0;if(!Y(o[o[a+4>>2]+56>>2],g+12|0,m)){break a}o[o[d>>2]>>2]=o[g+12>>2];d:{if(r[g+12>>2]>=l>>>0){if(!Y(o[o[a+4>>2]+56>>2],g+12|0,n)){break a}o[o[d+4>>2]>>2]=o[g+12>>2];if(!i){break d}f=0;while(1){if(!xa(o[o[a+4>>2]+56>>2],g+8|0,o[g+12>>2])){h=0;break a}o[(f<<2)+e>>2]=o[g+8>>2];f=f+1|0;h=h+1|0;if((i|0)!=(h|0)){continue}break}break d}o[o[d+4>>2]>>2]=0;if(!Zb(o[o[a+4>>2]+56>>2],e,i,o[g+12>>2])){break a}}h=1}N=g+16|0;return h}function Pb(){var a=0,b=0,c=0,d=0,e=0;d=qa(1,8);if(d){c=qa(1,504);o[d>>2]=c;if(c){a=qa(1,6160);o[d+4>>2]=a;if(a){e=qa(1,44);o[a+56>>2]=e;if(e){o[a+1128>>2]=16;b=da(o[1364]<<1&-16);o[a+1120>>2]=b;if(b){o[a+252>>2]=0;o[a+220>>2]=0;o[a+224>>2]=0;b=a+3616|0;o[b>>2]=0;o[b+4>>2]=0;b=a+3608|0;o[b>>2]=0;o[b+4>>2]=0;b=a+3600|0;o[b>>2]=0;o[b+4>>2]=0;b=a+3592|0;o[b>>2]=0;o[b+4>>2]=0;o[a+60>>2]=0;o[a+64>>2]=0;o[a+68>>2]=0;o[a+72>>2]=0;o[a+76>>2]=0;o[a+80>>2]=0;o[a+84>>2]=0;o[a+88>>2]=0;o[a+92>>2]=0;o[a+96>>2]=0;o[a+100>>2]=0;o[a+104>>2]=0;o[a+108>>2]=0;o[a+112>>2]=0;o[a+116>>2]=0;o[a+120>>2]=0;o[a+132>>2]=0;o[a+124>>2]=0;o[a+128>>2]=0;o[a+144>>2]=0;o[a+136>>2]=0;o[a+140>>2]=0;o[a+156>>2]=0;o[a+148>>2]=0;o[a+152>>2]=0;o[a+168>>2]=0;o[a+160>>2]=0;o[a+164>>2]=0;o[a+180>>2]=0;o[a+172>>2]=0;o[a+176>>2]=0;o[a+192>>2]=0;o[a+184>>2]=0;o[a+188>>2]=0;o[a+204>>2]=0;o[a+196>>2]=0;o[a+200>>2]=0;o[a+216>>2]=0;o[a+208>>2]=0;o[a+212>>2]=0;o[a+48>>2]=0;o[a+52>>2]=0;fa(a+608|0,512);o[a+1124>>2]=0;o[a+608>>2]=1;o[a+32>>2]=0;o[a+24>>2]=0;o[a+28>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0;o[a>>2]=0;o[a+4>>2]=0;o[c+28>>2]=0;o[c+32>>2]=1;o[c>>2]=9;return d|0}gb(e)}X(a)}X(c)}X(d)}return 0}function le(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;a:{b:{c:{d:{e:{f:{g:{if(b){b=o[a+140>>2];d=b;c=o[a+136>>2];if(!b&c>>>0<=88199|b>>>0<0){a=0;break a}if(Ge(c,d)|Q){a=0;break a}d=o[a+148>>2];if(!d){break b}if(p[(o[a+152>>2]+(d<<5)|0)+ -24|0]==170){break g}a=0;break a}e=o[a+148>>2];if(!e){break b}g=e+ -1|0;h=o[a+152>>2];b=0;while(1){d=h+(b<<5)|0;if(!p[d+8|0]){break c}c=p[d+23|0];h:{i:{if(b>>>0<g>>>0){if(!c){break d}if(p[o[d+24>>2]+8|0]>1){break e}break i}if(!c){break h}}a=0;while(1){if(a){f=o[d+24>>2]+(a<<4)|0;if((p[f+ -8|0]+1|0)!=p[f+8|0]){break f}}a=a+1|0;if(a>>>0<c>>>0){continue}break}}a=1;b=b+1|0;if((e|0)!=(b|0)){continue}break}break a}g=d+ -1|0;h=o[a+152>>2];b=0;while(1){a=h+(b<<5)|0;c=p[a+8|0];if(!c){break c}if(!((c|0)==170|c>>>0<100)){a=0;break a}if(Ge(o[a>>2],o[a+4>>2])|Q){a=0;break a}c=p[a+23|0];j:{k:{if(b>>>0<g>>>0){if(!c){break d}if(p[o[a+24>>2]+8|0]<2){break k}break e}if(!c){break j}}f=o[a+24>>2];a=0;while(1){e=f+(a<<4)|0;if(Ge(o[e>>2],o[e+4>>2])|Q){a=0;break a}if(p[e+8|0]!=(p[e+ -8|0]+1|0)?a:0){break f}a=a+1|0;if(a>>>0<c>>>0){continue}break}}a=1;b=b+1|0;if((d|0)!=(b|0)){continue}break}break a}a=0;break a}a=0;break a}a=0;break a}a=0;break a}a=0}return a}function $c(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=v(0),m=0,n=0,p=0,q=v(0);while(1){l=c;c=v(.05000000074505806);if(l<=v(0)){continue}c=v(.949999988079071);if(l>=v(1)){continue}break}c=v(b|0);d=v(c*d);a:{if(v(w(d))<v(2147483648)){g=~~d;break a}g=-2147483648}d=v(l*v(.5));c=v(c*e);b:{if(v(w(c))<v(2147483648)){k=~~c;break b}k=-2147483648}c=v(d*v(k-g|0));c:{if(v(w(c))<v(2147483648)){h=~~c;break c}h=-2147483648}if(!((g|0)<1|(b|0)<1)){f=g+ -1|0;i=b+ -1|0;i=f>>>0<i>>>0?f:i;fa(a,(i<<2)+4|0);f=i+1|0;while(1){n=(j|0)==(i|0);j=j+1|0;if(!n){continue}break}}g=g+h|0;d:{if((f|0)>=(g|0)|(f|0)>=(b|0)){break d}m=+(h|0);j=1;while(1){p=(f<<2)+a|0,q=v(.5-ba(+(j|0)*3.141592653589793/m)*.5),s[p>>2]=q;f=f+1|0;if((f|0)>=(g|0)){break d}j=j+1|0;if((f|0)<(b|0)){continue}break}}g=k-h|0;e:{if((f|0)>=(g|0)|(f|0)>=(b|0)){break e}while(1){o[(f<<2)+a>>2]=1065353216;f=f+1|0;if((f|0)>=(g|0)){break e}if((f|0)<(b|0)){continue}break}}f:{if((f|0)>=(k|0)|(f|0)>=(b|0)){break f}m=+(h|0);while(1){p=(f<<2)+a|0,q=v(.5-ba(+(h|0)*3.141592653589793/m)*.5),s[p>>2]=q;f=f+1|0;if((f|0)>=(k|0)){break f}h=h+ -1|0;if((f|0)<(b|0)){continue}break}}if((f|0)<(b|0)){fa((f<<2)+a|0,b-f<<2)}}function pe(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=v(0),f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0,t=0,u=0,w=v(0);if(b){d=o[a+ -4>>2];i=o[a+ -8>>2];m=d-i|0;f=o[a+ -12>>2];j=m+(f-i|0)|0;t=j+(((f<<1)-i|0)-o[a+ -16>>2]|0)|0;while(1){i=o[(q<<2)+a>>2];f=i>>31;p=(f^f+i)+p|0;f=i-d|0;l=f>>31;n=(l^f+l)+n|0;l=f-m|0;d=l>>31;k=(d^d+l)+k|0;j=l-j|0;d=j>>31;g=(d^d+j)+g|0;m=j-t|0;d=m>>31;h=(d^d+m)+h|0;d=i;m=f;t=j;j=l;q=q+1|0;if((q|0)!=(b|0)){continue}break}}a=n>>>0<k>>>0?n:k;a=a>>>0<g>>>0?a:g;a:{if(p>>>0<(a>>>0<h>>>0?a:h)>>>0){break a}r=1;a=k>>>0<g>>>0?k:g;if(n>>>0<(a>>>0<h>>>0?a:h)>>>0){break a}a=g>>>0<h>>>0;r=k>>>0<(a?g:h)>>>0?2:a?3:4}a=c;if(p){e=v(la(+(p>>>0)*.6931471805599453/+(b>>>0))/.6931471805599453)}else{e=v(0)}s[a>>2]=e;a=c;if(n){e=v(la(+(n>>>0)*.6931471805599453/+(b>>>0))/.6931471805599453)}else{e=v(0)}s[a+4>>2]=e;a=c;if(k){e=v(la(+(k>>>0)*.6931471805599453/+(b>>>0))/.6931471805599453)}else{e=v(0)}s[a+8>>2]=e;a=c;if(g){e=v(la(+(g>>>0)*.6931471805599453/+(b>>>0))/.6931471805599453)}else{e=v(0)}s[a+12>>2]=e;if(!h){s[c+16>>2]=0;return r|0}u=c,w=v(la(+(h>>>0)*.6931471805599453/+(b>>>0))/.6931471805599453),s[u+16>>2]=w;return r|0}function Gc(a,b,c,d){var e=0,h=0,i=0,j=0,k=0,l=0,m=0;i=N-32|0;N=i;e=d&2147483647;k=e;e=e+ -1006698496|0;j=c;h=c;if(c>>>0<0){e=e+1|0}l=h;h=e;e=k+ -1140785152|0;m=j;if(j>>>0<0){e=e+1|0}a:{if((e|0)==(h|0)&l>>>0<m>>>0|h>>>0<e>>>0){e=d<<4|c>>>28;c=c<<4|b>>>28;b=b&268435455;j=b;if((b|0)==134217728&a>>>0>=1|b>>>0>134217728){e=e+1073741824|0;a=c+1|0;if(a>>>0<1){e=e+1|0}h=a;break a}h=c;e=e-((c>>>0<0)+ -1073741824|0)|0;if(a|j^134217728){break a}a=h+(h&1)|0;if(a>>>0<h>>>0){e=e+1|0}h=a;break a}if(!(!j&(k|0)==2147418112?!(a|b):(k|0)==2147418112&j>>>0<0|k>>>0<2147418112)){e=d<<4|c>>>28;h=c<<4|b>>>28;e=e&524287|2146959360;break a}h=0;e=2146435072;if(k>>>0>1140785151){break a}e=0;j=k>>>16|0;if(j>>>0<15249){break a}e=d&65535|65536;ia(i+16|0,a,b,c,e,j+ -15233|0);Ja(i,a,b,c,e,15361-j|0);c=o[i+4>>2];a=o[i+8>>2];e=o[i+12>>2]<<4|a>>>28;h=a<<4|c>>>28;a=c&268435455;c=a;b=o[i>>2]|((o[i+16>>2]|o[i+24>>2])!=0|(o[i+20>>2]|o[i+28>>2])!=0);if((a|0)==134217728&b>>>0>=1|a>>>0>134217728){a=h+1|0;if(a>>>0<1){e=e+1|0}h=a;break a}if(b|c^134217728){break a}a=h+(h&1)|0;if(a>>>0<h>>>0){e=e+1|0}h=a}N=i+32|0;f(0,h|0);f(1,d&-2147483648|e);return+g()}function Va(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;c=N-16|0;N=c;f=1;a:{while(1){b=0;b:{while(1){g=o[a+4>>2];c:{if(o[g+3520>>2]){e=p[g+3590|0];o[c+8>>2]=e;o[g+3520>>2]=0;break c}if(!Y(o[g+56>>2],c+8|0,8)){d=0;break a}e=o[c+8>>2]}if(p[d+5409|0]==(e|0)){d=d+1|0;b=1;break b}d=0;if((b|0)==3){break a}if(p[b+7552|0]==(e|0)){b=b+1|0;if((b|0)!=3){continue}if(!Y(o[o[a+4>>2]+56>>2],c+12|0,24)){break a}if(!Y(o[o[a+4>>2]+56>>2],c+12|0,8)){break a}e=o[c+12>>2];if(!Y(o[o[a+4>>2]+56>>2],c+12|0,8)){break a}g=o[c+12>>2];if(!Y(o[o[a+4>>2]+56>>2],c+12|0,8)){break a}h=o[c+12>>2];if(!Y(o[o[a+4>>2]+56>>2],c+12|0,8)){break a}if(Ea(o[o[a+4>>2]+56>>2],o[c+12>>2]&127|(h<<7&16256|(g&127|e<<7&16256)<<14))){continue}break a}break}d:{if((e|0)!=255){break d}m[o[a+4>>2]+3588|0]=255;if(!Y(o[o[a+4>>2]+56>>2],c+8|0,8)){break a}b=o[c+8>>2];if((b|0)==255){b=o[a+4>>2];o[b+3520>>2]=1;m[b+3590|0]=255;break d}if((b&-2)!=248){break d}m[o[a+4>>2]+3589|0]=b;o[o[a>>2]>>2]=3;d=1;break a}b=0;if(!f){break b}f=o[a+4>>2];b=0;if(o[f+3632>>2]){break b}l[o[f+32>>2]](a,0,o[f+48>>2]);b=0}f=b;if(d>>>0<4){continue}break}d=1;o[o[a>>2]>>2]=1}N=c+16|0;return d}function ca(a,b,c){var d=0,e=0,f=0;if(c>>>0>=512){K(a|0,b|0,c|0)|0;return a}e=a+c|0;a:{if(!((a^b)&3)){b:{if((c|0)<1){c=a;break b}if(!(a&3)){c=a;break b}c=a;while(1){m[c|0]=p[b|0];b=b+1|0;c=c+1|0;if(c>>>0>=e>>>0){break b}if(c&3){continue}break}}d=e&-4;c:{if(d>>>0<64){break c}f=d+ -64|0;if(c>>>0>f>>>0){break c}while(1){o[c>>2]=o[b>>2];o[c+4>>2]=o[b+4>>2];o[c+8>>2]=o[b+8>>2];o[c+12>>2]=o[b+12>>2];o[c+16>>2]=o[b+16>>2];o[c+20>>2]=o[b+20>>2];o[c+24>>2]=o[b+24>>2];o[c+28>>2]=o[b+28>>2];o[c+32>>2]=o[b+32>>2];o[c+36>>2]=o[b+36>>2];o[c+40>>2]=o[b+40>>2];o[c+44>>2]=o[b+44>>2];o[c+48>>2]=o[b+48>>2];o[c+52>>2]=o[b+52>>2];o[c+56>>2]=o[b+56>>2];o[c+60>>2]=o[b+60>>2];b=b- -64|0;c=c- -64|0;if(c>>>0<=f>>>0){continue}break}}if(c>>>0>=d>>>0){break a}while(1){o[c>>2]=o[b>>2];b=b+4|0;c=c+4|0;if(c>>>0<d>>>0){continue}break}break a}if(e>>>0<4){c=a;break a}d=e+ -4|0;if(d>>>0<a>>>0){c=a;break a}c=a;while(1){m[c|0]=p[b|0];m[c+1|0]=p[b+1|0];m[c+2|0]=p[b+2|0];m[c+3|0]=p[b+3|0];b=b+4|0;c=c+4|0;if(c>>>0<=d>>>0){continue}break}}if(c>>>0<e>>>0){while(1){m[c|0]=p[b|0];b=b+1|0;c=c+1|0;if((e|0)!=(c|0)){continue}break}}return a}function Ia(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;g=N-16|0;N=g;f=o[a+16>>2];a:{if(!f){c=o[a+8>>2];break a}b=o[a+28>>2];b:{if(f>>>0<=b>>>0){d=b;break b}c=o[a+32>>2];if(!c){d=b;break b}d=b+1|0;o[a+28>>2]=d;e=o[a+24>>2];if(c>>>0<=31){b=o[o[a>>2]+(b<<2)>>2];while(1){e=q[((b>>>24-c&255^e>>>8)<<1)+1280>>1]^e<<8&65280;i=c>>>0<24;h=c+8|0;c=h;if(i){continue}break}o[a+32>>2]=h}o[a+32>>2]=0;o[a+24>>2]=e}b=Wb(o[a>>2]+(d<<2)|0,f-d|0,q[a+24>>1]);o[a+28>>2]=0;o[a+24>>2]=b;d=o[a>>2];b=o[a+16>>2];pa(d,d+(b<<2)|0,(o[a+8>>2]-b|0)+(o[a+12>>2]!=0)<<2);o[a+16>>2]=0;c=o[a+8>>2]-b|0;o[a+8>>2]=c}b=o[a+12>>2];d=(o[a+4>>2]-c<<2)-b|0;o[g+12>>2]=d;e=0;c:{if(!d){break c}d=o[a>>2]+(c<<2)|0;c=d+b|0;if(b){b=o[d>>2];o[d>>2]=b<<24|b<<8&16711680|(b>>>8&65280|b>>>24)}if(!l[o[a+36>>2]](c,g+12|0,o[a+40>>2])){break c}d=a;i=o[g+12>>2];c=o[a+12>>2];e=o[a+8>>2];b=e<<2;f=(i+(c+b|0)|0)+3>>>2|0;if(e>>>0<f>>>0){c=o[a>>2];while(1){h=c+(e<<2)|0;b=o[h>>2];o[h>>2]=b<<8&16711680|b<<24|(b>>>8&65280|b>>>24);e=e+1|0;if((f|0)!=(e|0)){continue}break}c=o[a+12>>2];b=o[a+8>>2]<<2}b=(c+i|0)+b|0;o[d+12>>2]=b&3;o[a+8>>2]=b>>>2;e=1}N=g+16|0;return e}function nc(a,b){var c=0,d=0,e=0,f=0,g=0;c=N-208|0;N=c;o[c+8>>2]=1;o[c+12>>2]=0;a:{g=u(b,24);if(!g){break a}o[c+16>>2]=24;o[c+20>>2]=24;b=24;f=24;e=2;while(1){d=b;b=(f+24|0)+b|0;o[(c+16|0)+(e<<2)>>2]=b;e=e+1|0;f=d;if(b>>>0<g>>>0){continue}break}d=(a+g|0)+ -24|0;b:{if(d>>>0<=a>>>0){e=1;b=1;break b}e=1;b=1;while(1){c:{if((e&3)==3){Sa(a,b,c+16|0);La(c+8|0,2);b=b+2|0;break c}f=b+ -1|0;d:{if(r[(c+16|0)+(f<<2)>>2]>=d-a>>>0){Ka(a,c+8|0,b,0,c+16|0);break d}Sa(a,b,c+16|0)}if((b|0)==1){Ma(c+8|0,1);b=0;break c}Ma(c+8|0,f);b=1}e=o[c+8>>2]|1;o[c+8>>2]=e;a=a+24|0;if(a>>>0<d>>>0){continue}break}}Ka(a,c+8|0,b,0,c+16|0);while(1){e:{f:{g:{if(!((b|0)!=1|(e|0)!=1)){if(o[c+12>>2]){break g}break a}if((b|0)>1){break f}}f=c+8|0;d=De(o[c+8>>2]+ -1|0);if(!d){d=De(o[c+12>>2]);d=d?d+32|0:0}La(f,d);e=o[c+8>>2];b=b+d|0;break e}Ma(c+8|0,2);o[c+8>>2]=o[c+8>>2]^7;La(c+8|0,1);f=a+ -24|0;d=b+ -2|0;Ka(f-o[(c+16|0)+(d<<2)>>2]|0,c+8|0,b+ -1|0,1,c+16|0);Ma(c+8|0,1);e=o[c+8>>2]|1;o[c+8>>2]=e;Ka(f,c+8|0,d,1,c+16|0);b=d}a=a+ -24|0;continue}}N=c+208|0}function ec(a){var b=0,c=0,d=0,e=0;c=1;a:{b=p[a|0];b:{if(!(b&128)){break b}if(!((b&224)!=192|(p[a+1|0]&192)!=128)){return((b&254)!=192)<<1}c:{if((b&240)!=224){break c}d=p[a+1|0];if((d&192)!=128){break c}e=p[a+2|0];if((e&192)!=128){break c}c=0;if((d&224)==128?(b|0)==224:0){break b}d:{e:{switch(b+ -237|0){case 0:if((d&224)!=160){break d}break b;case 2:break e;default:break d}}if((d|0)!=191){break d}if((e&254)==190){break b}}return 3}f:{if((b&248)!=240){break f}c=p[a+1|0];if((c&192)!=128|(p[a+2|0]&192)!=128){break f}if((p[a+3|0]&192)==128){break a}}g:{if((b&252)!=248){break g}c=p[a+1|0];if((c&192)!=128|(p[a+2|0]&192)!=128|((p[a+3|0]&192)!=128|(p[a+4|0]&192)!=128)){break g}return(b|0)==248?(c&248)==128?0:5:5}c=0;if((b&254)!=252){break b}d=p[a+1|0];if((d&192)!=128|(p[a+2|0]&192)!=128|((p[a+3|0]&192)!=128|(p[a+4|0]&192)!=128)){break b}if((p[a+5|0]&192)!=128){break b}c=(b|0)==252?(d&252)==128?0:6:6}return c}return(b|0)==240?((c&240)!=128)<<2:4}function oc(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;var h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0;l=1<<f;p=l>>>0>1?l:1;i=0-d|0;m=c+d>>>f|0;j=m-d|0;a:{if(g+4>>>0<(x(m)^-32)+33>>>0){g=0;while(1){d=0;i=i+m|0;if(h>>>0<i>>>0){while(1){c=o[(h<<2)+a>>2];k=c>>31;d=(k^c+k)+d|0;h=h+1|0;if(h>>>0<i>>>0){continue}break}h=j}c=(g<<3)+b|0;o[c>>2]=d;o[c+4>>2]=0;j=j+m|0;g=g+1|0;if((p|0)!=(g|0)){continue}break}break a}c=0;while(1){n=0;d=0;i=i+m|0;if(h>>>0<i>>>0){while(1){g=o[(h<<2)+a>>2];k=g>>31;k=k^g+k;g=k+n|0;if(g>>>0<k>>>0){d=d+1|0}n=g;h=h+1|0;if(h>>>0<i>>>0){continue}break}h=j}g=(c<<3)+b|0;o[g>>2]=n;o[g+4>>2]=d;j=j+m|0;c=c+1|0;if((p|0)!=(c|0)){continue}break}}if((f|0)>(e|0)){h=0;a=l;while(1){f=f+ -1|0;i=0;a=a>>>1|0;if(a){while(1){d=(h<<3)+b|0;c=o[d+8>>2];j=o[d+12>>2]+o[d+4>>2]|0;d=o[d>>2];c=d+c|0;if(c>>>0<d>>>0){j=j+1|0}g=(l<<3)+b|0;o[g>>2]=c;o[g+4>>2]=j;h=h+2|0;l=l+1|0;i=i+1|0;if((i|0)!=(a|0)){continue}break}}if((f|0)>(e|0)){continue}break}}}function Ce(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0;a:{b:{c:{d:{e:{f:{g:{h:{i:{d=b;if(d){e=c;if(!e){break i}break h}b=a;a=(a>>>0)/(c>>>0)|0;O=b-u(a,c)|0;P=0;Q=0;return a}if(!a){break g}break f}g=e+ -1|0;if(!(g&e)){break e}g=(x(e)+33|0)-x(d)|0;h=0-g|0;break c}O=0;a=(d>>>0)/0|0;P=d-u(a,0)|0;Q=0;return a}d=32-x(d)|0;if(d>>>0<31){break d}break b}O=a&g;P=0;if((e|0)==1){break a}d=De(e);c=d&31;if(32<=(d&63)>>>0){e=0;a=b>>>c|0}else{e=b>>>c|0;a=((1<<c)-1&b)<<32-c|a>>>c}Q=e;return a}g=d+1|0;h=63-d|0}d=b;e=g&63;f=e&31;if(32<=e>>>0){e=0;f=d>>>f|0}else{e=d>>>f|0;f=((1<<f)-1&d)<<32-f|a>>>f}h=h&63;d=h&31;if(32<=h>>>0){b=a<<d;a=0}else{b=(1<<d)-1&a>>>32-d|b<<d;a=a<<d}if(g){h=-1;d=c+ -1|0;if((d|0)!=-1){h=0}while(1){i=f<<1|b>>>31;j=i;e=e<<1|f>>>31;i=h-(e+(d>>>0<i>>>0)|0)>>31;k=c&i;f=j-k|0;e=e-(j>>>0<k>>>0)|0;b=b<<1|a>>>31;a=l|a<<1;i=i&1;l=i;g=g+ -1|0;if(g){continue}break}}O=f;P=e;Q=b<<1|a>>>31;return i|a<<1}O=a;P=b;a=0;b=0}Q=b;return a}function ac(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0;h=o[b>>2];f=o[d+4>>2];a=o[b+8>>2];if(a){e=h<<2;while(1){i=g<<2;j=o[i+c>>2];k=o[(f+i|0)+11764>>2];if(Pa(j,k,e)){e=0;a:{if(h){a=0;while(1){c=a<<2;i=o[c+j>>2];c=o[c+k>>2];if((i|0)!=(c|0)){e=a;break a}a=a+1|0;if((h|0)!=(a|0)){continue}break}}c=0;i=0}j=o[b+28>>2];a=e;l=a+o[b+24>>2]|0;if(l>>>0<a>>>0){j=j+1|0}k=f+11816|0;o[k>>2]=l;o[k+4>>2]=j;a=o[b+28>>2];b=o[b+24>>2];o[f+11840>>2]=i;o[f+11836>>2]=c;o[f+11832>>2]=e;o[f+11828>>2]=g;m=f+11824|0,n=Fe(b,a,h),o[m>>2]=n;o[o[d>>2]>>2]=4;return 1}g=g+1|0;if((a|0)!=(g|0)){continue}break}c=f+11800|0;b=o[c>>2]-h|0;o[c>>2]=b;b:{if(!a){break b}c=o[f+11764>>2];e=c;c=h<<2;pa(e,e+c|0,b<<2);g=1;if((a|0)==1){break b}while(1){b=o[d+4>>2];e=o[(b+(g<<2)|0)+11764>>2];pa(e,c+e|0,o[b+11800>>2]<<2);g=g+1|0;if((a|0)!=(g|0)){continue}break}}return 0}a=f+11800|0;o[a>>2]=o[a>>2]-h;return 0}function re(a,b,c){if((c|0)==15|c>>>0<15){if(!c&b>>>0<=127|c>>>0<0){return Z(a,b,8)}if(!c&b>>>0<=2047|c>>>0<0){return Z(a,(c&63)<<26|b>>>6|192,8)&Z(a,b&63|128,8)&1}if(!c&b>>>0<=65535|c>>>0<0){return Z(a,(c&4095)<<20|b>>>12|224,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}if(!c&b>>>0<=2097151|c>>>0<0){return Z(a,(c&262143)<<14|b>>>18|240,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}if(!c&b>>>0<=67108863|c>>>0<0){return Z(a,(c&16777215)<<8|b>>>24|248,8)&Z(a,b>>>18&63|128,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}if(!c&b>>>0<=2147483647|c>>>0<0){return Z(a,(c&1073741823)<<2|b>>>30|252,8)&Z(a,b>>>24&63|128,8)&Z(a,b>>>18&63|128,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}a=Z(a,254,8)&Z(a,(c&1073741823)<<2|b>>>30|128,8)&Z(a,b>>>24&63|128,8)&Z(a,b>>>18&63|128,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}else{a=0}return a}function yb(a){var b=0,c=0,d=0,e=0,f=0;e=N-16|0;N=e;a:{b:{c:{c=o[a+4>>2];if(!o[c+248>>2]){break c}d=o[c+308>>2];b=d;f=o[c+304>>2];if(!(b|f)){break c}d=o[c+244>>2];if((b|0)==(d|0)&r[c+240>>2]<f>>>0|d>>>0<b>>>0){break c}o[o[a>>2]>>2]=4;break b}d:{if(!(p[o[c+56>>2]+20|0]&7)){break d}c=o[o[a+4>>2]+56>>2];if(Y(c,e+12|0,8-(o[c+20>>2]&7)|0)){break d}b=0;break a}c=0;while(1){d=o[a+4>>2];e:{if(o[d+3520>>2]){b=p[d+3590|0];o[e+12>>2]=b;o[d+3520>>2]=0;break e}b=0;if(!Y(o[d+56>>2],e+12|0,8)){break a}b=o[e+12>>2]}f:{if((b|0)!=255){break f}m[o[a+4>>2]+3588|0]=255;b=0;if(!Y(o[o[a+4>>2]+56>>2],e+12|0,8)){break a}b=o[e+12>>2];if((b|0)==255){b=o[a+4>>2];o[b+3520>>2]=1;m[b+3590|0]=255;break f}if((b&-2)!=248){break f}m[o[a+4>>2]+3589|0]=b;o[o[a>>2]>>2]=3;break b}b=c;c=1;if(b){continue}b=o[a+4>>2];if(o[b+3632>>2]){continue}l[o[b+32>>2]](a,0,o[b+48>>2]);continue}}b=1}N=e+16|0;return b}function Nb(a){a=a|0;var b=0,c=0,d=0;b=o[a+4>>2];a:{if(o[o[a>>2]>>2]==9?!o[b+3628>>2]:0){break a}o[b+3624>>2]=0;o[b+240>>2]=0;o[b+244>>2]=0;if(o[b>>2]){Wd(o[a>>2]+32|0);b=o[a+4>>2]}b=o[b+56>>2];o[b+8>>2]=0;o[b+12>>2]=0;o[b+16>>2]=0;o[b+20>>2]=0;c=o[a>>2];o[c>>2]=2;b=o[a+4>>2];if(o[b>>2]){Td(c+32|0);b=o[a+4>>2]}b:{if(!o[b+3628>>2]){c=0;if(o[b+52>>2]==o[1887]){break a}d=o[b+8>>2];if(!d){break b}if((l[d](a,0,0,o[b+48>>2])|0)==1){break a}b=o[a+4>>2];break b}o[b+3628>>2]=0}o[o[a>>2]>>2]=0;o[b+248>>2]=0;X(o[b+452>>2]);o[o[a+4>>2]+452>>2]=0;b=o[a+4>>2];o[b+252>>2]=0;o[b+3624>>2]=o[o[a>>2]+28>>2];o[b+228>>2]=0;o[b+232>>2]=0;b=b+3636|0;o[b+80>>2]=0;o[b+84>>2]=0;o[b+64>>2]=1732584193;o[b+68>>2]=-271733879;o[b+72>>2]=-1732584194;o[b+76>>2]=271733878;o[b+88>>2]=0;o[b+92>>2]=0;a=o[a+4>>2];o[a+6152>>2]=0;o[a+6136>>2]=0;o[a+6140>>2]=0;c=1}return c|0}function we(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;h=N-16|0;N=h;a:{if(!Y(a,h+12|0,8)){break a}e=o[h+12>>2];if(c){g=o[d>>2];o[d>>2]=g+1;m[c+g|0]=e}b:{c:{d:{e:{if(e&128){if(!(!(e&192)|e&32)){e=e&31;f=1;break e}if(!(!(e&224)|e&16)){e=e&15;f=2;break e}if(!(!(e&240)|e&8)){e=e&7;f=3;break e}if(!(!(e&248)|e&4)){e=e&3;f=4;break e}if(!(!(e&252)|e&2)){e=e&1;f=5;break e}f=1;if(!(!(e&254)|e&1)){f=6;e=0;break e}o[b>>2]=-1;o[b+4>>2]=-1;break a}g=0;break d}g=0;if(!c){while(1){if(!Y(a,h+12|0,8)){f=0;break a}c=o[h+12>>2];if((c&192)!=128){break c}c=c&63;g=g<<6|e>>>26;e=c|e<<6;f=f+ -1|0;if(f){continue}break d}}while(1){if(!Y(a,h+12|0,8)){f=0;break a}i=o[h+12>>2];j=o[d>>2];o[d>>2]=j+1;m[c+j|0]=i;if((i&192)!=128){break c}g=g<<6|e>>>26;e=i&63|e<<6;f=f+ -1|0;if(f){continue}break}}o[b>>2]=e;o[b+4>>2]=g;break b}o[b>>2]=-1;o[b+4>>2]=-1}f=1}N=h+16|0;return f}function Cc(a){var b=0,c=0,d=0,f=0,g=0,i=0,j=0,k=0;h(+a);d=e(1)|0;j=e(0)|0;g=d>>>31|0;a:{b:{c:{d:{f=a;e:{f:{c=d;d=c&2147483647;g:{if(d>>>0>=1082532651){c=c&2147483647;if((c|0)==2146435072&j>>>0>0|c>>>0>2146435072){return a}if(!!(a>709.782712893384)){return a*8.98846567431158e+307}if(!(a<-745.1332191019411)|a<-708.3964185322641^1){break g}break b}if(d>>>0<1071001155){break d}if(d>>>0<1072734898){break f}}a=a*1.4426950408889634+t[(g<<3)+10448>>3];if(w(a)<2147483648){c=~~a;break e}c=-2147483648;break e}c=(g^1)-g|0}b=+(c|0);a=f+b*-.6931471803691238;i=b*1.9082149292705877e-10;f=a-i;break c}if(d>>>0<=1043333120){break a}c=0;f=a}b=f;k=a;b=b*b;a=f-b*(b*(b*(b*(b*4.1381367970572385e-8+ -16533902205465252e-22)+6613756321437934e-20)+ -.0027777777777015593)+.16666666666666602);b=k+(f*a/(2-a)-i)+1;if(!c){break b}b=ua(b,c)}return b}return a+1}function me(a,b,c,d){var e=0,f=0,g=0,h=0,i=0;a:{b:{c:{switch(c|0){case 4:if((b|0)<1){break b}f=o[d+ -12>>2];g=o[d+ -4>>2];c=0;while(1){i=c<<2;h=i+d|0;e=o[h+ -8>>2];g=((o[a+i>>2]+u(e,-6)|0)-o[h+ -16>>2]|0)+(f+g<<2)|0;o[h>>2]=g;f=e;c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 3:if((b|0)<1){break b}e=o[d+ -12>>2];f=o[d+ -4>>2];c=0;while(1){g=c<<2;h=g+d|0;i=o[a+g>>2]+e|0;e=o[h+ -8>>2];f=i+u(f-e|0,3)|0;o[h>>2]=f;c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 2:if((b|0)<1){break b}e=o[d+ -4>>2];c=0;while(1){f=c<<2;g=f+d|0;e=(o[a+f>>2]+(e<<1)|0)-o[g+ -8>>2]|0;o[g>>2]=e;c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 0:break a;case 1:break c;default:break b}}if((b|0)<1){break b}e=o[d+ -4>>2];c=0;while(1){f=c<<2;e=o[f+a>>2]+e|0;o[d+f>>2]=e;c=c+1|0;if((c|0)!=(b|0)){continue}break}}return}ca(d,a,b<<2)}function $d(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=v(0);i=N-16|0;N=i;a:{if(!b){h=2;break a}f=c+ -1|0;c=0;while(1){m=+v(w(s[(c<<2)+a>>2]));g=g<m?m:g;c=c+1|0;if((c|0)!=(b|0)){continue}break}h=2;if(g<=0){break a}k=1<<f;n=k+ -1|0;l=0-k|0;xb(g,i+12|0);c=o[i+12>>2];o[i+12>>2]=c+ -1;f=f-c|0;o[e>>2]=f;b:{h=-1<<o[1413]+ -1;c=h^-1;if((f|0)>(c|0)){o[e>>2]=c;f=c;break b}if((f|0)>=(h|0)){break b}h=1;break a}h=0;if((f|0)>=0){if(!b){break a}g=0;c=0;while(1){j=c<<2;g=g+ +v(s[j+a>>2]*v(1<<f));f=ub(g);f=(f|0)<(k|0)?(f|0)<(l|0)?l:f:n;o[d+j>>2]=f;c=c+1|0;if((c|0)==(b|0)){break a}g=g- +(f|0);f=o[e>>2];continue}}if(b){c=0;p=v(1<<0-f);g=0;while(1){j=c<<2;g=g+ +v(s[j+a>>2]/p);f=ub(g);f=(f|0)<(k|0)?(f|0)<(l|0)?l:f:n;o[d+j>>2]=f;g=g- +(f|0);c=c+1|0;if((c|0)!=(b|0)){continue}break}}o[e>>2]=0}N=i+16|0;return h}function Jc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0,h=0,i=0,j=0;e=N-32|0;N=e;g=o[a+28>>2];o[e+16>>2]=g;d=o[a+20>>2];o[e+28>>2]=c;o[e+24>>2]=b;b=d-g|0;o[e+20>>2]=b;g=b+c|0;j=2;b=e+16|0;a:{b:{f=G(o[a+60>>2],e+16|0,2,e+12|0)|0;d=0;c:{if(!f){break c}o[2896]=f;d=-1}d:{if(!d){while(1){d=o[e+12>>2];if((d|0)==(g|0)){break d}if((d|0)<=-1){break b}h=o[b+4>>2];f=d>>>0>h>>>0;i=(f<<3)+b|0;h=d-(f?h:0)|0;o[i>>2]=h+o[i>>2];i=(f?12:4)+b|0;o[i>>2]=o[i>>2]-h;g=g-d|0;b=f?b+8|0:b;j=j-f|0;f=G(o[a+60>>2],b|0,j|0,e+12|0)|0;d=0;e:{if(!f){break e}o[2896]=f;d=-1}if(!d){continue}break}}o[e+12>>2]=-1;if((g|0)!=-1){break b}}b=o[a+44>>2];o[a+28>>2]=b;o[a+20>>2]=b;o[a+16>>2]=b+o[a+48>>2];a=c;break a}o[a+28>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;o[a>>2]=o[a>>2]|32;a=0;if((j|0)==2){break a}a=c-o[b+4>>2]|0}N=e+32|0;return a|0}function Gb(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0,p=0,q=0,r=0;m=o[(h?5644:5640)>>2];j=o[(h?5632:5628)>>2];a:{b:{if(!g){if(!o[f>>2]){if(!_(a,o[e>>2],j)){break b}if(!Yb(a,b,c,o[e>>2])){break b}break a}if(!_(a,m,j)){break b}if(!_(a,o[f>>2],o[1409])){break b}if(!c){break a}h=0;while(1){if(va(a,o[(h<<2)+b>>2],o[f>>2])){h=h+1|0;if((h|0)!=(c|0)){continue}break a}break}return 0}q=c+d>>>g|0;r=o[1409];c=0;while(1){h=c;n=q-(k?0:d)|0;c=h+n|0;p=k<<2;i=p+f|0;c:{if(!o[i>>2]){l=0;i=e+p|0;if(!_(a,o[i>>2],j)){break b}if(Yb(a,(h<<2)+b|0,n,o[i>>2])){break c}break b}l=0;if(!_(a,m,j)){break b}if(!_(a,o[i>>2],r)){break b}if(h>>>0>=c>>>0){break c}while(1){if(!va(a,o[(h<<2)+b>>2],o[i>>2])){break b}h=h+1|0;if((h|0)!=(c|0)){continue}break}}l=1;k=k+1|0;if(!(k>>>g)){continue}break}}return l}return 1}function wc(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0;a:{if(!a){break a}i=o[a>>2];if(!i){break a}f=o[a+36>>2];if(o[a+32>>2]<=(f|0)){break a}d=o[a+16>>2];g=o[d+(f<<2)>>2];if(g&1024){o[a+36>>2]=f+1;b=a;d=a;c=o[a+348>>2];a=o[a+344>>2]+1|0;if(a>>>0<1){c=c+1|0}o[d+344>>2]=a;o[b+348>>2]=c;return-1}e=g&512;h=255;c=g&255;b:{if((c|0)!=255){h=c;break b}while(1){f=f+1|0;c=o[(f<<2)+d>>2];e=c&512?512:e;c=c&255;h=c+h|0;if((c|0)==255){continue}break}}c:{if(!b){e=o[a+344>>2];c=o[a+348>>2];g=o[a+12>>2];break c}o[b+8>>2]=g&256;o[b+12>>2]=e;g=o[a+12>>2];o[b>>2]=i+g;d=o[a+348>>2];c=d;e=o[a+344>>2];o[b+24>>2]=e;o[b+28>>2]=c;d=o[a+20>>2]+(f<<3)|0;i=o[d+4>>2];d=o[d>>2];o[b+4>>2]=h;o[b+16>>2]=d;o[b+20>>2]=i}d=e+1|0;if(d>>>0<1){c=c+1|0}o[a+344>>2]=d;o[a+348>>2]=c;e=1;o[a+36>>2]=f+1;o[a+12>>2]=g+h}return e}function ne(a,b,c,d){var e=0,f=0;a:{b:{c:{switch(c|0){case 4:c=0;if((b|0)<=0){break b}while(1){f=c<<2;e=f+a|0;o[d+f>>2]=(o[e+ -16>>2]+(o[e>>2]+u(o[e+ -8>>2],6)|0)|0)-(o[e+ -12>>2]+o[e+ -4>>2]<<2);c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 3:c=0;if((b|0)<=0){break b}while(1){f=c<<2;e=f+a|0;o[d+f>>2]=(o[e>>2]-o[e+ -12>>2]|0)+u(o[e+ -8>>2]-o[e+ -4>>2]|0,3);c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 2:c=0;if((b|0)<=0){break b}while(1){f=c<<2;e=f+a|0;o[d+f>>2]=o[e+ -8>>2]+(o[e>>2]-(o[e+ -4>>2]<<1)|0);c=c+1|0;if((c|0)!=(b|0)){continue}break}break b;case 0:break a;case 1:break c;default:break b}}c=0;if((b|0)<=0){break b}while(1){f=c<<2;e=f+a|0;o[d+f>>2]=o[e>>2]-o[e+ -4>>2];c=c+1|0;if((c|0)!=(b|0)){continue}break}}return}ca(d,a,b<<2)}function la(a){var b=0,c=0,d=0,i=0,j=0,k=0,l=0,m=0,n=0,o=0;a:{b:{c:{d:{h(+a);b=e(1)|0;d=e(0)|0;if((b|0)>0?1:(b|0)>=0?d>>>0<0?0:1:0){j=b;if(b>>>0>1048575){break d}}if(!(b&2147483647|d)){return-1/(a*a)}if((b|0)>-1?1:0){break c}return(a-a)/0}if(j>>>0>2146435071){break a}b=1072693248;k=-1023;if((j|0)!=1072693248){b=j;break b}if(d){break b}return 0}h(+(a*0x40000000000000));b=e(1)|0;d=e(0)|0;k=-1077}b=b+614242|0;i=+((b>>>20|0)+k|0);f(0,d|0);f(1,(b&1048575)+1072079006|0);a=+g()+ -1;c=a/(a+2);l=i*.6931471803691238;m=a;n=i*1.9082149292705877e-10;o=c;i=a*(a*.5);c=c*c;a=c*c;a=l+(m+(n+o*(i+(a*(a*(a*.15313837699209373+.22222198432149784)+.3999999999940942)+c*(a*(a*(a*.14798198605116586+.1818357216161805)+.2857142874366239)+.6666666666666735)))-i))}return a}function Z(a,b,c){var d=0,e=0,f=0,g=0,h=0;a:{if(!a|c>>>0>32){break a}e=o[a>>2];if(!e){break a}g=1;if(!c){break a}f=o[a+8>>2];d=o[a+12>>2];b:{if(f>>>0>d+c>>>0){d=e;break b}d=d+((o[a+16>>2]+c|0)+31>>>5|0)|0;if(d>>>0<=f>>>0){d=e;break b}g=0;h=d;d=d-f&1023;f=h+(d?1024-d|0:0)|0;c:{if(f){if((f|0)!=(f&1073741823)){break a}d=ea(e,f<<2);if(d){break c}X(e);return 0}d=ea(e,0);if(!d){break a}}o[a+8>>2]=f;o[a>>2]=d}e=o[a+16>>2];f=32-e|0;if(f>>>0>c>>>0){o[a+16>>2]=c+e;o[a+4>>2]=o[a+4>>2]<<c|b;return 1}if(e){e=c-f|0;o[a+16>>2]=e;c=o[a+12>>2];o[a+12>>2]=c+1;d=(c<<2)+d|0;c=o[a+4>>2]<<f|b>>>e;o[d>>2]=c<<24|c<<8&16711680|(c>>>8&65280|c>>>24);o[a+4>>2]=b;return 1}g=1;c=a;a=o[a+12>>2];o[c+12>>2]=a+1;o[(a<<2)+d>>2]=b<<8&16711680|b<<24|(b>>>8&65280|b>>>24)}return g}function ld(a,b,c,d,e){var f=0;a:{if(!_(e,(o[a+12>>2]<<1)+ -2|(o[1420]|(d|0)!=0),o[1416]+(o[1415]+o[1414]|0)|0)){break a}if(d){if(!Qa(e,d+ -1|0)){break a}}b:{if(!o[a+12>>2]){break b}d=0;while(1){if(va(e,o[((d<<2)+a|0)+152>>2],c)){d=d+1|0;if(d>>>0<r[a+12>>2]){continue}break b}break}return 0}if(!_(e,o[a+16>>2]+ -1|0,o[1412])){break a}if(!va(e,o[a+20>>2],o[1413])){break a}c:{if(!o[a+12>>2]){break c}d=0;while(1){if(va(e,o[((d<<2)+a|0)+24>>2],o[a+16>>2])){d=d+1|0;if(d>>>0<r[a+12>>2]){continue}break c}break}return 0}if(!_(e,o[a>>2],o[1405])){break a}d:{if(r[a>>2]>1){break d}if(!_(e,o[a+4>>2],o[1406])){break a}c=o[a>>2];if(c>>>0>1){break d}d=b;b=o[a+8>>2];if(!Gb(e,o[a+280>>2],d,o[a+12>>2],o[b>>2],o[b+4>>2],o[a+4>>2],(c|0)==1)){break a}}f=1}return f}function Xc(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=v(0);a:{if(!!(c<=v(0))){if((b|0)<1){break a}while(1){o[(d<<2)+a>>2]=1065353216;d=d+1|0;if((d|0)!=(b|0)){continue}break}break a}if(!!(c>=v(1))){if((b|0)<1){break a}f=+(b+ -1|0);while(1){h=(d<<2)+a|0,i=v(.5-ba(+(d|0)*6.283185307179586/f)*.5),s[h>>2]=i;d=d+1|0;if((d|0)!=(b|0)){continue}break}break a}c=v(v(c*v(.5))*v(b|0));b:{if(v(w(c))<v(2147483648)){e=~~c;break b}e=-2147483648}if((b|0)>=1){while(1){o[(d<<2)+a>>2]=1065353216;d=d+1|0;if((d|0)!=(b|0)){continue}break}}if((e|0)<2){break a}b=b-e|0;g=e+ -1|0;f=+(g|0);d=0;while(1){h=(d<<2)+a|0,i=v(.5-ba(+(d|0)*3.141592653589793/f)*.5),s[h>>2]=i;h=(b+d<<2)+a|0,i=v(.5-ba(+(d+g|0)*3.141592653589793/f)*.5),s[h>>2]=i;d=d+1|0;if((e|0)!=(d|0)){continue}break}}}function Ca(a,b){var c=0,d=0,e=0,f=0;a:{b:{if(!b){break b}c=o[a+8>>2];e=o[a+12>>2];c:{if(c>>>0>e+b>>>0){break c}d=e+((o[a+16>>2]+b|0)+31>>>5|0)|0;if(d>>>0<=c>>>0){break c}e=o[a>>2];c=d-c&1023;c=d+(c?1024-c|0:0)|0;d:{if(c){if((c|0)!=(c&1073741823)){break a}d=ea(e,c<<2);if(d){break d}X(e);return 0}d=ea(e,0);if(!d){break a}}o[a+8>>2]=c;o[a>>2]=d}c=o[a+16>>2];if(c){f=c;c=32-c|0;e=c>>>0<b>>>0?c:b;d=f+e|0;o[a+16>>2]=d;c=o[a+4>>2]<<e;o[a+4>>2]=c;if((d|0)!=32){break b}d=o[a+12>>2];o[a+12>>2]=d+1;o[o[a>>2]+(d<<2)>>2]=c<<8&16711680|c<<24|(c>>>8&65280|c>>>24);o[a+16>>2]=0;b=b-e|0}if(b>>>0>=32){c=o[a>>2];while(1){e=o[a+12>>2];o[a+12>>2]=e+1;o[c+(e<<2)>>2]=0;b=b+ -32|0;if(b>>>0>31){continue}break}}if(!b){break b}o[a+16>>2]=b;o[a+4>>2]=0}f=1}return f}function Y(a,b,c){var d=0,e=0,f=0;a:{if(c){b:{while(1){f=o[a+8>>2];e=o[a+16>>2];d=o[a+20>>2];if(((f-e<<5)+(o[a+12>>2]<<3)|0)-d>>>0>=c>>>0){break b}if(Ia(a)){continue}break}return 0}if(f>>>0>e>>>0){if(d){f=o[a>>2];e=o[f+(e<<2)>>2]&-1>>>d;d=32-d|0;if(d>>>0>c>>>0){o[b>>2]=e>>>d-c;o[a+20>>2]=o[a+20>>2]+c;break a}o[b>>2]=e;o[a+20>>2]=0;o[a+16>>2]=o[a+16>>2]+1;c=c-d|0;if(!c){break a}d=o[b>>2]<<c;o[b>>2]=d;o[b>>2]=d|o[f+(o[a+16>>2]<<2)>>2]>>>32-c;o[a+20>>2]=c;return 1}d=o[o[a>>2]+(e<<2)>>2];if(c>>>0<=31){o[b>>2]=d>>>32-c;o[a+20>>2]=c;break a}o[b>>2]=d;o[a+16>>2]=o[a+16>>2]+1;return 1}e=o[o[a>>2]+(e<<2)>>2];if(d){o[b>>2]=(e&-1>>>d)>>>32-(c+d|0);o[a+20>>2]=o[a+20>>2]+c;break a}o[b>>2]=e>>>32-c;o[a+20>>2]=o[a+20>>2]+c;break a}o[b>>2]=0}return 1}function _b(a,b){var c=0,d=0,e=0;d=o[b+80>>2]&63;c=d+b|0;m[c|0]=128;c=c+1|0;e=56;a:{if(d>>>0<56){e=55-d|0;break a}fa(c,d^63);Ra(b- -64|0,b);c=b}fa(c,e);c=o[b+80>>2];o[b+56>>2]=c<<3;o[b+60>>2]=o[b+84>>2]<<3|c>>>29;Ra(b- -64|0,b);c=p[b+76|0]|p[b+77|0]<<8|(p[b+78|0]<<16|p[b+79|0]<<24);d=p[b+72|0]|p[b+73|0]<<8|(p[b+74|0]<<16|p[b+75|0]<<24);m[a+8|0]=d;m[a+9|0]=d>>>8;m[a+10|0]=d>>>16;m[a+11|0]=d>>>24;m[a+12|0]=c;m[a+13|0]=c>>>8;m[a+14|0]=c>>>16;m[a+15|0]=c>>>24;c=p[b+68|0]|p[b+69|0]<<8|(p[b+70|0]<<16|p[b+71|0]<<24);d=p[b+64|0]|p[b+65|0]<<8|(p[b+66|0]<<16|p[b+67|0]<<24);m[a|0]=d;m[a+1|0]=d>>>8;m[a+2|0]=d>>>16;m[a+3|0]=d>>>24;m[a+4|0]=c;m[a+5|0]=c>>>8;m[a+6|0]=c>>>16;m[a+7|0]=c>>>24;a=o[b+88>>2];if(a){X(a);o[b+88>>2]=0;o[b+92>>2]=0}fa(b,96)}function pa(a,b,c){var d=0;a:{if((a|0)==(b|0)){break a}if((b-a|0)-c>>>0<=0-(c<<1)>>>0){ca(a,b,c);return}d=(a^b)&3;b:{c:{if(a>>>0<b>>>0){if(d){break b}if(!(a&3)){break c}while(1){if(!c){break a}m[a|0]=p[b|0];b=b+1|0;c=c+ -1|0;a=a+1|0;if(a&3){continue}break}break c}d:{if(d){break d}if(a+c&3){while(1){if(!c){break a}c=c+ -1|0;d=c+a|0;m[d|0]=p[b+c|0];if(d&3){continue}break}}if(c>>>0<=3){break d}while(1){c=c+ -4|0;o[c+a>>2]=o[b+c>>2];if(c>>>0>3){continue}break}}if(!c){break a}while(1){c=c+ -1|0;m[c+a|0]=p[b+c|0];if(c){continue}break}break a}if(c>>>0<=3){break b}while(1){o[a>>2]=o[b>>2];b=b+4|0;a=a+4|0;c=c+ -4|0;if(c>>>0>3){continue}break}}if(!c){break a}while(1){m[a|0]=p[b|0];a=a+1|0;b=b+1|0;c=c+ -1|0;if(c){continue}break}}}function xe(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;h=N-16|0;N=h;a:{if(!Y(a,h+12|0,8)){break a}e=o[h+12>>2];if(c){f=o[d>>2];o[d>>2]=f+1;m[c+f|0]=e}b:{c:{d:{e:{if(!(e&128)){break e}f:{if(!(!(e&192)|e&32)){g=31;f=1;break f}if(!(!(e&224)|e&16)){g=15;f=2;break f}if(!(!(e&240)|e&8)){g=7;f=3;break f}if(e&248){g=3;f=4;if(!(e&4)){break f}}if(!(e&252)|e&2){break d}g=1;f=5}e=e&g;if(!c){while(1){if(!Y(a,h+12|0,8)){break a}c=o[h+12>>2];if((c&192)!=128){break c}e=c&63|e<<6;f=f+ -1|0;if(f){continue}break e}}while(1){if(!Y(a,h+12|0,8)){break a}g=o[h+12>>2];i=o[d>>2];o[d>>2]=i+1;m[c+i|0]=g;if((g&192)!=128){break c}e=g&63|e<<6;f=f+ -1|0;if(f){continue}break}}o[b>>2]=e;break b}o[b>>2]=-1;break b}o[b>>2]=-1}j=1}N=h+16|0;return j}function ce(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0,n=0,p=0;h=N-256|0;N=h;n=o[b>>2];k=+s[a>>2];a:{while(1){if((f|0)==(n|0)){break a}m=f+1|0;g=+v(-s[(m<<2)+a>>2]);b:{if(f){l=f>>>1|0;e=0;while(1){g=g-t[(e<<3)+h>>3]*+s[(f-e<<2)+a>>2];e=e+1|0;if((e|0)!=(f|0)){continue}break}g=g/k;t[(f<<3)+h>>3]=g;e=0;if(l){while(1){i=(e<<3)+h|0;j=t[i>>3];p=i;i=((e^-1)+f<<3)+h|0;t[p>>3]=j+g*t[i>>3];t[i>>3]=g*j+t[i>>3];e=e+1|0;if((l|0)!=(e|0)){continue}break}}if(!(f&1)){break b}i=(l<<3)+h|0;j=t[i>>3];t[i>>3]=j+g*j;break b}g=g/k;t[(f<<3)+h>>3]=g}j=1-g*g;e=0;while(1){s[((f<<7)+c|0)+(e<<2)>>2]=-v(t[(e<<3)+h>>3]);e=e+1|0;if(e>>>0<=f>>>0){continue}break}k=k*j;t[(f<<3)+d>>3]=k;f=m;if(k!=0){continue}break}o[b>>2]=f}N=h+256|0}function mb(a,b,c,d,e,f){var g=0;g=N-80|0;N=g;a:{if((f|0)>=16384){$(g+32|0,b,c,d,e,0,0,0,2147352576);d=o[g+40>>2];e=o[g+44>>2];b=o[g+32>>2];c=o[g+36>>2];if((f|0)<32767){f=f+ -16383|0;break a}$(g+16|0,b,c,d,e,0,0,0,2147352576);f=((f|0)<49149?f:49149)+ -32766|0;d=o[g+24>>2];e=o[g+28>>2];b=o[g+16>>2];c=o[g+20>>2];break a}if((f|0)>-16383){break a}$(g- -64|0,b,c,d,e,0,0,0,65536);d=o[g+72>>2];e=o[g+76>>2];b=o[g+64>>2];c=o[g+68>>2];if((f|0)>-32765){f=f+16382|0;break a}$(g+48|0,b,c,d,e,0,0,0,65536);f=((f|0)>-49146?f:-49146)+32764|0;d=o[g+56>>2];e=o[g+60>>2];b=o[g+48>>2];c=o[g+52>>2]}$(g,b,c,d,e,0,0,0,f+16383<<16);b=o[g+12>>2];o[a+8>>2]=o[g+8>>2];o[a+12>>2]=b;b=o[g+4>>2];o[a>>2]=o[g>>2];o[a+4>>2]=b;N=g+80|0}function mc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;a:{d=o[c+4>>2];if(o[d>>2]){break a}e=o[d+20>>2];if(!e){break a}if(!l[e](c,o[d+48>>2])){break a}o[b>>2]=0;o[o[c>>2]>>2]=4;return 0}b:{c:{if(o[b>>2]){d=o[c+4>>2];if(!(!o[d+3632>>2]|r[d+6152>>2]<21)){o[o[c>>2]>>2]=7;break c}d:{e:{f:{g:{if(o[d>>2]){e=0;switch(Ud(o[c>>2]+32|0,a,b,c,o[d+48>>2])|0){case 0:case 2:break e;case 1:break f;default:break g}}e=l[o[d+4>>2]](c,a,b,o[d+48>>2])|0;if((e|0)!=2){break e}}o[o[c>>2]>>2]=7;break c}a=1;if(!o[b>>2]){break d}break b}a=1;if(o[b>>2]){break b}if((e|0)==1){break d}b=o[c+4>>2];if(o[b>>2]){break b}d=o[b+20>>2];if(!d){break b}if(!l[d](c,o[b+48>>2])){break b}}o[o[c>>2]>>2]=4;break c}o[o[c>>2]>>2]=7}a=0}return a|0}function ga(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;b=o[a+116>>2];c=b;a:{f=o[a+112>>2];b:{if(b|f){b=o[a+124>>2];if((b|0)>(c|0)?1:(b|0)>=(c|0)?r[a+120>>2]<f>>>0?0:1:0){break b}}f=Fc(a);if((f|0)>-1){break a}}o[a+104>>2]=0;return-1}b=o[a+8>>2];c=o[a+116>>2];d=c;c:{d:{e=o[a+112>>2];if(!(c|e)){break d}c=(o[a+124>>2]^-1)+d|0;d=o[a+120>>2]^-1;e=d+e|0;if(e>>>0<d>>>0){c=c+1|0}d=e;e=o[a+4>>2];g=b-e|0;h=d>>>0<g>>>0?0:1;g=g>>31;if((c|0)>(g|0)?1:(c|0)>=(g|0)?h:0){break d}o[a+104>>2]=d+e;break c}o[a+104>>2]=b}e:{if(!b){a=o[a+4>>2];break e}e=o[a+124>>2];c=a;d=o[a+120>>2];a=o[a+4>>2];b=(b-a|0)+1|0;g=b;d=d+b|0;b=(b>>31)+e|0;o[c+120>>2]=d;o[c+124>>2]=d>>>0<g>>>0?b+1|0:b}a=a+ -1|0;if(p[a|0]!=(f|0)){m[a|0]=f}return f}function fa(a,b){var c=0,d=0;a:{if(!b){break a}c=a+b|0;m[c+ -1|0]=0;m[a|0]=0;if(b>>>0<3){break a}m[c+ -2|0]=0;m[a+1|0]=0;m[c+ -3|0]=0;m[a+2|0]=0;if(b>>>0<7){break a}m[c+ -4|0]=0;m[a+3|0]=0;if(b>>>0<9){break a}d=0-a&3;c=d+a|0;o[c>>2]=0;d=b-d&-4;b=d+c|0;o[b+ -4>>2]=0;if(d>>>0<9){break a}o[c+8>>2]=0;o[c+4>>2]=0;o[b+ -8>>2]=0;o[b+ -12>>2]=0;if(d>>>0<25){break a}o[c+24>>2]=0;o[c+20>>2]=0;o[c+16>>2]=0;o[c+12>>2]=0;o[b+ -16>>2]=0;o[b+ -20>>2]=0;o[b+ -24>>2]=0;o[b+ -28>>2]=0;b=d;d=c&4|24;b=b-d|0;if(b>>>0<32){break a}c=c+d|0;while(1){o[c+24>>2]=0;o[c+28>>2]=0;o[c+16>>2]=0;o[c+20>>2]=0;o[c+8>>2]=0;o[c+12>>2]=0;o[c>>2]=0;o[c+4>>2]=0;c=c+32|0;b=b+ -32|0;if(b>>>0>31){continue}break}}return a}function za(a,b,c,d,e,f,g,h){var i=0,j=0,k=0,l=0,m=0,n=0;j=1;i=d&2147483647;m=i;k=c;a:{if(!c&(i|0)==2147418112?a|b:(i|0)==2147418112&c>>>0>0|i>>>0>2147418112){break a}l=h&2147483647;n=l;i=g;if(!g&(l|0)==2147418112?e|f:(l|0)==2147418112&g>>>0>0|l>>>0>2147418112){break a}if(!(a|e|(i|k)|(b|f|(m|n)))){return 0}k=d&h;if((k|0)>0?1:(k|0)>=0?(c&g)>>>0<0?0:1:0){j=-1;if((c|0)==(g|0)&(d|0)==(h|0)?(b|0)==(f|0)&a>>>0<e>>>0|b>>>0<f>>>0:(d|0)<(h|0)?1:(d|0)<=(h|0)?c>>>0>=g>>>0?0:1:0){break a}return(a^e|c^g)!=0|(b^f|d^h)!=0}j=-1;if((c|0)==(g|0)&(d|0)==(h|0)?(b|0)==(f|0)&a>>>0>e>>>0|b>>>0>f>>>0:(d|0)>(h|0)?1:(d|0)>=(h|0)?c>>>0<=g>>>0?0:1:0){break a}j=(a^e|c^g)!=0|(b^f|d^h)!=0}return j}function Ub(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0;a:{b=o[a>>2];if(!b){break a}nc(o[a+4>>2],b);if(!o[a>>2]){break a}e=1;f=o[a>>2];if(f>>>0>1){h=1;while(1){c=o[a+4>>2];d=c+u(h,24)|0;b=o[d+4>>2];g=o[d>>2];b:{if((g|0)!=-1|(b|0)!=-1){i=g;g=(u(e,24)+c|0)+ -24|0;if((i|0)==o[g>>2]&o[g+4>>2]==(b|0)){break b}}b=o[d+4>>2];c=u(e,24)+c|0;o[c>>2]=o[d>>2];o[c+4>>2]=b;b=o[d+20>>2];o[c+16>>2]=o[d+16>>2];o[c+20>>2]=b;b=o[d+12>>2];o[c+8>>2]=o[d+8>>2];o[c+12>>2]=b;e=e+1|0;f=o[a>>2]}h=h+1|0;if(h>>>0<f>>>0){continue}break}}if(e>>>0>=f>>>0){break a}d=o[a+4>>2];a=e;while(1){b=d+u(a,24)|0;o[b+16>>2]=0;o[b+8>>2]=0;o[b+12>>2]=0;o[b>>2]=-1;o[b+4>>2]=-1;a=a+1|0;if((f|0)!=(a|0)){continue}break}}}function Yc(a,b){var c=0,d=0,e=v(0),f=0,g=v(0),h=0;d=1;a:{if(b&1){c=(b+1|0)/2|0;if((b|0)>=1){e=v(v(b|0)+v(1));f=(c|0)>1?c:1;d=f+1|0;c=1;while(1){g=v(c|0);s[((c<<2)+a|0)+ -4>>2]=v(g+g)/e;h=(c|0)==(f|0);c=c+1|0;if(!h){continue}break}}if((d|0)>(b|0)){break a}e=v(v(b|0)+v(1));while(1){s[((d<<2)+a|0)+ -4>>2]=v((b-d<<1)+2|0)/e;c=(b|0)==(d|0);d=d+1|0;if(!c){continue}break}break a}c=1;if((b|0)>=2){f=b>>>1|0;c=f+1|0;e=v(v(b|0)+v(1));while(1){g=v(d|0);s[((d<<2)+a|0)+ -4>>2]=v(g+g)/e;h=(d|0)==(f|0);d=d+1|0;if(!h){continue}break}}if((c|0)>(b|0)){break a}e=v(v(b|0)+v(1));while(1){s[((c<<2)+a|0)+ -4>>2]=v((b-c<<1)+2|0)/e;d=(b|0)!=(c|0);c=c+1|0;if(d){continue}break}}}function ze(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;f=o[a+16>>2];c=o[a+28>>2];a:{if(f>>>0<=c>>>0){e=c;break a}b=o[a+32>>2];if(!b){e=c;break a}e=c+1|0;o[a+28>>2]=e;d=o[a+24>>2];if(b>>>0<=31){c=o[o[a>>2]+(c<<2)>>2];while(1){d=q[((c>>>24-b&255^d>>>8)<<1)+1280>>1]^d<<8&65280;h=b>>>0<24;g=b+8|0;b=g;if(h){continue}break}o[a+32>>2]=g}o[a+32>>2]=0;o[a+24>>2]=d}b=Wb(o[a>>2]+(e<<2)|0,f-e|0,q[a+24>>1]);o[a+28>>2]=0;o[a+24>>2]=b;c=o[a+20>>2];b:{if(!c){break b}d=o[a+32>>2];if(d>>>0>=c>>>0){break b}e=o[o[a>>2]+(o[a+16>>2]<<2)>>2];while(1){b=q[((e>>>24-d&255^b>>>8)<<1)+1280>>1]^b<<8&65280;d=d+8|0;if(d>>>0<c>>>0){continue}break}o[a+32>>2]=d;o[a+24>>2]=b}return b}function wb(a,b,c,d,e,f,g,h,i,j,k){var l=0,m=0;l=5;a:{m=o[a>>2];b:{if(o[m>>2]!=9){break b}l=2;if(!i|(!b|!g)){break b}if(c){if(!f|(!d|!e)){break b}}l=o[a+4>>2];o[l>>2]=k;if(k){if(!Vd(m+32|0)){break a}l=o[a+4>>2]}Xb(l+3524|0);k=o[a+4>>2];o[k+44>>2]=5;o[k+40>>2]=6;o[k+36>>2]=5;if(!ye(o[k+56>>2],a)){o[o[a>>2]>>2]=8;return 3}k=o[a+4>>2];o[k+48>>2]=j;o[k+32>>2]=i;o[k+28>>2]=h;o[k+24>>2]=g;o[k+20>>2]=f;o[k+16>>2]=e;o[k+12>>2]=d;o[k+8>>2]=c;o[k+4>>2]=b;o[k+3520>>2]=0;o[k+248>>2]=0;o[k+240>>2]=0;o[k+244>>2]=0;o[k+228>>2]=0;o[k+232>>2]=0;o[k+3624>>2]=o[o[a>>2]+28>>2];o[k+3628>>2]=1;o[k+3632>>2]=0;l=Nb(a)?0:3}return l}o[o[a>>2]+4>>2]=4;return 4}function eb(a,b){var c=0,d=0,e=0;o[b>>2]=0;a:{while(1){d=o[a+16>>2];b:{if(d>>>0>=r[a+8>>2]){c=o[a+20>>2];break b}c=o[a+20>>2];e=o[a>>2];while(1){d=o[e+(d<<2)>>2]<<c;if(d){c=b;e=o[b>>2];b=x(d);o[c>>2]=e+b;c=(b+o[a+20>>2]|0)+1|0;o[a+20>>2]=c;b=1;if(c>>>0<32){break a}o[a+20>>2]=0;o[a+16>>2]=o[a+16>>2]+1;return 1}o[b>>2]=(o[b>>2]-c|0)+32;c=0;o[a+20>>2]=0;d=o[a+16>>2]+1|0;o[a+16>>2]=d;if(d>>>0<r[a+8>>2]){continue}break}}e=o[a+12>>2]<<3;if(e>>>0>c>>>0){d=(o[o[a>>2]+(d<<2)>>2]&-1<<32-e)<<c;if(d){c=b;e=o[b>>2];b=x(d);o[c>>2]=e+b;o[a+20>>2]=(b+o[a+20>>2]|0)+1;return 1}o[b>>2]=o[b>>2]+(e-c|0);o[a+20>>2]=e}if(Ia(a)){continue}break}b=0}return b}function Ka(a,b,c,d,e){var f=0,g=0,h=0,i=0;f=N-240|0;N=f;g=o[b>>2];o[f+232>>2]=g;b=o[b+4>>2];o[f>>2]=a;o[f+236>>2]=b;h=1;a:{b:{c:{d:{if(b?0:(g|0)==1){break d}g=a-o[(c<<2)+e>>2]|0;if((l[1](g,a)|0)<1){break d}i=!d;while(1){e:{b=g;if(!(!i|(c|0)<2)){d=o[((c<<2)+e|0)+ -8>>2];g=a+ -24|0;if((l[1](g,b)|0)>-1){break e}if((l[1](g-d|0,b)|0)>-1){break e}}o[(h<<2)+f>>2]=b;d=f+232|0;a=De(o[f+232>>2]+ -1|0);if(!a){a=De(o[f+236>>2]);a=a?a+32|0:0}La(d,a);h=h+1|0;c=a+c|0;if(o[f+236>>2]?0:o[f+232>>2]==1){break b}d=0;i=1;a=b;g=a-o[(c<<2)+e>>2]|0;if((l[1](g,o[f>>2])|0)>0){continue}break c}break}b=a;break b}b=a}if(d){break a}}Eb(f,h);Sa(b,c,e)}N=f+240|0}function Ed(a){a=a|0;var b=0,c=0;if(a){o[o[a+4>>2]+11848>>2]=1;Mb(a);b=o[a+4>>2];c=o[b+11752>>2];if(c){Sb(c);b=o[a+4>>2]}aa(b+6256|0);aa(o[a+4>>2]+6268|0);aa(o[a+4>>2]+6280|0);aa(o[a+4>>2]+6292|0);aa(o[a+4>>2]+6304|0);aa(o[a+4>>2]+6316|0);aa(o[a+4>>2]+6328|0);aa(o[a+4>>2]+6340|0);aa(o[a+4>>2]+6352|0);aa(o[a+4>>2]+6364|0);aa(o[a+4>>2]+6376|0);aa(o[a+4>>2]+6388|0);aa(o[a+4>>2]+6400|0);aa(o[a+4>>2]+6412|0);aa(o[a+4>>2]+6424|0);aa(o[a+4>>2]+6436|0);aa(o[a+4>>2]+6448|0);aa(o[a+4>>2]+6460|0);aa(o[a+4>>2]+6472|0);aa(o[a+4>>2]+6484|0);aa(o[a+4>>2]+11724|0);aa(o[a+4>>2]+11736|0);gb(o[o[a+4>>2]+6856>>2]);X(o[a+4>>2]);X(o[a>>2]);X(a)}}function na(a,b,c){var d=0,e=0;e=N-16|0;N=e;a:{if(!c){d=1;break a}while(1){if(!o[a+20>>2]){b:{if(c>>>0<4){break b}while(1){c:{d=o[a+16>>2];if(d>>>0<r[a+8>>2]){o[a+16>>2]=d+1;d=o[o[a>>2]+(d<<2)>>2];d=d<<24|d<<8&16711680|(d>>>8&65280|d>>>24);m[b|0]=d;m[b+1|0]=d>>>8;m[b+2|0]=d>>>16;m[b+3|0]=d>>>24;c=c+ -4|0;b=b+4|0;break c}if(Ia(a)){break c}d=0;break a}if(c>>>0>3){continue}break}if(c){break b}d=1;break a}while(1){if(!Y(a,e+12|0,8)){d=0;break a}m[b|0]=o[e+12>>2];d=1;b=b+1|0;c=c+ -1|0;if(c){continue}break}break a}if(!Y(a,e+12|0,8)){d=0;break a}m[b|0]=o[e+12>>2];d=1;b=b+1|0;c=c+ -1|0;if(c){continue}break}}N=e+16|0;return d}function sa(a,b){var c=0,d=0,f=0,g=0,i=0,j=0,k=0,l=0;g=N-16|0;N=g;h(+b);j=e(1)|0;i=e(0)|0;f=j&2147483647;c=f;f=c+ -1048576|0;d=i;if(d>>>0<0){f=f+1|0}a:{if((f|0)==2145386495|f>>>0<2145386495){k=d<<28;f=(c&15)<<28|d>>>4;c=(c>>>4|0)+1006632960|0;d=f;c=d>>>0<0?c+1|0:c;break a}if((c|0)==2146435072&d>>>0>=0|c>>>0>2146435072){k=i<<28;f=i;c=j;i=c>>>4|0;d=(c&15)<<28|f>>>4;c=i|2147418112;break a}if(!(c|d)){d=0;c=0;break a}f=c;c=(c|0)==1&d>>>0<0|c>>>0<1?x(i)+32|0:x(c);ia(g,d,f,0,0,c+49|0);l=o[g>>2];k=o[g+4>>2];d=o[g+8>>2];c=o[g+12>>2]^65536|15372-c<<16}o[a>>2]=l;o[a+4>>2]=k;o[a+8>>2]=d;o[a+12>>2]=j&-2147483648|c;N=g+16|0}function jd(a,b){var c=0,d=v(0),e=0,f=v(0),g=0,h=0,i=0;h=b+ -1|0;a:{if(b&1){e=(h|0)/2|0;if((b|0)>=0){i=(e|0)>0?e:0;g=i+1|0;f=v(h|0);while(1){d=v(c|0);s[(c<<2)+a>>2]=v(d+d)/f;e=(c|0)==(i|0);c=c+1|0;if(!e){continue}break}}if((g|0)>=(b|0)){break a}f=v(h|0);while(1){d=v(g|0);s[(g<<2)+a>>2]=v(2)-v(v(d+d)/f);g=g+1|0;if((g|0)!=(b|0)){continue}break}break a}e=(b|0)/2|0;if((b|0)>=2){f=v(h|0);while(1){d=v(c|0);s[(c<<2)+a>>2]=v(d+d)/f;c=c+1|0;if((e|0)!=(c|0)){continue}break}c=e}if((c|0)>=(b|0)){break a}f=v(h|0);while(1){d=v(c|0);s[(c<<2)+a>>2]=v(2)-v(v(d+d)/f);c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function se(a,b){if((b|0)>=0){if(b>>>0<=127){return Z(a,b,8)}if(b>>>0<=2047){return Z(a,b>>>6|192,8)&Z(a,b&63|128,8)&1}if(b>>>0<=65535){return Z(a,b>>>12|224,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}if(b>>>0<=2097151){return Z(a,b>>>18|240,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}if(b>>>0<=67108863){return Z(a,b>>>24|248,8)&Z(a,b>>>18&63|128,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}a=Z(a,b>>>30|252,8)&Z(a,b>>>24&63|128,8)&Z(a,b>>>18&63|128,8)&Z(a,b>>>12&63|128,8)&Z(a,b>>>6&63|128,8)&Z(a,b&63|128,8)&1}else{a=0}return a}function db(a,b){var c=0,d=0,e=0,f=0;d=N-16|0;N=d;e=1;a:{if(!b){break a}c=o[a+20>>2]&7;b:{if(c){c=8-c|0;c=c>>>0<b>>>0?c:b;if(!Y(a,d+8|0,c)){break b}b=b-c|0}c=b>>>3|0;if(c){while(1){c:{if(!o[a+20>>2]){if(c>>>0>3){while(1){f=o[a+16>>2];d:{if(f>>>0<r[a+8>>2]){o[a+16>>2]=f+1;c=c+ -4|0;break d}if(!Ia(a)){break b}}if(c>>>0>3){continue}break}if(!c){break c}}while(1){if(!Y(a,d+12|0,8)){break b}c=c+ -1|0;if(c){continue}break}break c}if(!Y(a,d+12|0,8)){break b}c=c+ -1|0;if(c){continue}}break}b=b&7}if(!b){break a}if(Y(a,d+8|0,b)){break a}}e=0}N=d+16|0;return e}function cb(a,b,c){var d=0,e=0,f=0,g=0,h=0;f=o[a+16>>2];a:{if(f&7){break a}b:{if(!f){e=o[a>>2];d=0;break b}g=o[a+12>>2];c:{if((g|0)!=o[a+8>>2]){break c}e=f+63>>>5|0;d=e+g|0;if(d>>>0<=g>>>0){break c}g=0;f=o[a>>2];h=d;d=e&1023;d=h+(d?1024-d|0:0)|0;d:{if(d){if((d|0)!=(d&1073741823)){break a}e=ea(f,d<<2);if(e){break d}X(f);return 0}e=ea(f,0);if(!e){break a}}o[a+8>>2]=d;o[a>>2]=e;g=o[a+12>>2];f=o[a+16>>2]}e=o[a>>2];d=o[a+4>>2]<<32-f;o[e+(g<<2)>>2]=d<<24|d<<8&16711680|(d>>>8&65280|d>>>24);d=o[a+16>>2]>>>3|0}o[b>>2]=e;o[c>>2]=d+(o[a+12>>2]<<2);g=1}return g}function fe(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0,g=0,h=v(0),i=0,j=0;g=b-c|0;a:{if(!c){while(1){e=e+1|0;if(e>>>0<=g>>>0){continue}break}break a}j=fa(d,c<<2);while(1){h=s[(e<<2)+a>>2];f=0;while(1){i=(f<<2)+j|0;s[i>>2]=s[i>>2]+v(h*s[(e+f<<2)+a>>2]);f=f+1|0;if((f|0)!=(c|0)){continue}break}e=e+1|0;if(e>>>0<=g>>>0){continue}break}}if(e>>>0<b>>>0){while(1){c=b-e|0;if(c){h=s[(e<<2)+a>>2];f=0;while(1){g=(f<<2)+d|0;s[g>>2]=s[g>>2]+v(h*s[(e+f<<2)+a>>2]);f=f+1|0;if(f>>>0<c>>>0){continue}break}}e=e+1|0;if((e|0)!=(b|0)){continue}break}}}function Jb(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0;h=-1;f=d&2147483647;i=f;g=c;a:{if(!c&(f|0)==2147418112?a|b:(f|0)==2147418112&c>>>0>0|f>>>0>2147418112){break a}f=e&2147483647;j=f;if((f|0)==2147418112?0:f>>>0>2147418112){break a}if(!(a|g|(i|j|b))){return 0}g=d&e;if((g|0)>0?1:(g|0)>=0?1:0){if(!c&(d|0)==(e|0)?!b&a>>>0<0|b>>>0<0:(d|0)<(e|0)?1:(d|0)<=(e|0)?c>>>0>=0?0:1:0){break a}return(a|c)!=0|(d^e|b)!=0}if(!c&(d|0)==(e|0)?!b&a>>>0>0|b>>>0>0:(d|0)>(e|0)?1:(d|0)>=(e|0)?c>>>0<=0?0:1:0){break a}h=(a|c)!=0|(d^e|b)!=0}return h}function md(a,b,c,d,e){var f=0;a:{if(!_(e,o[1419]|(d|0)!=0|o[a+12>>2]<<1,o[1416]+(o[1415]+o[1414]|0)|0)){break a}if(d){if(!Qa(e,d+ -1|0)){break a}}b:{if(!o[a+12>>2]){break b}d=0;while(1){if(va(e,o[((d<<2)+a|0)+16>>2],c)){d=d+1|0;if(d>>>0<r[a+12>>2]){continue}break b}break}return 0}if(!_(e,o[a>>2],o[1405])){break a}c:{if(r[a>>2]>1){break c}if(!_(e,o[a+4>>2],o[1406])){break a}c=o[a>>2];if(c>>>0>1){break c}d=b;b=o[a+8>>2];if(!Gb(e,o[a+32>>2],d,o[a+12>>2],o[b>>2],o[b+4>>2],o[a+4>>2],(c|0)==1)){break a}}f=1}return f}function Gd(a,b){a=a|0;b=b|0;var c=0,d=0,e=0;c=0;a:{if(o[o[a>>2]>>2]!=9){break a}d=o[a+4>>2];c=1;if(o[d+616>>2]){break a}c=o[d+1120>>2];b:{e=o[d+1124>>2];c:{if((e|0)!=o[d+1128>>2]){d=c;break c}d:{if(!e){d=ea(c,0);break d}if(e+e>>>0>=e>>>0){d=ea(c,e<<1);if(d){break d}X(c);d=o[a+4>>2]}o[d+1120>>2]=0;break b}c=o[a+4>>2];o[c+1120>>2]=d;if(!d){break b}o[c+1128>>2]=o[c+1128>>2]<<1;e=o[c+1124>>2]}c=d;d=o[1364]>>>3|0;ca(c+u(d,e)|0,b,d);a=o[a+4>>2];o[a+1124>>2]=o[a+1124>>2]+1;return 1}o[o[a>>2]>>2]=8;c=0}return c|0}function Ja(a,b,c,d,e,f){var g=0,h=0,i=0,j=0;a:{if(f&64){c=f+ -64|0;b=c&31;if(32<=(c&63)>>>0){c=0;b=e>>>b|0}else{c=e>>>b|0;b=((1<<b)-1&e)<<32-b|d>>>b}d=0;e=0;break a}if(!f){break a}h=e;i=d;j=64-f|0;g=j&31;if(32<=(j&63)>>>0){h=i<<g;j=0}else{h=(1<<g)-1&i>>>32-g|h<<g;j=i<<g}i=b;g=f;b=g&31;if(32<=(g&63)>>>0){g=0;b=c>>>b|0}else{g=c>>>b|0;b=((1<<b)-1&c)<<32-b|i>>>b}b=j|b;c=g|h;g=d;d=f&31;if(32<=(f&63)>>>0){h=0;d=e>>>d|0}else{h=e>>>d|0;d=((1<<d)-1&e)<<32-d|g>>>d}e=h}o[a>>2]=b;o[a+4>>2]=c;o[a+8>>2]=d;o[a+12>>2]=e}function Lc(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0,f=0,g=0;e=N-32|0;N=e;o[e+16>>2]=b;d=o[a+48>>2];o[e+20>>2]=c-((d|0)!=0);f=o[a+44>>2];o[e+28>>2]=d;o[e+24>>2]=f;a:{b:{f=L(o[a+60>>2],e+16|0,2,e+12|0)|0;d=0;c:{if(!f){break c}o[2896]=f;d=-1}d:{if(d){o[e+12>>2]=-1;c=-1;break d}d=o[e+12>>2];if((d|0)>0){break b}c=d}o[a>>2]=o[a>>2]|c&48^16;break a}g=o[e+20>>2];if(d>>>0<=g>>>0){c=d;break a}f=o[a+44>>2];o[a+4>>2]=f;o[a+8>>2]=f+(d-g|0);if(!o[a+48>>2]){break a}o[a+4>>2]=f+1;m[(b+c|0)+ -1|0]=p[f|0]}N=e+32|0;return c|0}function ia(a,b,c,d,e,f){var g=0,h=0,i=0,j=0;a:{if(f&64){d=b;e=f+ -64|0;b=e&31;if(32<=(e&63)>>>0){e=d<<b;d=0}else{e=(1<<b)-1&d>>>32-b|c<<b;d=d<<b}b=0;c=0;break a}if(!f){break a}g=d;i=f;d=f&31;if(32<=(f&63)>>>0){h=g<<d;j=0}else{h=(1<<d)-1&g>>>32-d|e<<d;j=g<<d}d=c;g=b;f=64-f|0;e=f&31;if(32<=(f&63)>>>0){f=0;d=d>>>e|0}else{f=d>>>e|0;d=((1<<e)-1&d)<<32-e|g>>>e}d=j|d;e=f|h;f=b;b=i&31;if(32<=(i&63)>>>0){h=f<<b;b=0}else{h=(1<<b)-1&f>>>32-b|c<<b;b=f<<b}c=h}o[a>>2]=b;o[a+4>>2]=c;o[a+8>>2]=d;o[a+12>>2]=e}function Jd(a,b){a=a|0;b=b|0;var c=0,d=0,e=0;if(o[o[a>>2]>>2]==9){c=o[a+4>>2];if(!o[c+616>>2]){return 1}d=o[c+1120>>2];a:{e=o[c+1124>>2];b:{if((e|0)!=o[c+1128>>2]){c=d;break b}c:{if(!e){c=ea(d,0);break c}if(e+e>>>0>=e>>>0){c=ea(d,e<<1);if(c){break c}X(d);c=o[a+4>>2]}o[c+1120>>2]=0;break a}d=o[a+4>>2];o[d+1120>>2]=c;if(!c){break a}o[d+1128>>2]=o[d+1128>>2]<<1;e=o[d+1124>>2]}d=c;c=o[1364]>>>3|0;ca(d+u(c,e)|0,b,c);a=o[a+4>>2];o[a+1124>>2]=o[a+1124>>2]+1;return 1}o[o[a>>2]>>2]=8}return 0}function qe(a,b){var c=0,d=0;if(b>>>0>7){while(1){d=c;c=p[a|0]|p[a+1|0]<<8;c=d^(c<<8&16711680|c<<24)>>>16;c=q[(p[a+7|0]<<1)+1280>>1]^(q[((p[a+6|0]<<1)+1280|0)+512>>1]^(q[(p[a+5|0]<<1)+2304>>1]^(q[(p[a+4|0]<<1)+2816>>1]^(q[(p[a+3|0]<<1)+3328>>1]^(q[(p[a+2|0]<<1)+3840>>1]^(q[((c&255)<<1)+4352>>1]^q[(c>>>7&510)+4864>>1]))))));a=a+8|0;b=b+ -8|0;if(b>>>0>7){continue}break}}if(b){while(1){c=q[((p[a|0]^(c&65280)>>>8)<<1)+1280>>1]^c<<8;a=a+1|0;b=b+ -1|0;if(b){continue}break}}return c&65535}function Wb(a,b,c){var d=0;if(b>>>0>=2){while(1){d=c;c=o[a>>2];d=d^c>>>16;d=q[((d&255)<<1)+4352>>1]^q[(d>>>7&510)+4864>>1]^q[(c>>>7&510)+3840>>1]^q[((c&255)<<1)+3328>>1];c=o[a+4>>2];c=d^q[(c>>>23&510)+2816>>1]^q[(c>>>15&510)+2304>>1]^q[((c>>>7&510)+1280|0)+512>>1]^q[((c&255)<<1)+1280>>1];a=a+8|0;b=b+ -2|0;if(b>>>0>1){continue}break}}if(b){a=o[a>>2];b=a>>>16^c;c=q[((b&255)<<1)+2304>>1]^q[(b>>>7&510)+2816>>1]^q[((a>>>7&510)+1280|0)+512>>1]^q[((a&255)<<1)+1280>>1]}return c&65535}function ma(a,b,c){var d=0,e=0,f=0,g=0;d=o[a+8>>2];e=o[a+12>>2];a:{b:{if(d>>>0>(e+(c>>>2|0)|0)+1>>>0){break b}f=e+((o[a+16>>2]+(c<<3)|0)+31>>>5|0)|0;if(f>>>0<=d>>>0){break b}e=0;g=o[a>>2];d=f-d&1023;d=f+(d?1024-d|0:0)|0;c:{if(d){if((d|0)!=(d&1073741823)){break a}f=ea(g,d<<2);if(f){break c}X(g);return 0}f=ea(g,0);if(!f){break a}}o[a+8>>2]=d;o[a>>2]=f}e=1;if(!c){break a}e=0;d:{while(1){if(!Z(a,p[b+e|0],8)){break d}e=e+1|0;if((e|0)!=(c|0)){continue}break}return 1}e=0}return e}function tc(a,b){var c=0,d=0,e=0;c=o[a+4>>2];if((c|0)>=0){e=o[a+12>>2];if(e){d=o[a+8>>2]-e|0;o[a+8>>2]=d;if((d|0)>=1){c=o[a>>2];pa(c,c+e|0,d);c=o[a+4>>2]}o[a+12>>2]=0}d=c;c=o[a+8>>2];a:{if((d-c|0)>=(b|0)){b=o[a>>2];break a}c=(b+c|0)+4096|0;b=o[a>>2];b:{if(b){b=ea(b,c);break b}b=da(c)}if(!b){b=o[a>>2];if(b){X(b)}o[a>>2]=0;o[a+4>>2]=0;o[a+24>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0;return 0}o[a+4>>2]=c;o[a>>2]=b;c=o[a+8>>2]}a=b+c|0}else{a=0}return a}function tb(a){var b=0,c=0,d=0,e=0;if(a){m[o[a>>2]+22|0]=0;m[o[a>>2]+23|0]=0;m[o[a>>2]+24|0]=0;m[o[a>>2]+25|0]=0;d=o[a+4>>2];if((d|0)>=1){e=o[a>>2];while(1){b=o[((p[c+e|0]^b>>>24)<<2)+6512>>2]^b<<8;c=c+1|0;if((d|0)!=(c|0)){continue}break}}d=o[a+12>>2];if((d|0)>=1){e=o[a+8>>2];c=0;while(1){b=o[((p[c+e|0]^b>>>24)<<2)+6512>>2]^b<<8;c=c+1|0;if((d|0)!=(c|0)){continue}break}}m[o[a>>2]+22|0]=b;m[o[a>>2]+23|0]=b>>>8;m[o[a>>2]+24|0]=b>>>16;m[o[a>>2]+25|0]=b>>>24}}function Sc(a,b){var c=0,d=0,f=0,g=0,h=0,j=0,k=0;f=N-16|0;N=f;g=(i(b),e(0));c=g&2147483647;a:{if(c+ -8388608>>>0<=2130706431){d=c;c=c>>>7|0;d=d<<25;c=c+1065353216|0;h=d;c=d>>>0<0?c+1|0:c;break a}if(c>>>0>=2139095040){c=g;d=c>>>7|0;h=c<<25;c=d|2147418112;break a}if(!c){c=0;break a}d=c;c=x(c);ia(f,d,0,0,0,c+81|0);j=o[f>>2];k=o[f+4>>2];h=o[f+8>>2];c=o[f+12>>2]^65536|16265-c<<16}o[a>>2]=j;o[a+4>>2]=k;o[a+8>>2]=h;o[a+12>>2]=g&-2147483648|c;N=f+16|0}function Ic(a,b){var c=0,d=0;a:{d=b&255;if(d){if(a&3){while(1){c=p[a|0];if(!c|(c|0)==(b&255)){break a}a=a+1|0;if(a&3){continue}break}}c=o[a>>2];b:{if((c^-1)&c+ -16843009&-2139062144){break b}d=u(d,16843009);while(1){c=c^d;if((c^-1)&c+ -16843009&-2139062144){break b}c=o[a+4>>2];a=a+4|0;if(!(c+ -16843009&(c^-1)&-2139062144)){continue}break}}while(1){c=a;d=p[c|0];if(d){a=c+1|0;if((d|0)!=(b&255)){continue}}break}return c}return Ga(a)+a|0}return a}function zc(a,b){var c=0;c=(b|0)!=0;a:{b:{c:{if(!b|!(a&3)){break c}while(1){if(p[a|0]==79){break b}a=a+1|0;b=b+ -1|0;c=(b|0)!=0;if(!b){break c}if(a&3){continue}break}}if(!c){break a}}d:{if(p[a|0]==79|b>>>0<4){break d}while(1){c=o[a>>2]^1330597711;if((c^-1)&c+ -16843009&-2139062144){break d}a=a+4|0;b=b+ -4|0;if(b>>>0>3){continue}break}}if(!b){break a}while(1){if(p[a|0]==79){return a}a=a+1|0;b=b+ -1|0;if(b){continue}break}}return 0}function Ea(a,b){var c=0,d=0,e=0;c=N-16|0;N=c;d=1;a:{if(!b){break a}while(1){b:{if(!o[a+20>>2]){c:{if(b>>>0<4){break c}while(1){e=o[a+16>>2];d:{if(e>>>0<r[a+8>>2]){o[a+16>>2]=e+1;b=b+ -4|0;break d}if(!Ia(a)){break b}}if(b>>>0>3){continue}break}if(b){break c}break a}while(1){if(!Y(a,c+12|0,8)){break b}b=b+ -1|0;if(b){continue}break}break a}if(!Y(a,c+12|0,8)){break b}b=b+ -1|0;if(b){continue}break a}break}d=0}N=c+16|0;return d}function bc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0,f=0;f=o[d+4>>2];if(o[f+11760>>2]){o[c>>2]=4;a=p[5409]|p[5410]<<8|(p[5411]<<16|p[5412]<<24);m[b|0]=a;m[b+1|0]=a>>>8;m[b+2|0]=a>>>16;m[b+3|0]=a>>>24;o[o[d+4>>2]+11760>>2]=0;return 0}a=o[f+11812>>2];if(!a){return 2}e=o[c>>2];if(a>>>0<e>>>0){o[c>>2]=a;e=a}ca(b,o[f+11804>>2],e);a=o[d+4>>2];b=a+11804|0;d=b;e=o[b>>2];b=o[c>>2];o[d>>2]=e+b;a=a+11812|0;o[a>>2]=o[a>>2]-b;return 0}function td(a,b){a=a|0;b=b|0;var c=0,d=0,e=0,f=0;d=o[a>>2];if(o[d>>2]==1){c=u(b>>>0<8?b:8,44);b=c+11184|0;e=o[b+4>>2];o[d+16>>2]=o[b>>2];o[d+20>>2]=e;d=_a(a,o[b+40>>2]);a=o[a>>2];if(o[a>>2]==1){b=c+11184|0;c=o[b+32>>2];o[a+576>>2]=o[b+28>>2];o[a+580>>2]=c;o[a+568>>2]=o[b+24>>2];o[a+564>>2]=o[b+16>>2];c=o[b+12>>2];o[a+556>>2]=o[b+8>>2];o[a+560>>2]=c;f=d&1;a=1}else{a=0}a=a&f}else{a=0}return a|0}function ba(a){var b=0,c=0,d=0;b=N-16|0;N=b;h(+a);d=e(1)|0;e(0)|0;d=d&2147483647;a:{if(d>>>0<=1072243195){c=1;if(d>>>0<1044816030){break a}c=Za(a,0);break a}c=a-a;if(d>>>0>=2146435072){break a}b:{switch(Oc(a,b)&3){case 0:c=Za(t[b>>3],t[b+8>>3]);break a;case 1:c=-Ib(t[b>>3],t[b+8>>3]);break a;case 2:c=-Za(t[b>>3],t[b+8>>3]);break a;default:break b}}c=Ib(t[b>>3],t[b+8>>3])}a=c;N=b+16|0;return a}function ed(a,b){var c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=v(0);if((b|0)>=1){c=+(b+ -1|0);while(1){e=+(d|0);f=ba(e*12.566370614359172/c);g=ba(e*6.283185307179586/c);h=ba(e*18.84955592153876/c);i=(d<<2)+a|0,j=v(ba(e*25.132741228718345/c)*.0069473679177463055+(f*.27726316452026367+(g*-.4166315793991089+.21557894349098206)+h*-.08357894420623779)),s[i>>2]=j;d=d+1|0;if((d|0)!=(b|0)){continue}break}}}function ra(a,b,c,d,e){var f=0,g=0,h=0,i=0,j=0,k=0,l=0,m=0;j=e;e=0;k=e;h=c;c=0;g=Ee(j,e,h,c);e=Q;l=g;g=g>>>0<0?e+1|0:e;f=d;e=0;i=b;d=Ee(f,e,b,0);b=Q;f=Ee(f,e,h,c);c=b+f|0;b=Q;b=c>>>0<f>>>0?b+1|0:b;h=b;f=b+l|0;b=g;b=f>>>0<h>>>0?b+1|0:b;g=b;b=Ee(i,m,j,k)+c|0;e=Q;e=b>>>0<c>>>0?e+1|0:e;i=e;f=e+f|0;e=g;o[a+8>>2]=f;o[a+12>>2]=f>>>0<i>>>0?e+1|0:e;o[a>>2]=d;o[a+4>>2]=b}function Wa(a,b,c,d,e){var f=0;f=1;a:{b:{c:{switch(o[d>>2]){case 0:if(nd(d+4|0,c,o[d+288>>2],e)){break a}break b;case 2:if(md(d+4|0,b-o[d+16>>2]|0,c,o[d+288>>2],e)){break a}break b;case 3:if(ld(d+4|0,b-o[d+16>>2]|0,c,o[d+288>>2],e)){break a}break b;case 1:break c;default:break a}}if(kd(d+4|0,b,c,o[d+288>>2],e)){break a}}o[o[a>>2]>>2]=7;f=0}return f}function Sa(a,b,c){var d=0,e=0,f=0,g=0,h=0;d=N-240|0;N=d;o[d>>2]=a;g=1;a:{if((b|0)<2){break a}e=a;while(1){f=e+ -24|0;h=b+ -2|0;e=f-o[(h<<2)+c>>2]|0;if((l[1](a,e)|0)>=0){if((l[1](a,f)|0)>-1){break a}}a=(g<<2)+d|0;b:{if((l[1](e,f)|0)>=0){o[a>>2]=e;h=b+ -1|0;break b}o[a>>2]=f;e=f}g=g+1|0;if((h|0)<2){break a}a=o[d>>2];b=h;continue}}Eb(d,g);N=d+240|0}function ua(a,b){a:{if((b|0)>=1024){a=a*8.98846567431158e+307;if((b|0)<2047){b=b+ -1023|0;break a}a=a*8.98846567431158e+307;b=((b|0)<3069?b:3069)+ -2046|0;break a}if((b|0)>-1023){break a}a=a*2.2250738585072014e-308;if((b|0)>-2045){b=b+1022|0;break a}a=a*2.2250738585072014e-308;b=((b|0)>-3066?b:-3066)+2044|0}f(0,0);f(1,b+1023<<20);return a*+g()}function Hb(a,b){var c=0;a:{c=o[a+24>>2];if((c-b|0)<=o[a+28>>2]){if((c|0)>(2147483647-b|0)){break a}b=b+c|0;b=(b|0)<2147483615?b+32|0:b;c=ea(o[a+16>>2],b<<2);if(!c){break a}o[a+16>>2]=c;c=ea(o[a+20>>2],b<<3);if(!c){break a}o[a+24>>2]=b;o[a+20>>2]=c}return 0}b=o[a>>2];if(b){X(b)}b=o[a+16>>2];if(b){X(b)}b=o[a+20>>2];if(b){X(b)}fa(a,360);return-1}function Ob(a){a=a|0;var b=0,c=0,d=0;b=N-16|0;N=b;c=1;a:{while(1){b:{c:{switch(o[o[a>>2]>>2]){case 0:if(Va(a)){continue}c=0;break b;case 1:d=(Ta(a)|0)!=0;break a;case 2:if(yb(a)){continue}break b;case 4:case 7:break b;case 3:break c;default:break a}}if(!ob(a,b+12|0)){c=0;break b}if(!o[b+12>>2]){continue}}break}d=c}N=b+16|0;return d|0}function gc(a,b){var c=0,d=0,e=0;c=N-160|0;N=c;fa(c+16|0,144);o[c+92>>2]=-1;o[c+60>>2]=b;o[c+24>>2]=-1;o[c+20>>2]=b;o[c+128>>2]=0;o[c+132>>2]=0;b=o[c+24>>2];d=b-o[c+20>>2]|0;o[c+136>>2]=d;o[c+140>>2]=d>>31;o[c+120>>2]=b;Rc(c,c+16|0);b=o[c+8>>2];d=o[c+12>>2];e=o[c+4>>2];o[a>>2]=o[c>>2];o[a+4>>2]=e;o[a+8>>2]=b;o[a+12>>2]=d;N=c+160|0}function Ga(a){var b=0,c=0,d=0;a:{b:{b=a;if(!(b&3)){break b}if(!p[a|0]){return 0}while(1){b=b+1|0;if(!(b&3)){break b}if(p[b|0]){continue}break}break a}while(1){c=b;b=b+4|0;d=o[c>>2];if(!((d^-1)&d+ -16843009&-2139062144)){continue}break}if(!(d&255)){return c-a|0}while(1){d=p[c+1|0];b=c+1|0;c=b;if(d){continue}break}}return b-a|0}function Eb(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=24;e=N-256|0;N=e;a:{if((b|0)<2){break a}h=(b<<2)+a|0;o[h>>2]=e;c=e;while(1){f=d>>>0<256?d:256;ca(c,o[a>>2],f);c=0;while(1){g=(c<<2)+a|0;c=c+1|0;ca(o[g>>2],o[(c<<2)+a>>2],f);o[g>>2]=o[g>>2]+f;if((b|0)!=(c|0)){continue}break}d=d-f|0;if(!d){break a}c=o[h>>2];continue}}N=e+256|0}function ee(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0,k=0;f=1;if(b){k=.5/+(c>>>0);h=4294967295;while(1){e=t[(g<<3)+a>>3];a:{if(!!(e>0)){e=la(k*e)*.5/.6931471805599453;e=e>=0?e:0;break a}e=e<0?1e+32:0}e=e*+(c-f>>>0)+ +(u(d,f)>>>0);i=e<h;h=i?e:h;j=i?g:j;f=f+1|0;g=g+1|0;if((g|0)!=(b|0)){continue}break}a=j+1|0}else{a=1}return a}function bd(a,b){var c=0,d=0,e=0,f=0,g=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=+(c|0);f=(c<<2)+a|0,g=v(ba(e*12.566370614359172/d)*.09799999743700027+(ba(e*6.283185307179586/d)*-.49799999594688416+.4020000100135803)+ba(e*18.84955592153876/d)*-.0010000000474974513),s[f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function ad(a,b){var c=0,d=0,e=0,f=0,g=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=+(c|0);f=(c<<2)+a|0,g=v(ba(e*12.566370614359172/d)*.13659949600696564+(ba(e*6.283185307179586/d)*-.48917749524116516+.36358189582824707)+ba(e*18.84955592153876/d)*-.010641099885106087),s[f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function gd(a,b){var c=0,d=0,e=0,f=0,g=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=+(c|0);f=(c<<2)+a|0,g=v(ba(e*12.566370614359172/d)*.14127999544143677+(ba(e*6.283185307179586/d)*-.488290011882782+.35874998569488525)+ba(e*18.84955592153876/d)*-.011680000461637974),s[f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function Nd(a){a=a|0;var b=0,c=0,d=0;b=N-16|0;N=b;c=1;a:{b:{while(1){c:{d:{switch(o[o[a>>2]>>2]){case 0:if(Va(a)){continue}break c;case 1:if(Ta(a)){continue}break c;case 2:if(yb(a)){continue}break b;case 4:case 7:break b;case 3:break d;default:break a}}if(ob(a,b+12|0)){continue}}break}c=0}d=c}N=b+16|0;return d|0}function ka(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;d=N-16|0;N=d;g=a;h=a;a:{if(!b){b=0;break a}c=b>>31;e=c+b^c;c=x(e);ia(d,e,0,0,0,c+81|0);c=(o[d+12>>2]^65536)+(16414-c<<16)|0;e=0+o[d+8>>2]|0;if(e>>>0<f>>>0){c=c+1|0}f=b&-2147483648|c;c=o[d+4>>2];b=o[d>>2]}o[h>>2]=b;o[g+4>>2]=c;o[a+8>>2]=e;o[a+12>>2]=f;N=d+16|0}function sd(a,b,c){a=a|0;b=b|0;c=c|0;var d=0,e=0;d=o[a>>2];if(o[d>>2]==1){e=o[d+600>>2];if(e){X(e);d=o[a>>2];o[d+600>>2]=0;o[d+604>>2]=0}c=b?c:0;if(c){d=Na(4,c);if(!d){return 0}b=ca(d,b,c<<2);d=o[a>>2];o[d+604>>2]=c;o[d+600>>2]=b}if(c>>>o[1886]){a=0}else{o[d+636>>2]=c;a=1}a=(a|0)!=0}else{a=0}return a|0}function fb(a,b){var c=0,d=0,e=0;c=N-16|0;N=c;o[c+8>>2]=0;a:{if(!Y(a,c+8|0,8)){break a}if(!Y(a,c+12|0,8)){break a}d=o[c+8>>2]|o[c+12>>2]<<8;o[c+8>>2]=d;if(!Y(a,c+12|0,8)){break a}d=d|o[c+12>>2]<<16;o[c+8>>2]=d;if(!Y(a,c+12|0,8)){break a}a=d|o[c+12>>2]<<24;o[c+8>>2]=a;o[b>>2]=a;e=1}N=c+16|0;return e}function Sb(a){a=a|0;var b=0,c=0;if(a){$a(a);b=o[a+4>>2];c=o[b+1120>>2];if(c){X(c);b=o[a+4>>2]}gb(o[b+56>>2]);aa(o[a+4>>2]+124|0);aa(o[a+4>>2]+136|0);aa(o[a+4>>2]+148|0);aa(o[a+4>>2]+160|0);aa(o[a+4>>2]+172|0);aa(o[a+4>>2]+184|0);aa(o[a+4>>2]+196|0);aa(o[a+4>>2]+208|0);X(o[a+4>>2]);X(o[a>>2]);X(a)}}function qb(a,b){var c=0,d=0,e=0;if(a){fa(a+8|0,352);o[a+24>>2]=1024;o[a+4>>2]=16384;d=da(16384);o[a>>2]=d;c=da(4096);o[a+16>>2]=c;e=da(8192);o[a+20>>2]=e;a:{if(d){if(c?e:0){break a}X(d);c=o[a+16>>2]}if(c){X(c)}b=o[a+20>>2];if(b){X(b)}fa(a,360);return-1}o[a+336>>2]=b;a=0}else{a=-1}return a}function Ba(a,b){var c=0,d=0,e=0,f=0,g=0,h=0;c=N-16|0;N=c;g=a;h=a;a:{if(!b){b=0;e=0;break a}d=b;b=x(b)^31;ia(c,d,0,0,0,112-b|0);b=(o[c+12>>2]^65536)+(b+16383<<16)|0;d=0+o[c+8>>2]|0;if(d>>>0<f>>>0){b=b+1|0}f=d;d=b;b=o[c+4>>2];e=o[c>>2]}o[h>>2]=e;o[g+4>>2]=b;o[a+8>>2]=f;o[a+12>>2]=d;N=c+16|0}function wa(a,b,c){var d=0,e=0,f=0,g=0;d=N-16|0;N=d;e=b;f=b;a:{b:{if(c>>>0>=33){if(!Y(a,d+12|0,c+ -32|0)){break a}if(!Y(a,d+8|0,32)){break a}a=o[d+12>>2];c=0;o[b>>2]=c;o[b+4>>2]=a;b=o[d+8>>2]|c;break b}if(!Y(a,d+8|0,c)){break a}a=0;b=o[d+8>>2]}o[f>>2]=b;o[e+4>>2]=a;g=1}N=d+16|0;return g}function pd(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=0;a=o[a>>2];if(o[a>>2]==1){g=c;h=a;i=b;e=o[1363];d=e&31;if(32<=(e&63)>>>0){e=-1<<d;d=0}else{e=(1<<d)-1&-1>>>32-d|-1<<d;d=-1<<d}f=d^-1;d=e^-1;b=(c|0)==(d|0)&f>>>0>b>>>0|d>>>0>c>>>0;o[h+592>>2]=b?i:f;o[a+596>>2]=b?g:d;a=1}else{a=0}return a}function ie(a){var b=0,c=0;a:{b:{c=o[a+4>>2];b=p[c|0];if(!b){break b}while(1){if((b+ -32&255)>>>0<95){c=c+1|0;b=p[c|0];if(b){continue}break b}break}c=0;break a}c=1;b=o[a+8>>2];if(!p[b|0]){break a}while(1){a=ec(b);if(!a){c=0;break a}b=a+b|0;if(p[b|0]){continue}break}}return c}function ge(a){var b=0,c=0,d=0,e=0,f=0,g=0,h=0;d=o[a>>2];if(!d){return 1}g=o[a+4>>2];a=0;e=1;while(1){h=c;f=b;b=u(a,24)+g|0;c=o[b>>2];b=o[b+4>>2];if(!((c|0)==-1&(b|0)==-1|e|((b|0)==(f|0)&c>>>0>h>>>0|b>>>0>f>>>0))){return 0}e=0;a=a+1|0;if(a>>>0<d>>>0){continue}break}return 1}function jb(a,b,c,d,e,f,g){a:{b:{if(!e){break b}c:{switch(l[e](a,b,c,g)|0){case 1:break a;case 0:break c;default:break b}}tb(d);if(l[f](a,o[d>>2],o[d+4>>2],0,0,g)){break a}if(!l[f](a,o[d+8>>2],o[d+12>>2],0,0,g)){return 1}o[o[a>>2]>>2]=5}return 0}o[o[a>>2]>>2]=5;return 0}function id(a,b){var c=0,d=v(0),e=v(0),f=0,g=v(0);if((b|0)>=1){e=v(b+ -1|0);while(1){d=v(v(c|0)/e);f=(c<<2)+a|0,g=v(+v(w(v(d+v(-.5))))*-.47999998927116394+.6200000047683716+ba(+d*6.283185307179586)*-.3799999952316284),s[f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function Ya(a){var b=0,c=0;a:{if(r[a+20>>2]<=r[a+28>>2]){break a}l[o[a+36>>2]](a,0,0)|0;if(o[a+20>>2]){break a}return-1}b=o[a+4>>2];c=o[a+8>>2];if(b>>>0<c>>>0){b=b-c|0;l[o[a+40>>2]](a,b,b>>31,1)|0}o[a+28>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;o[a+4>>2]=0;o[a+8>>2]=0;return 0}function Cb(a){var b=0,c=0,d=0,e=0;d=o[a+76>>2]>=0?1:d;e=o[a>>2]&1;if(!e){b=o[a+52>>2];if(b){o[b+56>>2]=o[a+56>>2]}c=o[a+56>>2];if(c){o[c+52>>2]=b}if(o[3023]==(a|0)){o[3023]=c}}Bb(a);l[o[a+12>>2]](a)|0;b=o[a+96>>2];if(b){X(b)}a:{if(!e){X(a);break a}if(!d){break a}}}function kd(a,b,c,d,e){a=o[a>>2];a:{if(!_(e,o[1418]|(d|0)!=0,o[1416]+(o[1415]+o[1414]|0)|0)){break a}if(d){if(!Qa(e,d+ -1|0)){break a}}if(!b){return 1}d=0;b:{while(1){if(!va(e,o[a+(d<<2)>>2],c)){break b}d=d+1|0;if((d|0)!=(b|0)){continue}break}return 1}}return 0}function xb(a,b){var c=0,d=0,i=0;h(+a);c=e(1)|0;d=e(0)|0;i=c;c=c>>>20&2047;if((c|0)!=2047){if(!c){c=b;if(a==0){b=0}else{a=xb(a*0x10000000000000000,b);b=o[b>>2]+ -64|0}o[c>>2]=b;return a}o[b>>2]=c+ -1022;f(0,d|0);f(1,i&-2146435073|1071644672);a=+g()}return a}function ab(a,b){var c=0,d=0,e=0,f=0;d=1;a:{if(r[a+8>>2]>=b>>>0){break a}d=o[a>>2];e=4<<b;c=ea(d,e);if(!(c|b>>>0>29)){X(d)}o[a>>2]=c;d=0;if(!c){break a}f=o[a+4>>2];c=ea(f,e);if(!(c|b>>>0>29)){X(f)}o[a+4>>2]=c;if(!c){break a}fa(c,e);o[a+8>>2]=b;d=1}return d}function hd(a,b){var c=0,d=0,e=0,f=0,g=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=+(c|0);f=(c<<2)+a|0,g=v(ba(e*12.566370614359172/d)*.07999999821186066+(ba(e*6.283185307179586/d)*-.5+.41999998688697815)),s[f>>2]=g;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function Hc(a){var b=0,c=0;b=p[a+74|0];m[a+74|0]=b+ -1|b;if(r[a+20>>2]>r[a+28>>2]){l[o[a+36>>2]](a,0,0)|0}o[a+28>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;b=o[a>>2];if(b&4){o[a>>2]=b|32;return-1}c=o[a+44>>2]+o[a+48>>2]|0;o[a+8>>2]=c;o[a+4>>2]=c;return b<<27>>31}function Za(a,b){var c=0,d=0,e=0,f=0;c=a*a;d=c*.5;e=1-d;f=1-e-d;d=c*c;return e+(f+(c*(c*(c*(c*2480158728947673e-20+ -.001388888888887411)+.0416666666666666)+d*d*(c*(c*-1.1359647557788195e-11+2.087572321298175e-9)+ -2.7557314351390663e-7))-a*b))}function Kc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;var e=0;e=N-16|0;N=e;a=I(o[a+60>>2],b|0,c|0,d&255,e+8|0)|0;b=0;a:{if(!a){break a}o[2896]=a;b=-1}b:{if(!b){b=o[e+12>>2];a=o[e+8>>2];break b}o[e+8>>2]=-1;o[e+12>>2]=-1;b=-1;a=-1}N=e+16|0;Q=b;return a|0}function ea(a,b){var c=0,d=0;if(!a){return da(b)}if(b>>>0>=4294967232){o[2896]=48;return 0}c=fc(a+ -8|0,b>>>0<11?16:b+11&-8);if(c){return c+8|0}c=da(b);if(!c){return 0}d=o[a+ -4>>2];d=(d&3?-4:-8)+(d&-8)|0;ca(c,a,d>>>0<b>>>0?d:b);X(a);return c}function Vd(a){var b=0;if(!qb(a+8|0,o[a+4>>2])){b=a+368|0;if(b){o[b>>2]=0;o[b+4>>2]=0;o[b+24>>2]=0;o[b+16>>2]=0;o[b+20>>2]=0;o[b+8>>2]=0;o[b+12>>2]=0}o[a+396>>2]=-1;o[a+400>>2]=-1;o[a+408>>2]=0;o[a+412>>2]=0;o[a+404>>2]=o[a>>2];b=1}return b}function ha(a,b,c){var d=0,e=0,f=0;if(!c){return 0}d=p[a|0];a:{if(!d){break a}while(1){b:{e=p[b|0];if((e|0)!=(d|0)){break b}c=c+ -1|0;if(!c|!e){break b}b=b+1|0;d=p[a+1|0];a=a+1|0;if(d){continue}break a}break}f=d}return(f&255)-p[b|0]|0}function Od(a){a=a|0;var b=0,c=0;a:{b:{while(1){c:{b=1;d:{switch(o[o[a>>2]>>2]){case 0:if(Va(a)){continue}break c;case 2:case 3:case 4:case 7:break b;case 1:break d;default:break a}}if(Ta(a)){continue}}break}b=0}c=b}return c|0}function Be(a,b,c,d){var e=0,f=0,g=0,h=0,i=0,j=0;e=c>>>16|0;f=a>>>16|0;j=u(e,f);g=c&65535;h=a&65535;i=u(g,h);f=(i>>>16|0)+u(f,g)|0;e=(f&65535)+u(e,h)|0;a=(u(b,c)+j|0)+u(a,d)+(f>>>16)+(e>>>16)|0;b=i&65535|e<<16;Q=a;return b}function cd(a,b){var c=0,d=0,e=0,f=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=(c<<2)+a|0,f=v(ba(+(c|0)*6.283185307179586/d)*-.46000000834465027+.5400000214576721),s[e>>2]=f;c=c+1|0;if((c|0)!=(b|0)){continue}break}}} + + + +function Xb(a){o[a+8>>2]=0;o[a+12>>2]=0;o[a>>2]=0;o[a+4>>2]=3;o[a+56>>2]=0;o[a+60>>2]=0;o[a+48>>2]=0;o[a+52>>2]=0;o[a+40>>2]=0;o[a+44>>2]=0;o[a+32>>2]=0;o[a+36>>2]=0;o[a+24>>2]=0;o[a+28>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0}function Ib(a,b){var c=0,d=0;c=a*a;d=c*a;return a-(c*(b*.5-d*(c*(c*c)*(c*1.58969099521155e-10+ -2.5050760253406863e-8)+(c*(c*27557313707070068e-22+ -.0001984126982985795)+.00833333333332249)))-b+d*.16666666666666632)}function pb(a){if(!(!a|!o[a>>2])){o[a+344>>2]=0;o[a+348>>2]=0;o[a+340>>2]=-1;o[a+332>>2]=0;o[a+324>>2]=0;o[a+328>>2]=0;o[a+36>>2]=0;o[a+28>>2]=0;o[a+32>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0;o[a+352>>2]=0;o[a+356>>2]=0}}function Bb(a){var b=0;if(a){if(o[a+76>>2]<=-1){return Ya(a)}return Ya(a)}if(o[2794]){b=Bb(o[2794])}a=o[3023];if(a){while(1){if(r[a+20>>2]>r[a+28>>2]){b=Ya(a)|b}a=o[a+56>>2];if(a){continue}break}}return b}function dd(a,b,c){var d=0,e=0,f=0,g=0,h=0,i=v(0);if((b|0)>=1){e=+(b+ -1|0)*.5;g=e*+c;while(1){f=(+(d|0)-e)/g;h=(d<<2)+a|0,i=v(Cc(f*(f*-.5))),s[h>>2]=i;d=d+1|0;if((d|0)!=(b|0)){continue}break}}}function ib(a,b){var c=0,d=0;c=p[a|0];d=p[b|0];a:{if(!c|(c|0)!=(d|0)){break a}while(1){d=p[b+1|0];c=p[a+1|0];if(!c){break a}b=b+1|0;a=a+1|0;if((c|0)==(d|0)){continue}break}}return c-d|0}function Da(a,b,c,d){var e=0;a:{if(d>>>0>=33){d=d+ -32|0;if(c>>>d|0?d>>>0<=31:0){break a}if(!Z(a,c,d)){break a}return(Z(a,b,32)|0)!=0}if(b>>>d|0?(d|0)!=32:0){break a}e=Z(a,b,d)}return e}function Lb(a,b){var c=0,d=0,e=0,f=v(0);if((b|0)>=1){d=+(b+ -1|0);while(1){e=(c<<2)+a|0,f=v(.5-ba(+(c|0)*6.283185307179586/d)*.5),s[e>>2]=f;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function Xa(a,b,c,d,e,f,g,h,i){var j=0;j=N-16|0;N=j;ja(j,b,c,d,e,f,g,h,i^-2147483648);b=o[j+4>>2];o[a>>2]=o[j>>2];o[a+4>>2]=b;b=o[j+12>>2];o[a+8>>2]=o[j+8>>2];o[a+12>>2]=b;N=j+16|0}function Hd(a){a=a|0;var b=0;if(o[o[a>>2]>>2]==9){b=o[a+4>>2];a=0;while(1){o[((a<<2)+b|0)+608>>2]=1;a=a+1|0;if((a|0)!=128){continue}break}o[b+1124>>2]=0;a=1}else{a=0}return a|0}function ya(a){var b=0,c=0;b=o[3544];c=a+3&-4;a=b+c|0;a:{if(a>>>0<=b>>>0?(c|0)>=1:0){break a}if(a>>>0>R()<<16>>>0){if(!J(a|0)){break a}}o[3544]=a;return b}o[2896]=48;return-1}function La(a,b){var c=0,d=0,e=0;e=a;a:{if(b>>>0<=31){c=o[a>>2];d=o[a+4>>2];break a}c=o[a+4>>2];o[a+4>>2]=0;o[a>>2]=c;b=b+ -32|0;d=0}o[e+4>>2]=d>>>b;o[a>>2]=d<<32-b|c>>>b}function qa(a,b){var c=0,d=0,e=0;c=0;a:{if(!a){break a}d=Ee(a,0,b,0);e=Q;c=d;if((a|b)>>>0<65536){break a}c=e?-1:d}b=c;a=da(b);if(!(!a|!(p[a+ -4|0]&3))){fa(a,b)}return a}function Td(a){pb(a+8|0);if(o[a+372>>2]>=0){o[a+376>>2]=0;o[a+380>>2]=0;o[a+392>>2]=0;o[a+384>>2]=0;o[a+388>>2]=0}o[a+408>>2]=0;o[a+412>>2]=0;if(o[a>>2]){o[a+404>>2]=1}}function Pa(a,b,c){var d=0,e=0,f=0;a:{if(!c){break a}while(1){d=p[a|0];e=p[b|0];if((d|0)==(e|0)){b=b+1|0;a=a+1|0;c=c+ -1|0;if(c){continue}break a}break}f=d-e|0}return f}function Ma(a,b){var c=0,d=0,e=0;e=a;a:{if(b>>>0<=31){c=o[a+4>>2];d=o[a>>2];break a}c=o[a>>2];o[a+4>>2]=c;o[a>>2]=0;b=b+ -32|0;d=0}o[e>>2]=d<<b;o[a+4>>2]=c<<b|d>>>32-b}function Ld(a,b){a=a|0;b=b|0;var c=0;a:{if(o[o[a>>2]>>2]!=9|b>>>0>126){break a}a=o[a+4>>2];o[(a+(b<<2)|0)+608>>2]=0;c=1;if((b|0)!=2){break a}o[a+1124>>2]=0}return c|0}function Id(a,b){a=a|0;b=b|0;var c=0;a:{if(o[o[a>>2]>>2]!=9|b>>>0>126){break a}c=1;a=o[a+4>>2];o[(a+(b<<2)|0)+608>>2]=1;if((b|0)!=2){break a}o[a+1124>>2]=0}return c|0}function nd(a,b,c,d){var e=0;a:{if(!_(d,o[1417]|(c|0)!=0,o[1416]+(o[1415]+o[1414]|0)|0)){break a}if(c){if(!Qa(d,c+ -1|0)){break a}}e=(va(d,o[a>>2],b)|0)!=0}return e}function kc(a,b){a=a|0;b=b|0;var c=0,d=0;c=o[a+4>>2];d=o[b+4>>2];a=o[a>>2];b=o[b>>2];return((a|0)==(b|0)&(c|0)==(d|0)?0:(c|0)==(d|0)&a>>>0<b>>>0|c>>>0<d>>>0?-1:1)|0}function rc(a,b){var c=0;if(o[a+4>>2]>=0){while(1){c=qc(a,b);if((c|0)>0){return 1}if(!c){return 0}if(o[a+16>>2]){continue}break}o[a+16>>2]=1;a=-1}else{a=0}return a}function ye(a,b){var c=0;o[a+8>>2]=0;o[a+12>>2]=0;o[a+4>>2]=2048;o[a+16>>2]=0;o[a+20>>2]=0;c=da(8192);o[a>>2]=c;if(!c){return 0}o[a+40>>2]=b;o[a+36>>2]=7;return 1}function uc(a,b){var c=0,d=0;if(!(!a|!o[a>>2])){d=o[a+28>>2];a:{b:{if(o[a+328>>2]){if(d){break b}break a}if(o[a+332>>2]|!d){break a}}c=1}c=rb(a,b,c)}return c}function fd(a,b){var c=0,d=0,e=0;if((b|0)>=1){e=+(b+ -1|0)*.5;while(1){c=(+(d|0)-e)/e;c=1-c*c;s[(d<<2)+a>>2]=c*c;d=d+1|0;if((d|0)!=(b|0)){continue}break}}}function ue(a,b){var c=0,d=0,e=0,f=0;c=N-16|0;N=c;d=0;a:{if(!cb(a,c+12|0,c+8|0)){break a}e=b,f=qe(o[c+12>>2],o[c+8>>2]),n[e>>1]=f;d=1}N=c+16|0;return d}function te(a,b){var c=0,d=0,e=0,f=0;c=N-16|0;N=c;d=0;a:{if(!cb(a,c+12|0,c+8|0)){break a}e=b,f=Vb(o[c+12>>2],o[c+8>>2]),m[e|0]=f;d=1}N=c+16|0;return d}function bb(a,b){var c=0;a:{if(!Z(a,b&255,8)){break a}if(!Z(a,b>>>8&255,8)){break a}if(!Z(a,b>>>16&255,8)){break a}c=(Z(a,b>>>24|0,8)|0)!=0}return c}function Wc(a,b){var c=0,d=0,e=0;if((b|0)>=1){d=+(b+ -1|0)*.5;while(1){e=(+(c|0)-d)/d;s[(c<<2)+a>>2]=1-e*e;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function ta(a,b,c){var d=0;a:{if(a>>>0>1073741823){break a}a=da(a?a<<2:1);if(!a){break a}d=o[b>>2];if(d){X(d)}o[b>>2]=a;o[c>>2]=a;d=1}return d}function Ae(a){var b=0;b=o[a>>2];if(b){X(b)}o[a+36>>2]=0;o[a+40>>2]=0;o[a>>2]=0;o[a+4>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0}function xc(a,b){var c=0;c=N-16|0;N=c;o[c+8>>2]=o[b>>2];o[c+12>>2]=o[b+4>>2];a=yc(a,c+8|0,o[b+12>>2],o[b+16>>2],o[b+20>>2]);N=c+16|0;return a}function Xd(a,b,c){var d=0;a:{if(a>>>0>536870911){break a}a=da(a?a<<3:1);if(!a){break a}d=o[b>>2];if(d){X(d)}o[b>>2]=a;o[c>>2]=a;d=1}return d}function Wd(a){pb(a+8|0);if(o[a+372>>2]>=0){o[a+376>>2]=0;o[a+380>>2]=0;o[a+392>>2]=0;o[a+384>>2]=0;o[a+388>>2]=0}o[a+408>>2]=0;o[a+412>>2]=0}function Qc(a,b,c,d){var e=0,f=0;f=d&65535;d=d>>>16&32767;a:{if((d|0)!=32767){e=4;if(d){break a}return a|c|(b|f)?3:2}e=!(a|c|(b|f))}return e}function Fc(a){var b=0,c=0;b=N-16|0;N=b;c=-1;a:{if(Hc(a)){break a}if((l[o[a+32>>2]](a,b+15|0,1)|0)!=1){break a}c=p[b+15|0]}N=b+16|0;return c}function xa(a,b,c){var d=0,e=0;d=N-16|0;N=d;e=0;a:{if(!Y(a,d+12|0,c)){break a}a=1<<c+ -1;o[b>>2]=(a^o[d+12>>2])-a;e=1}a=e;N=d+16|0;return a}function sc(a){var b=0;if(a){b=o[a>>2];if(b){X(b)}o[a>>2]=0;o[a+4>>2]=0;o[a+24>>2]=0;o[a+16>>2]=0;o[a+20>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0}}function ke(a){var b=0,c=0;a:{if(!(a&1)){while(1){b=b+1|0;c=a&2;a=a>>>1|0;if(!c){continue}break}a=15;if(b>>>0>14){break a}}a=b}return a}function pc(a,b){var c=0,d=0;c=-1;d=o[a+4>>2];a:{if((d|0)<0){break a}b=o[a+8>>2]+b|0;if((b|0)>(d|0)){break a}o[a+8>>2]=b;c=0}return c}function Yd(a,b,c,d){var e=0,f=0;if(d){while(1){f=e<<2;s[f+c>>2]=s[b+f>>2]*v(o[a+f>>2]);e=e+1|0;if((e|0)!=(d|0)){continue}break}}}function Qb(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;return wb(a,b,c,d,e,f,g,h,i,j,0)|0}function Pd(a,b,c,d,e,f,g,h,i,j){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;h=h|0;i=i|0;j=j|0;return wb(a,b,c,d,e,f,g,h,i,j,1)|0}function lc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;a=l[o[o[a+4>>2]+4>>2]](a,b,c,d)|0;if(a>>>0<=2){return o[(a<<2)+7572>>2]}return 5}function Fb(a,b,c,d,e,f,g,h,i){o[a>>2]=b;o[a+4>>2]=c;o[a+8>>2]=d;o[a+12>>2]=e&65535|(i>>>16&32768|e>>>16&32767)<<16}function Zc(a,b){var c=0;if((b|0)>=1){while(1){o[(c<<2)+a>>2]=1065353216;c=c+1|0;if((c|0)!=(b|0)){continue}break}}}function Sd(a){if(qb(a+8|0,o[a>>2])){a=0}else{o[a+392>>2]=0;o[a+396>>2]=0;o[a+384>>2]=0;o[a+388>>2]=1;a=1}return a}function Aa(a){var b=0;b=o[a>>2];if(b){X(b)}b=o[a+8>>2];if(b){X(b)}o[a>>2]=0;o[a+4>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0}function Kd(a){a=a|0;if(o[o[a>>2]>>2]==9){fa(o[a+4>>2]+608|0,512);o[o[a+4>>2]+1124>>2]=0;a=1}else{a=0}return a|0}function Vb(a,b){var c=0;if(b){while(1){c=p[(p[a|0]^c)+1024|0];a=a+1|0;b=b+ -1|0;if(b){continue}break}}return c}function oa(a){var b=0,c=0;b=N-16|0;N=b;gc(b,a);c=Gc(o[b>>2],o[b+4>>2],o[b+8>>2],o[b+12>>2]);N=b+16|0;return c}function sb(a){var b=0;if(a){b=o[a>>2];if(b){X(b)}b=o[a+16>>2];if(b){X(b)}b=o[a+20>>2];if(b){X(b)}fa(a,360)}}function de(a,b){if(!!(a>0)){a=la(.5/+(b>>>0)*a)*.5/.6931471805599453;return a>=0?a:0}return a<0?1e+32:0}function Fd(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==9){o[a+36>>2]=b;o[a+32>>2]=0;a=1}else{a=0}return a|0}function je(a,b,c){var d=0;while(1){d=a;if(d){a=d+ -1|0;if(b>>>d>>>0<=c>>>0){continue}}break}return d}function aa(a){var b=0;b=o[a>>2];if(b){X(b)}b=o[a+4>>2];if(b){X(b)}o[a+8>>2]=0;o[a>>2]=0;o[a+4>>2]=0}function Bd(a,b,c,d,e,f,g){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;g=g|0;return vb(a,b,c,d,e,f,g,1)|0}function he(a){if(a+ -1>>>0<=655349){return!((a>>>0)%10)|(!((a>>>0)%1e3)|a>>>0<65536)}return 0}function Qa(a,b){if(b>>>0<=31){return Z(a,1,b+1|0)}if(!Ca(a,b)){return 0}return(Z(a,1,1)|0)!=0}function ve(a){var b=0;b=o[a>>2];if(b){X(b)}o[a+16>>2]=0;o[a>>2]=0;o[a+8>>2]=0;o[a+12>>2]=0}function rd(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+632>>2]=b;a=1}else{a=0}return a|0}function Na(a,b){if(!(b?a:0)){return da(1)}Ee(b,0,a,0);if(Q){a=0}else{a=da(u(a,b))}return a}function He(a,b){var c=0,d=0;c=b&31;d=(-1>>>c&a)<<c;c=a;a=0-b&31;return d|(c&-1<<a)>>>a} + + + +function Cd(a){a=a|0;if(!o[o[a>>2]+4>>2]){return 9}return o[o[o[o[a+4>>2]+11752>>2]>>2]>>2]}function wd(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+28>>2]=b;a=1}else{a=0}return a|0}function vd(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+36>>2]=b;a=1}else{a=0}return a|0}function ud(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+24>>2]=b;a=1}else{a=0}return a|0}function qd(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+32>>2]=b;a=1}else{a=0}return a|0}function Md(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==9){o[a+28>>2]=b;a=1}else{a=0}return a|0}function od(a,b){a=a|0;b=b|0;a=o[a>>2];if(o[a>>2]==1){o[a+4>>2]=b;a=1}else{a=0}return a|0}function Ad(a,b,c,d,e,f){a=a|0;b=b|0;c=c|0;d=d|0;e=e|0;f=f|0;return vb(a,0,b,c,d,e,f,0)|0}function _(a,b,c){var d=0;a:{if(c>>>0<=31){d=0;if(b>>>c){break a}}d=Z(a,b,c)}return d}function ub(a){a=+H(+a);if(w(a)<2147483648){return~~a}return-2147483648}function va(a,b,c){return Z(a,(c>>>0<32?-1<<c^-1:-1)&b,c)}function Uc(a,b,c,d){a=a|0;b=b|0;c=c|0;d=d|0;Q=0;return 0}function Ac(a,b,c){a=a|0;b=b|0;c=c|0;return pd(a,b,c)|0}function Ha(a,b){a=Ic(a,b);return p[a|0]==(b&255)?a:0}function De(a){if(a){return 31-x(a+ -1^a)|0}return 32}function dc(a,b,c){a=a|0;b=b|0;c=c|0;o[o[c>>2]>>2]=3}function gb(a){var b=0;b=o[a>>2];if(b){X(b)}X(a)}function jc(a){a=a|0;a=N-a&-16;N=a;return a|0}function Qd(a){a=a|0;return o[o[a>>2]+28>>2]}function Mc(a){a=a|0;return M(o[a+60>>2])|0}function Ee(a,b,c,d){a=Be(a,b,c,d);return a}function Dd(a){a=a|0;return o[o[a>>2]+4>>2]}function Rb(a){a=a|0;return o[o[a>>2]>>2]}function Ge(a,b){Ce(a,b,588);Q=P;return O}function cc(a,b,c){a=a|0;b=b|0;c=c|0}function Pc(a){a=a|0;return S(a|0)|0}function Fe(a,b,c){return Ce(a,b,c)}function Vc(a){a=a|0;return 0}function Tc(){return 11584}function ic(a){a=a|0;N=a}function hc(){return N|0}function Ec(){} +// EMSCRIPTEN_END_FUNCS +l[1]=kc;l[2]=Mc;l[3]=Lc;l[4]=Kc;l[5]=_d;l[6]=Zd;l[7]=mc;l[8]=lc;l[9]=Vc;l[10]=Jc;l[11]=Uc;l[12]=be;l[13]=ae;l[14]=oe;l[15]=pe;l[16]=oc;l[17]=fe;l[18]=bc;l[19]=ac;l[20]=cc;l[21]=dc;function R(){return buffer.byteLength/65536|0}function S(pagesToAdd){pagesToAdd=pagesToAdd|0;var T=R()|0;var U=T+pagesToAdd|0;if(T<U&&U<65536){var V=new ArrayBuffer(u(U,65536));var W=new global.Int8Array(V);W.set(m);m=W;m=new global.Int8Array(V);n=new global.Int16Array(V);o=new global.Int32Array(V);p=new global.Uint8Array(V);q=new global.Uint16Array(V);r=new global.Uint32Array(V);s=new global.Float32Array(V);t=new global.Float64Array(V);buffer=V;k.buffer=V}return T}return{"__wasm_call_ctors":Ec,"FLAC__stream_decoder_new":Pb,"FLAC__stream_decoder_delete":Sb,"FLAC__stream_decoder_finish":$a,"FLAC__stream_decoder_init_stream":Qb,"FLAC__stream_decoder_reset":Nb,"FLAC__stream_decoder_init_ogg_stream":Pd,"FLAC__stream_decoder_set_ogg_serial_number":Fd,"FLAC__stream_decoder_set_md5_checking":Md,"FLAC__stream_decoder_set_metadata_respond":Id,"FLAC__stream_decoder_set_metadata_respond_application":Gd,"FLAC__stream_decoder_set_metadata_respond_all":Hd,"FLAC__stream_decoder_set_metadata_ignore":Ld,"FLAC__stream_decoder_set_metadata_ignore_application":Jd,"FLAC__stream_decoder_set_metadata_ignore_all":Kd,"FLAC__stream_decoder_get_state":Rb,"FLAC__stream_decoder_get_md5_checking":Qd,"FLAC__stream_decoder_process_single":Ob,"FLAC__stream_decoder_process_until_end_of_metadata":Od,"FLAC__stream_decoder_process_until_end_of_stream":Nd,"FLAC__stream_encoder_new":zd,"FLAC__stream_encoder_delete":Ed,"FLAC__stream_encoder_finish":Mb,"FLAC__stream_encoder_init_stream":Ad,"FLAC__stream_encoder_init_ogg_stream":Bd,"FLAC__stream_encoder_set_ogg_serial_number":rd,"FLAC__stream_encoder_set_verify":od,"FLAC__stream_encoder_set_channels":ud,"FLAC__stream_encoder_set_bits_per_sample":wd,"FLAC__stream_encoder_set_sample_rate":qd,"FLAC__stream_encoder_set_compression_level":td,"FLAC__stream_encoder_set_blocksize":vd,"FLAC__stream_encoder_set_total_samples_estimate":Ac,"FLAC__stream_encoder_set_metadata":sd,"FLAC__stream_encoder_get_state":Rb,"FLAC__stream_encoder_get_verify_decoder_state":Cd,"FLAC__stream_encoder_get_verify":Dd,"FLAC__stream_encoder_process":yd,"FLAC__stream_encoder_process_interleaved":xd,"__errno_location":Tc,"stackSave":hc,"stackRestore":ic,"stackAlloc":jc,"malloc":da,"free":X,"__growWasmMemory":Pc}}return j({"Int8Array":Int8Array,"Int16Array":Int16Array,"Int32Array":Int32Array,"Uint8Array":Uint8Array,"Uint16Array":Uint16Array,"Uint32Array":Uint32Array,"Float32Array":Float32Array,"Float64Array":Float64Array,"NaN":NaN,"Infinity":Infinity,"Math":Math},asmLibraryArg,wasmMemory.buffer)} + + +// EMSCRIPTEN_END_ASM + + + + +)(asmLibraryArg,wasmMemory,wasmTable)},instantiate:function(binary,info){return{then:function(ok){ok({"instance":new WebAssembly.Instance(new WebAssembly.Module(binary))})}}},RuntimeError:Error};wasmBinary=[];if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}function getValue(ptr,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":return HEAP8[ptr>>0];case"i8":return HEAP8[ptr>>0];case"i16":return HEAP16[ptr>>1];case"i32":return HEAP32[ptr>>2];case"i64":return HEAP32[ptr>>2];case"float":return HEAPF32[ptr>>2];case"double":return HEAPF64[ptr>>3];default:abort("invalid type for getValue: "+type)}return null}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":22,"maximum":22+5,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i<args.length;i++){var converter=toC[argTypes[i]];if(converter){if(stack===0)stack=stackSave();cArgs[i]=converter(args[i])}else{cArgs[i]=args[i]}}}var ret=func.apply(null,cArgs);ret=convertReturnValue(ret);if(stack!==0)stackRestore(stack);return ret}function cwrap(ident,returnType,argTypes,opts){argTypes=argTypes||[];var numericArgs=argTypes.every(function(type){return type==="number"});var numericRet=returnType!=="string";if(numericRet&&numericArgs&&!opts){return getCFunc(ident)}return function(){return ccall(ident,returnType,argTypes,arguments,opts)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;function UTF8ArrayToString(heap,idx,maxBytesToRead){var endIdx=idx+maxBytesToRead;var endPtr=idx;while(heap[endPtr]&&!(endPtr>=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx<endPtr){var u0=heap[idx++];if(!(u0&128)){str+=String.fromCharCode(u0);continue}var u1=heap[idx++]&63;if((u0&224)==192){str+=String.fromCharCode((u0&31)<<6|u1);continue}var u2=heap[idx++]&63;if((u0&240)==224){u0=(u0&15)<<12|u1<<6|u2}else{u0=(u0&7)<<18|u1<<12|u2<<6|heap[idx++]&63}if(u0<65536){str+=String.fromCharCode(u0)}else{var ch=u0-65536;str+=String.fromCharCode(55296|ch>>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i<str.length;++i){var u=str.charCodeAt(i);if(u>=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var DYNAMIC_BASE=5257216,DYNAMICTOP_PTR=14176;var INITIAL_INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_INITIAL_MEMORY/WASM_PAGE_SIZE,"maximum":2147483648/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_INITIAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;what="abort("+what+"). Build with -s ASSERTIONS=1 for more info.";throw new WebAssembly.RuntimeError(what)}var memoryInitializer="libflac.min.js.mem";function hasPrefix(str,prefix){return String.prototype.startsWith?str.startsWith(prefix):str.indexOf(prefix)===0}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return hasPrefix(filename,dataURIPrefix)}var fileURIPrefix="file://";function isFileURI(filename){return hasPrefix(filename,fileURIPrefix)}var wasmBinaryFile="libflac.min.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"&&!isFileURI(wasmBinaryFile)){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"env":asmLibraryArg,"wasi_snapshot_preview1":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&!isFileURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;__ATINIT__.push({func:function(){___wasm_call_ctors()}});function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function _emscripten_get_heap_size(){return HEAPU8.length}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){requestedSize=requestedSize>>>0;var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var maxHeapSize=2147483648;if(requestedSize>maxHeapSize){return false}var minHeapSize=16777216;for(var cutDown=1;cutDown<=4;cutDown*=2){var overGrownHeapSize=oldSize*(1+.2/cutDown);overGrownHeapSize=Math.min(overGrownHeapSize,requestedSize+100663296);var newSize=Math.min(maxHeapSize,alignUp(Math.max(minHeapSize,requestedSize,overGrownHeapSize),PAGE_MULTIPLE));var replacement=emscripten_realloc_buffer(newSize);if(replacement){return true}}return false}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};function setErrNo(value){HEAP32[___errno_location()>>2]=value;return value}var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")}};var TTY={ttys:[],init:function(){},shutdown:function(){},register:function(dev,ops){TTY.ttys[dev]={input:[],output:[],ops:ops};FS.registerDevice(dev,TTY.stream_ops)},stream_ops:{open:function(stream){var tty=TTY.ttys[stream.node.rdev];if(!tty){throw new FS.ErrnoError(43)}stream.tty=tty;stream.seekable=false},close:function(stream){stream.tty.ops.flush(stream.tty)},flush:function(stream){stream.tty.ops.flush(stream.tty)},read:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.get_char){throw new FS.ErrnoError(60)}var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=stream.tty.ops.get_char(stream.tty)}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){if(!stream.tty||!stream.tty.ops.put_char){throw new FS.ErrnoError(60)}try{for(var i=0;i<length;i++){stream.tty.ops.put_char(stream.tty,buffer[offset+i])}}catch(e){throw new FS.ErrnoError(29)}if(length){stream.node.timestamp=Date.now()}return i}},default_tty_ops:{get_char:function(tty){if(!tty.input.length){var result=null;if(ENVIRONMENT_IS_NODE){var BUFSIZE=256;var buf=Buffer.alloc?Buffer.alloc(BUFSIZE):new Buffer(BUFSIZE);var bytesRead=0;try{bytesRead=nodeFS.readSync(process.stdin.fd,buf,0,BUFSIZE,null)}catch(e){if(e.toString().indexOf("EOF")!=-1)bytesRead=0;else throw e}if(bytesRead>0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node},getFileDataAsRegularArray:function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i<node.usedBytes;++i)arr.push(node.contents[i]);return arr}return node.contents},getFileDataAsTypedArray:function(node){if(!node.contents)return new Uint8Array(0);if(node.contents.subarray)return node.contents.subarray(0,node.usedBytes);return new Uint8Array(node.contents)},expandFileStorage:function(node,newCapacity){var prevCapacity=node.contents?node.contents.length:0;if(prevCapacity>=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity<CAPACITY_DOUBLING_MAX?2:1.125)>>>0);if(prevCapacity!=0)newCapacity=Math.max(newCapacity,256);var oldContents=node.contents;node.contents=new Uint8Array(newCapacity);if(node.usedBytes>0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(newSize);if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length<newSize)node.contents.push(0);node.usedBytes=newSize},node_ops:{getattr:function(node){var attr={};attr.dev=FS.isChrdev(node.mode)?node.id:1;attr.ino=node.id;attr.mode=node.mode;attr.nlink=1;attr.uid=0;attr.gid=0;attr.rdev=node.rdev;if(FS.isDir(node.mode)){attr.size=4096}else if(FS.isFile(node.mode)){attr.size=node.usedBytes}else if(FS.isLink(node.mode)){attr.size=node.link.length}else{attr.size=0}attr.atime=new Date(node.timestamp);attr.mtime=new Date(node.timestamp);attr.ctime=new Date(node.timestamp);attr.blksize=4096;attr.blocks=Math.ceil(attr.size/attr.blksize);return attr},setattr:function(node,attr){if(attr.mode!==undefined){node.mode=attr.mode}if(attr.timestamp!==undefined){node.timestamp=attr.timestamp}if(attr.size!==undefined){MEMFS.resizeFileStorage(node,attr.size)}},lookup:function(parent,name){throw FS.genericErrors[44]},mknod:function(parent,name,mode,dev){return MEMFS.createNode(parent,name,mode,dev)},rename:function(old_node,new_dir,new_name){if(FS.isDir(old_node.mode)){var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(new_node){for(var i in new_node.contents){throw new FS.ErrnoError(55)}}}delete old_node.parent.contents[old_node.name];old_node.name=new_name;new_dir.contents[new_name]=old_node;old_node.parent=new_dir},unlink:function(parent,name){delete parent.contents[name]},rmdir:function(parent,name){var node=FS.lookupNode(parent,name);for(var i in node.contents){throw new FS.ErrnoError(55)}delete parent.contents[name]},readdir:function(node){var entries=[".",".."];for(var key in node.contents){if(!node.contents.hasOwnProperty(key)){continue}entries.push(key)}return entries},symlink:function(parent,newname,oldpath){var node=MEMFS.createNode(parent,newname,511|40960,0);node.link=oldpath;return node},readlink:function(node){if(!FS.isLink(node.mode)){throw new FS.ErrnoError(28)}return node.link}},stream_ops:{read:function(stream,buffer,offset,length,position){var contents=stream.node.contents;if(position>=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i<size;i++)buffer[offset+i]=contents[position+i]}return size},write:function(stream,buffer,offset,length,position,canOwn){if(buffer.buffer===HEAP8.buffer){canOwn=false}if(!length)return 0;var node=stream.node;node.timestamp=Date.now();if(buffer.subarray&&(!node.contents||node.contents.subarray)){if(canOwn){node.contents=buffer.subarray(offset,offset+length);node.usedBytes=length;return length}else if(node.usedBytes===0&&position===0){node.contents=buffer.slice(offset,offset+length);node.usedBytes=length;return length}else if(position+length<=node.usedBytes){node.contents.set(buffer.subarray(offset,offset+length),position);return length}}MEMFS.expandFileStorage(node,position+length);if(node.contents.subarray&&buffer.subarray)node.contents.set(buffer.subarray(offset,offset+length),position);else{for(var i=0;i<length;i++){node.contents[position+i]=buffer[offset+i]}}node.usedBytes=Math.max(node.usedBytes,position+length);return length},llseek:function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.usedBytes}}if(position<0){throw new FS.ErrnoError(28)}return position},allocate:function(stream,offset,length){MEMFS.expandFileStorage(stream.node,offset+length);stream.node.usedBytes=Math.max(stream.node.usedBytes,offset+length)},mmap:function(stream,address,length,position,prot,flags){assert(address===0);if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}var ptr;var allocated;var contents=stream.node.contents;if(!(flags&2)&&contents.buffer===buffer){allocated=false;ptr=contents.byteOffset}else{if(position>0||position+length<contents.length){if(contents.subarray){contents=contents.subarray(position,position+length)}else{contents=Array.prototype.slice.call(contents,position,position+length)}}allocated=true;ptr=_malloc(length);if(!ptr){throw new FS.ErrnoError(48)}HEAP8.set(contents,ptr)}return{ptr:ptr,allocated:allocated}},msync:function(stream,buffer,offset,length,mmapFlags){if(!FS.isFile(stream.node.mode)){throw new FS.ErrnoError(43)}if(mmapFlags&2){return 0}var bytesWritten=MEMFS.stream_ops.write(stream,buffer,0,length,offset,false);return 0}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e){if(!(e instanceof FS.ErrnoError))throw e+" : "+stackTrace();return setErrNo(e.errno)},lookupPath:function(path,opts){path=PATH_FS.resolve(FS.cwd(),path);opts=opts||{};if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};for(var key in defaults){if(opts[key]===undefined){opts[key]=defaults[key]}}if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i<parts.length;i++){var islast=i===parts.length-1;if(islast&&opts.parent){break}current=FS.lookupNode(current,parts[i]);current_path=PATH.join2(current_path,parts[i]);if(FS.isMountpoint(current)){if(!islast||islast&&opts.follow_mount){current=current.mounted.root}}if(!islast||opts.follow){var count=0;while(FS.isLink(current.mode)){var link=FS.readlink(current_path);current_path=PATH_FS.resolve(PATH.dirname(current_path),link);var lookup=FS.lookupPath(current_path,{recurse_count:opts.recurse_count});current=lookup.node;if(count++>40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i<name.length;i++){hash=(hash<<5)-hash+name.charCodeAt(i)|0}return(parentid+hash>>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var errCode=FS.mayLookup(parent);if(errCode){throw new FS.ErrnoError(errCode,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var errCode=FS.nodePermissions(dir,"x");if(errCode)return errCode;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var errCode=FS.nodePermissions(dir,"wx");if(errCode){return errCode}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}}}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){err("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(errCode){FS.syncFSRequests--;return callback(errCode)}function done(errCode){if(errCode){if(!done.errored){done.errored=true;return doCallback(errCode)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var errCode=FS.mayCreate(parent,name);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;i<dirs.length;++i){if(!dirs[i])continue;d+="/"+dirs[i];try{FS.mkdir(d,mode)}catch(e){if(e.errno!=20)throw e}}},mkdev:function(path,mode,dev){if(typeof dev==="undefined"){dev=mode;mode=438}mode|=8192;return FS.mknod(path,mode,dev)},symlink:function(oldpath,newpath){if(!PATH_FS.resolve(oldpath)){throw new FS.ErrnoError(44)}var lookup=FS.lookupPath(newpath,{parent:true});var parent=lookup.node;if(!parent){throw new FS.ErrnoError(44)}var newname=PATH.basename(newpath);var errCode=FS.mayCreate(parent,newname);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.symlink){throw new FS.ErrnoError(63)}return parent.node_ops.symlink(parent,newname,oldpath)},rename:function(old_path,new_path){var old_dirname=PATH.dirname(old_path);var new_dirname=PATH.dirname(new_path);var old_name=PATH.basename(old_path);var new_name=PATH.basename(new_path);var lookup,old_dir,new_dir;try{lookup=FS.lookupPath(old_path,{parent:true});old_dir=lookup.node;lookup=FS.lookupPath(new_path,{parent:true});new_dir=lookup.node}catch(e){throw new FS.ErrnoError(10)}if(!old_dir||!new_dir)throw new FS.ErrnoError(44);if(old_dir.mount!==new_dir.mount){throw new FS.ErrnoError(75)}var old_node=FS.lookupNode(old_dir,old_name);var relative=PATH_FS.relative(old_path,new_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(28)}relative=PATH_FS.relative(new_path,old_dirname);if(relative.charAt(0)!=="."){throw new FS.ErrnoError(55)}var new_node;try{new_node=FS.lookupNode(new_dir,new_name)}catch(e){}if(old_node===new_node){return}var isdir=FS.isDir(old_node.mode);var errCode=FS.mayDelete(old_dir,old_name,isdir);if(errCode){throw new FS.ErrnoError(errCode)}errCode=new_node?FS.mayDelete(new_dir,new_name,isdir):FS.mayCreate(new_dir,new_name);if(errCode){throw new FS.ErrnoError(errCode)}if(!old_dir.node_ops.rename){throw new FS.ErrnoError(63)}if(FS.isMountpoint(old_node)||new_node&&FS.isMountpoint(new_node)){throw new FS.ErrnoError(10)}if(new_dir!==old_dir){errCode=FS.nodePermissions(old_dir,"w");if(errCode){throw new FS.ErrnoError(errCode)}}try{if(FS.trackingDelegate["willMovePath"]){FS.trackingDelegate["willMovePath"](old_path,new_path)}}catch(e){err("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}FS.hashRemoveNode(old_node);try{old_dir.node_ops.rename(old_node,new_dir,new_name)}catch(e){throw e}finally{FS.hashAddNode(old_node)}try{if(FS.trackingDelegate["onMovePath"])FS.trackingDelegate["onMovePath"](old_path,new_path)}catch(e){err("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: "+e.message)}},rmdir:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,true);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.rmdir){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.rmdir(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readdir:function(path){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;if(!node.node_ops.readdir){throw new FS.ErrnoError(54)}return node.node_ops.readdir(node)},unlink:function(path){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);var node=FS.lookupNode(parent,name);var errCode=FS.mayDelete(parent,name,false);if(errCode){throw new FS.ErrnoError(errCode)}if(!parent.node_ops.unlink){throw new FS.ErrnoError(63)}if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}try{if(FS.trackingDelegate["willDeletePath"]){FS.trackingDelegate["willDeletePath"](path)}}catch(e){err("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: "+e.message)}parent.node_ops.unlink(parent,name);FS.destroyNode(node);try{if(FS.trackingDelegate["onDeletePath"])FS.trackingDelegate["onDeletePath"](path)}catch(e){err("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: "+e.message)}},readlink:function(path){var lookup=FS.lookupPath(path);var link=lookup.node;if(!link){throw new FS.ErrnoError(44)}if(!link.node_ops.readlink){throw new FS.ErrnoError(28)}return PATH_FS.resolve(FS.getPath(link.parent),link.node_ops.readlink(link))},stat:function(path,dontFollow){var lookup=FS.lookupPath(path,{follow:!dontFollow});var node=lookup.node;if(!node){throw new FS.ErrnoError(44)}if(!node.node_ops.getattr){throw new FS.ErrnoError(63)}return node.node_ops.getattr(node)},lstat:function(path){return FS.stat(path,true)},chmod:function(path,mode,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{mode:mode&4095|node.mode&~4095,timestamp:Date.now()})},lchmod:function(path,mode){FS.chmod(path,mode,true)},fchmod:function(fd,mode){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chmod(stream.node,mode)},chown:function(path,uid,gid,dontFollow){var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:!dontFollow});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}node.node_ops.setattr(node,{timestamp:Date.now()})},lchown:function(path,uid,gid){FS.chown(path,uid,gid,true)},fchown:function(fd,uid,gid){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}FS.chown(stream.node,uid,gid)},truncate:function(path,len){if(len<0){throw new FS.ErrnoError(28)}var node;if(typeof path==="string"){var lookup=FS.lookupPath(path,{follow:true});node=lookup.node}else{node=path}if(!node.node_ops.setattr){throw new FS.ErrnoError(63)}if(FS.isDir(node.mode)){throw new FS.ErrnoError(31)}if(!FS.isFile(node.mode)){throw new FS.ErrnoError(28)}var errCode=FS.nodePermissions(node,"w");if(errCode){throw new FS.ErrnoError(errCode)}node.node_ops.setattr(node,{size:len,timestamp:Date.now()})},ftruncate:function(fd,len){var stream=FS.getStream(fd);if(!stream){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(28)}FS.truncate(stream.node,len)},utime:function(path,atime,mtime){var lookup=FS.lookupPath(path,{follow:true});var node=lookup.node;node.node_ops.setattr(node,{timestamp:Math.max(atime,mtime)})},open:function(path,flags,mode,fd_start,fd_end){if(path===""){throw new FS.ErrnoError(44)}flags=typeof flags==="string"?FS.modeStringToFlags(flags):flags;mode=typeof mode==="undefined"?438:mode;if(flags&64){mode=mode&4095|32768}else{mode=0}var node;if(typeof path==="object"){node=path}else{path=PATH.normalize(path);try{var lookup=FS.lookupPath(path,{follow:!(flags&131072)});node=lookup.node}catch(e){}}var created=false;if(flags&64){if(node){if(flags&128){throw new FS.ErrnoError(20)}}else{node=FS.mknod(path,mode,0);created=true}}if(!node){throw new FS.ErrnoError(44)}if(FS.isChrdev(node.mode)){flags&=~512}if(flags&65536&&!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}if(!created){var errCode=FS.mayOpen(node,flags);if(errCode){throw new FS.ErrnoError(errCode)}}if(flags&512){FS.truncate(node,0)}flags&=~(128|512|131072);var stream=FS.createStream({node:node,path:FS.getPath(node),flags:flags,seekable:true,position:0,stream_ops:node.stream_ops,ungotten:[],error:false},fd_start,fd_end);if(stream.stream_ops.open){stream.stream_ops.open(stream)}if(Module["logReadFiles"]&&!(flags&1)){if(!FS.readFiles)FS.readFiles={};if(!(path in FS.readFiles)){FS.readFiles[path]=1;err("FS.trackingDelegate error on read file: "+path)}}try{if(FS.trackingDelegate["onOpenFile"]){var trackingFlags=0;if((flags&2097155)!==1){trackingFlags|=FS.tracking.openFlags.READ}if((flags&2097155)!==0){trackingFlags|=FS.tracking.openFlags.WRITE}FS.trackingDelegate["onOpenFile"](path,trackingFlags)}}catch(e){err("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: "+e.message)}return stream},close:function(stream){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(stream.getdents)stream.getdents=null;try{if(stream.stream_ops.close){stream.stream_ops.close(stream)}}catch(e){throw e}finally{FS.closeStream(stream.fd)}stream.fd=null},isClosed:function(stream){return stream.fd===null},llseek:function(stream,offset,whence){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(!stream.seekable||!stream.stream_ops.llseek){throw new FS.ErrnoError(70)}if(whence!=0&&whence!=1&&whence!=2){throw new FS.ErrnoError(28)}stream.position=stream.stream_ops.llseek(stream,offset,whence);stream.ungotten=[];return stream.position},read:function(stream,buffer,offset,length,position){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.read){throw new FS.ErrnoError(28)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesRead=stream.stream_ops.read(stream,buffer,offset,length,position);if(!seeking)stream.position+=bytesRead;return bytesRead},write:function(stream,buffer,offset,length,position,canOwn){if(length<0||position<0){throw new FS.ErrnoError(28)}if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(FS.isDir(stream.node.mode)){throw new FS.ErrnoError(31)}if(!stream.stream_ops.write){throw new FS.ErrnoError(28)}if(stream.seekable&&stream.flags&1024){FS.llseek(stream,0,2)}var seeking=typeof position!=="undefined";if(!seeking){position=stream.position}else if(!stream.seekable){throw new FS.ErrnoError(70)}var bytesWritten=stream.stream_ops.write(stream,buffer,offset,length,position,canOwn);if(!seeking)stream.position+=bytesWritten;try{if(stream.path&&FS.trackingDelegate["onWriteToFile"])FS.trackingDelegate["onWriteToFile"](stream.path)}catch(e){err("FS.trackingDelegate['onWriteToFile']('"+stream.path+"') threw an exception: "+e.message)}return bytesWritten},allocate:function(stream,offset,length){if(FS.isClosed(stream)){throw new FS.ErrnoError(8)}if(offset<0||length<=0){throw new FS.ErrnoError(28)}if((stream.flags&2097155)===0){throw new FS.ErrnoError(8)}if(!FS.isFile(stream.node.mode)&&!FS.isDir(stream.node.mode)){throw new FS.ErrnoError(43)}if(!stream.stream_ops.allocate){throw new FS.ErrnoError(138)}stream.stream_ops.allocate(stream,offset,length)},mmap:function(stream,address,length,position,prot,flags){if((prot&2)!==0&&(flags&2)===0&&(stream.flags&2097155)!==2){throw new FS.ErrnoError(2)}if((stream.flags&2097155)===1){throw new FS.ErrnoError(2)}if(!stream.stream_ops.mmap){throw new FS.ErrnoError(43)}return stream.stream_ops.mmap(stream,address,length,position,prot,flags)},msync:function(stream,buffer,offset,length,mmapFlags){if(!stream||!stream.stream_ops.msync){return 0}return stream.stream_ops.msync(stream,buffer,offset,length,mmapFlags)},munmap:function(stream){return 0},ioctl:function(stream,cmd,arg){if(!stream.stream_ops.ioctl){throw new FS.ErrnoError(59)}return stream.stream_ops.ioctl(stream,cmd,arg)},readFile:function(path,opts){opts=opts||{};opts.flags=opts.flags||"r";opts.encoding=opts.encoding||"binary";if(opts.encoding!=="utf8"&&opts.encoding!=="binary"){throw new Error('Invalid encoding type "'+opts.encoding+'"')}var ret;var stream=FS.open(path,opts.flags);var stat=FS.stat(path);var length=stat.size;var buf=new Uint8Array(length);FS.read(stream,buf,0,length,0);if(opts.encoding==="utf8"){ret=UTF8ArrayToString(buf,0)}else if(opts.encoding==="binary"){ret=buf}FS.close(stream);return ret},writeFile:function(path,data,opts){opts=opts||{};opts.flags=opts.flags||"w";var stream=FS.open(path,opts.flags,opts.mode);if(typeof data==="string"){var buf=new Uint8Array(lengthBytesUTF8(data)+1);var actualNumBytes=stringToUTF8Array(data,buf,0,buf.length);FS.write(stream,buf,0,actualNumBytes,undefined,opts.canOwn)}else if(ArrayBuffer.isView(data)){FS.write(stream,data,0,data.byteLength,undefined,opts.canOwn)}else{throw new Error("Unsupported data type")}FS.close(stream)},cwd:function(){return FS.currentPath},chdir:function(path){var lookup=FS.lookupPath(path,{follow:true});if(lookup.node===null){throw new FS.ErrnoError(44)}if(!FS.isDir(lookup.node.mode)){throw new FS.ErrnoError(54)}var errCode=FS.nodePermissions(lookup.node,"x");if(errCode){throw new FS.ErrnoError(errCode)}FS.currentPath=lookup.path},createDefaultDirectories:function(){FS.mkdir("/tmp");FS.mkdir("/home");FS.mkdir("/home/web_user")},createDefaultDevices:function(){FS.mkdir("/dev");FS.registerDevice(FS.makedev(1,3),{read:function(){return 0},write:function(stream,buffer,offset,length,pos){return length}});FS.mkdev("/dev/null",FS.makedev(1,3));TTY.register(FS.makedev(5,0),TTY.default_tty_ops);TTY.register(FS.makedev(6,0),TTY.default_tty1_ops);FS.mkdev("/dev/tty",FS.makedev(5,0));FS.mkdev("/dev/tty1",FS.makedev(6,0));var random_device;if(typeof crypto==="object"&&typeof crypto["getRandomValues"]==="function"){var randomBuffer=new Uint8Array(1);random_device=function(){crypto.getRandomValues(randomBuffer);return randomBuffer[0]}}else if(ENVIRONMENT_IS_NODE){try{var crypto_module=require("crypto");random_device=function(){return crypto_module["randomBytes"](1)[0]}}catch(e){}}else{}if(!random_device){random_device=function(){abort("random_device")}}FS.createDevice("/dev","random",random_device);FS.createDevice("/dev","urandom",random_device);FS.mkdir("/dev/shm");FS.mkdir("/dev/shm/tmp")},createSpecialDirectories:function(){FS.mkdir("/proc");FS.mkdir("/proc/self");FS.mkdir("/proc/self/fd");FS.mount({mount:function(){var node=FS.createNode("/proc/self","fd",16384|511,73);node.node_ops={lookup:function(parent,name){var fd=+name;var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);var ret={parent:null,mount:{mountpoint:"fake"},node_ops:{readlink:function(){return stream.path}}};ret.parent=ret;return ret}};return node}},{},"/proc/self/fd")},createStandardStreams:function(){if(Module["stdin"]){FS.createDevice("/dev","stdin",Module["stdin"])}else{FS.symlink("/dev/tty","/dev/stdin")}if(Module["stdout"]){FS.createDevice("/dev","stdout",null,Module["stdout"])}else{FS.symlink("/dev/tty","/dev/stdout")}if(Module["stderr"]){FS.createDevice("/dev","stderr",null,Module["stderr"])}else{FS.symlink("/dev/tty1","/dev/stderr")}var stdin=FS.open("/dev/stdin","r");var stdout=FS.open("/dev/stdout","w");var stderr=FS.open("/dev/stderr","w")},ensureErrnoError:function(){if(FS.ErrnoError)return;FS.ErrnoError=function ErrnoError(errno,node){this.node=node;this.setErrno=function(errno){this.errno=errno};this.setErrno(errno);this.message="FS error"};FS.ErrnoError.prototype=new Error;FS.ErrnoError.prototype.constructor=FS.ErrnoError;[44].forEach(function(code){FS.genericErrors[code]=new FS.ErrnoError(code);FS.genericErrors[code].stack="<generic error, no stack>"})},staticInit:function(){FS.ensureErrnoError();FS.nameTable=new Array(4096);FS.mount(MEMFS,{},"/");FS.createDefaultDirectories();FS.createDefaultDevices();FS.createSpecialDirectories();FS.filesystems={"MEMFS":MEMFS}},init:function(input,output,error){FS.init.initialized=true;FS.ensureErrnoError();Module["stdin"]=input||Module["stdin"];Module["stdout"]=output||Module["stdout"];Module["stderr"]=error||Module["stderr"];FS.createStandardStreams()},quit:function(){FS.init.initialized=false;var fflush=Module["_fflush"];if(fflush)fflush(0);for(var i=0;i<FS.streams.length;i++){var stream=FS.streams[i];if(!stream){continue}FS.close(stream)}},getMode:function(canRead,canWrite){var mode=0;if(canRead)mode|=292|73;if(canWrite)mode|=146;return mode},joinPath:function(parts,forceRelative){var path=PATH.join.apply(null,parts);if(forceRelative&&path[0]=="/")path=path.substr(1);return path},absolutePath:function(relative,base){return PATH_FS.resolve(base,relative)},standardizePath:function(path){return PATH.normalize(path)},findObject:function(path,dontResolveLastLink){var ret=FS.analyzePath(path,dontResolveLastLink);if(ret.exists){return ret.object}else{setErrNo(ret.error);return null}},analyzePath:function(path,dontResolveLastLink){try{var lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});path=lookup.path}catch(e){}var ret={isRoot:false,exists:false,error:0,name:null,path:null,object:null,parentExists:false,parentPath:null,parentObject:null};try{var lookup=FS.lookupPath(path,{parent:true});ret.parentExists=true;ret.parentPath=lookup.path;ret.parentObject=lookup.node;ret.name=PATH.basename(path);lookup=FS.lookupPath(path,{follow:!dontResolveLastLink});ret.exists=true;ret.path=lookup.path;ret.object=lookup.node;ret.name=lookup.node.name;ret.isRoot=lookup.path==="/"}catch(e){ret.error=e.errno}return ret},createFolder:function(parent,name,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.mkdir(path,mode)},createPath:function(parent,path,canRead,canWrite){parent=typeof parent==="string"?parent:FS.getPath(parent);var parts=path.split("/").reverse();while(parts.length){var part=parts.pop();if(!part)continue;var current=PATH.join2(parent,part);try{FS.mkdir(current)}catch(e){}parent=current}return current},createFile:function(parent,name,properties,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(canRead,canWrite);return FS.create(path,mode)},createDataFile:function(parent,name,data,canRead,canWrite,canOwn){var path=name?PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name):parent;var mode=FS.getMode(canRead,canWrite);var node=FS.create(path,mode);if(data){if(typeof data==="string"){var arr=new Array(data.length);for(var i=0,len=data.length;i<len;++i)arr[i]=data.charCodeAt(i);data=arr}FS.chmod(node,mode|146);var stream=FS.open(node,"w");FS.write(stream,data,0,data.length,0,canOwn);FS.close(stream);FS.chmod(node,mode)}return node},createDevice:function(parent,name,input,output){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);var mode=FS.getMode(!!input,!!output);if(!FS.createDevice.major)FS.createDevice.major=64;var dev=FS.makedev(FS.createDevice.major++,0);FS.registerDevice(dev,{open:function(stream){stream.seekable=false},close:function(stream){if(output&&output.buffer&&output.buffer.length){output(10)}},read:function(stream,buffer,offset,length,pos){var bytesRead=0;for(var i=0;i<length;i++){var result;try{result=input()}catch(e){throw new FS.ErrnoError(29)}if(result===undefined&&bytesRead===0){throw new FS.ErrnoError(6)}if(result===null||result===undefined)break;bytesRead++;buffer[offset+i]=result}if(bytesRead){stream.node.timestamp=Date.now()}return bytesRead},write:function(stream,buffer,offset,length,pos){for(var i=0;i<length;i++){try{output(buffer[offset+i])}catch(e){throw new FS.ErrnoError(29)}}if(length){stream.node.timestamp=Date.now()}return i}});return FS.mkdev(path,mode,dev)},createLink:function(parent,name,target,canRead,canWrite){var path=PATH.join2(typeof parent==="string"?parent:FS.getPath(parent),name);return FS.symlink(target,path)},forceLoadFile:function(obj){if(obj.isDevice||obj.isFolder||obj.link||obj.contents)return true;var success=true;if(typeof XMLHttpRequest!=="undefined"){throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.")}else if(read_){try{obj.contents=intArrayFromString(read_(obj.url),true);obj.usedBytes=obj.contents.length}catch(e){success=false}}else{throw new Error("Cannot load without read() or XMLHttpRequest.")}if(!success)setErrNo(29);return success},createLazyFile:function(parent,name,url,canRead,canWrite){function LazyUint8Array(){this.lengthKnown=false;this.chunks=[]}LazyUint8Array.prototype.get=function LazyUint8Array_get(idx){if(idx>this.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;out("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i<size;i++){buffer[offset+i]=contents[position+i]}}else{for(var i=0;i<size;i++){buffer[offset+i]=contents.get(position+i)}}return size};node.stream_ops=stream_ops;return node},createPreloadedFile:function(parent,name,url,canRead,canWrite,onload,onerror,dontCreateFile,canOwn,preFinish){Browser.init();var fullname=name?PATH_FS.resolve(PATH.join2(parent,name)):parent;var dep=getUniqueRunDependency("cp "+fullname);function processData(byteArray){function finish(byteArray){if(preFinish)preFinish();if(!dontCreateFile){FS.createDataFile(parent,name,byteArray,canRead,canWrite,canOwn)}if(onload)onload();removeRunDependency(dep)}var handled=false;Module["preloadPlugins"].forEach(function(plugin){if(handled)return;if(plugin["canHandle"](fullname)){plugin["handle"](byteArray,fullname,finish,function(){if(onerror)onerror();removeRunDependency(dep)});handled=true}});if(!handled)finish(byteArray)}addRunDependency(dep);if(typeof url=="string"){Browser.asyncLoad(url,function(byteArray){processData(byteArray)},onerror)}else{processData(url)}},indexedDB:function(){return window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB},DB_NAME:function(){return"EM_FS_"+window.location.pathname},DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=function openRequest_onupgradeneeded(){out("creating db");var db=openRequest.result;db.createObjectStore(FS.DB_STORE_NAME)};openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;var transaction=db.transaction([FS.DB_STORE_NAME],"readwrite");var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var putRequest=files.put(FS.analyzePath(path).object.contents,path);putRequest.onsuccess=function putRequest_onsuccess(){ok++;if(ok+fail==total)finish()};putRequest.onerror=function putRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror},loadFilesFromDB:function(paths,onload,onerror){onload=onload||function(){};onerror=onerror||function(){};var indexedDB=FS.indexedDB();try{var openRequest=indexedDB.open(FS.DB_NAME(),FS.DB_VERSION)}catch(e){return onerror(e)}openRequest.onupgradeneeded=onerror;openRequest.onsuccess=function openRequest_onsuccess(){var db=openRequest.result;try{var transaction=db.transaction([FS.DB_STORE_NAME],"readonly")}catch(e){onerror(e);return}var files=transaction.objectStore(FS.DB_STORE_NAME);var ok=0,fail=0,total=paths.length;function finish(){if(fail==0)onload();else onerror()}paths.forEach(function(path){var getRequest=files.get(path);getRequest.onsuccess=function getRequest_onsuccess(){if(FS.analyzePath(path).exists){FS.unlink(path)}FS.createDataFile(PATH.dirname(path),PATH.basename(path),getRequest.result,true,true,true);ok++;if(ok+fail==total)finish()};getRequest.onerror=function getRequest_onerror(){fail++;if(ok+fail==total)finish()}});transaction.onerror=onerror};openRequest.onerror=onerror}};var SYSCALLS={mappings:{},DEFAULT_POLLMASK:5,umask:511,calculateAt:function(dirfd,path){if(path[0]!=="/"){var dir;if(dirfd===-100){dir=FS.cwd()}else{var dirstream=FS.getStream(dirfd);if(!dirstream)throw new FS.ErrnoError(8);dir=dirstream.path}path=PATH.join2(dir,path)}return path},doStat:function(func,path,buf){try{var stat=func(path)}catch(e){if(e&&e.node&&PATH.normalize(path)!==PATH.normalize(FS.getPath(e.node))){return-54}throw e}HEAP32[buf>>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags,offset){var buffer=HEAPU8.slice(addr,addr+len);FS.msync(stream,buffer,offset,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr<len)break}return ret},doWritev:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i<iovcnt;i++){var ptr=HEAP32[iov+i*8>>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},getStreamFromFD:function(fd){var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(low,high){return low}};function _fd_close(fd){try{var stream=SYSCALLS.getStreamFromFD(fd);FS.close(stream);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_read(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doReadv(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _round(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}var FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};var readMode=292|73;var writeMode=146;Object.defineProperties(FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}});FS.FSNode=FSNode;FS.staticInit();function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"emscripten_memcpy_big":_emscripten_memcpy_big,"emscripten_resize_heap":_emscripten_resize_heap,"fd_close":_fd_close,"fd_read":_fd_read,"fd_seek":_fd_seek,"fd_write":_fd_write,"memory":wasmMemory,"round":_round,"table":wasmTable};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["__wasm_call_ctors"]).apply(null,arguments)};var _FLAC__stream_decoder_new=Module["_FLAC__stream_decoder_new"]=function(){return(_FLAC__stream_decoder_new=Module["_FLAC__stream_decoder_new"]=Module["asm"]["FLAC__stream_decoder_new"]).apply(null,arguments)};var _FLAC__stream_decoder_delete=Module["_FLAC__stream_decoder_delete"]=function(){return(_FLAC__stream_decoder_delete=Module["_FLAC__stream_decoder_delete"]=Module["asm"]["FLAC__stream_decoder_delete"]).apply(null,arguments)};var _FLAC__stream_decoder_finish=Module["_FLAC__stream_decoder_finish"]=function(){return(_FLAC__stream_decoder_finish=Module["_FLAC__stream_decoder_finish"]=Module["asm"]["FLAC__stream_decoder_finish"]).apply(null,arguments)};var _FLAC__stream_decoder_init_stream=Module["_FLAC__stream_decoder_init_stream"]=function(){return(_FLAC__stream_decoder_init_stream=Module["_FLAC__stream_decoder_init_stream"]=Module["asm"]["FLAC__stream_decoder_init_stream"]).apply(null,arguments)};var _FLAC__stream_decoder_reset=Module["_FLAC__stream_decoder_reset"]=function(){return(_FLAC__stream_decoder_reset=Module["_FLAC__stream_decoder_reset"]=Module["asm"]["FLAC__stream_decoder_reset"]).apply(null,arguments)};var _FLAC__stream_decoder_init_ogg_stream=Module["_FLAC__stream_decoder_init_ogg_stream"]=function(){return(_FLAC__stream_decoder_init_ogg_stream=Module["_FLAC__stream_decoder_init_ogg_stream"]=Module["asm"]["FLAC__stream_decoder_init_ogg_stream"]).apply(null,arguments)};var _FLAC__stream_decoder_set_ogg_serial_number=Module["_FLAC__stream_decoder_set_ogg_serial_number"]=function(){return(_FLAC__stream_decoder_set_ogg_serial_number=Module["_FLAC__stream_decoder_set_ogg_serial_number"]=Module["asm"]["FLAC__stream_decoder_set_ogg_serial_number"]).apply(null,arguments)};var _FLAC__stream_decoder_set_md5_checking=Module["_FLAC__stream_decoder_set_md5_checking"]=function(){return(_FLAC__stream_decoder_set_md5_checking=Module["_FLAC__stream_decoder_set_md5_checking"]=Module["asm"]["FLAC__stream_decoder_set_md5_checking"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_respond=Module["_FLAC__stream_decoder_set_metadata_respond"]=function(){return(_FLAC__stream_decoder_set_metadata_respond=Module["_FLAC__stream_decoder_set_metadata_respond"]=Module["asm"]["FLAC__stream_decoder_set_metadata_respond"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_respond_application=Module["_FLAC__stream_decoder_set_metadata_respond_application"]=function(){return(_FLAC__stream_decoder_set_metadata_respond_application=Module["_FLAC__stream_decoder_set_metadata_respond_application"]=Module["asm"]["FLAC__stream_decoder_set_metadata_respond_application"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_respond_all=Module["_FLAC__stream_decoder_set_metadata_respond_all"]=function(){return(_FLAC__stream_decoder_set_metadata_respond_all=Module["_FLAC__stream_decoder_set_metadata_respond_all"]=Module["asm"]["FLAC__stream_decoder_set_metadata_respond_all"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_ignore=Module["_FLAC__stream_decoder_set_metadata_ignore"]=function(){return(_FLAC__stream_decoder_set_metadata_ignore=Module["_FLAC__stream_decoder_set_metadata_ignore"]=Module["asm"]["FLAC__stream_decoder_set_metadata_ignore"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_ignore_application=Module["_FLAC__stream_decoder_set_metadata_ignore_application"]=function(){return(_FLAC__stream_decoder_set_metadata_ignore_application=Module["_FLAC__stream_decoder_set_metadata_ignore_application"]=Module["asm"]["FLAC__stream_decoder_set_metadata_ignore_application"]).apply(null,arguments)};var _FLAC__stream_decoder_set_metadata_ignore_all=Module["_FLAC__stream_decoder_set_metadata_ignore_all"]=function(){return(_FLAC__stream_decoder_set_metadata_ignore_all=Module["_FLAC__stream_decoder_set_metadata_ignore_all"]=Module["asm"]["FLAC__stream_decoder_set_metadata_ignore_all"]).apply(null,arguments)};var _FLAC__stream_decoder_get_state=Module["_FLAC__stream_decoder_get_state"]=function(){return(_FLAC__stream_decoder_get_state=Module["_FLAC__stream_decoder_get_state"]=Module["asm"]["FLAC__stream_decoder_get_state"]).apply(null,arguments)};var _FLAC__stream_decoder_get_md5_checking=Module["_FLAC__stream_decoder_get_md5_checking"]=function(){return(_FLAC__stream_decoder_get_md5_checking=Module["_FLAC__stream_decoder_get_md5_checking"]=Module["asm"]["FLAC__stream_decoder_get_md5_checking"]).apply(null,arguments)};var _FLAC__stream_decoder_process_single=Module["_FLAC__stream_decoder_process_single"]=function(){return(_FLAC__stream_decoder_process_single=Module["_FLAC__stream_decoder_process_single"]=Module["asm"]["FLAC__stream_decoder_process_single"]).apply(null,arguments)};var _FLAC__stream_decoder_process_until_end_of_metadata=Module["_FLAC__stream_decoder_process_until_end_of_metadata"]=function(){return(_FLAC__stream_decoder_process_until_end_of_metadata=Module["_FLAC__stream_decoder_process_until_end_of_metadata"]=Module["asm"]["FLAC__stream_decoder_process_until_end_of_metadata"]).apply(null,arguments)};var _FLAC__stream_decoder_process_until_end_of_stream=Module["_FLAC__stream_decoder_process_until_end_of_stream"]=function(){return(_FLAC__stream_decoder_process_until_end_of_stream=Module["_FLAC__stream_decoder_process_until_end_of_stream"]=Module["asm"]["FLAC__stream_decoder_process_until_end_of_stream"]).apply(null,arguments)};var _FLAC__stream_encoder_new=Module["_FLAC__stream_encoder_new"]=function(){return(_FLAC__stream_encoder_new=Module["_FLAC__stream_encoder_new"]=Module["asm"]["FLAC__stream_encoder_new"]).apply(null,arguments)};var _FLAC__stream_encoder_delete=Module["_FLAC__stream_encoder_delete"]=function(){return(_FLAC__stream_encoder_delete=Module["_FLAC__stream_encoder_delete"]=Module["asm"]["FLAC__stream_encoder_delete"]).apply(null,arguments)};var _FLAC__stream_encoder_finish=Module["_FLAC__stream_encoder_finish"]=function(){return(_FLAC__stream_encoder_finish=Module["_FLAC__stream_encoder_finish"]=Module["asm"]["FLAC__stream_encoder_finish"]).apply(null,arguments)};var _FLAC__stream_encoder_init_stream=Module["_FLAC__stream_encoder_init_stream"]=function(){return(_FLAC__stream_encoder_init_stream=Module["_FLAC__stream_encoder_init_stream"]=Module["asm"]["FLAC__stream_encoder_init_stream"]).apply(null,arguments)};var _FLAC__stream_encoder_init_ogg_stream=Module["_FLAC__stream_encoder_init_ogg_stream"]=function(){return(_FLAC__stream_encoder_init_ogg_stream=Module["_FLAC__stream_encoder_init_ogg_stream"]=Module["asm"]["FLAC__stream_encoder_init_ogg_stream"]).apply(null,arguments)};var _FLAC__stream_encoder_set_ogg_serial_number=Module["_FLAC__stream_encoder_set_ogg_serial_number"]=function(){return(_FLAC__stream_encoder_set_ogg_serial_number=Module["_FLAC__stream_encoder_set_ogg_serial_number"]=Module["asm"]["FLAC__stream_encoder_set_ogg_serial_number"]).apply(null,arguments)};var _FLAC__stream_encoder_set_verify=Module["_FLAC__stream_encoder_set_verify"]=function(){return(_FLAC__stream_encoder_set_verify=Module["_FLAC__stream_encoder_set_verify"]=Module["asm"]["FLAC__stream_encoder_set_verify"]).apply(null,arguments)};var _FLAC__stream_encoder_set_channels=Module["_FLAC__stream_encoder_set_channels"]=function(){return(_FLAC__stream_encoder_set_channels=Module["_FLAC__stream_encoder_set_channels"]=Module["asm"]["FLAC__stream_encoder_set_channels"]).apply(null,arguments)};var _FLAC__stream_encoder_set_bits_per_sample=Module["_FLAC__stream_encoder_set_bits_per_sample"]=function(){return(_FLAC__stream_encoder_set_bits_per_sample=Module["_FLAC__stream_encoder_set_bits_per_sample"]=Module["asm"]["FLAC__stream_encoder_set_bits_per_sample"]).apply(null,arguments)};var _FLAC__stream_encoder_set_sample_rate=Module["_FLAC__stream_encoder_set_sample_rate"]=function(){return(_FLAC__stream_encoder_set_sample_rate=Module["_FLAC__stream_encoder_set_sample_rate"]=Module["asm"]["FLAC__stream_encoder_set_sample_rate"]).apply(null,arguments)};var _FLAC__stream_encoder_set_compression_level=Module["_FLAC__stream_encoder_set_compression_level"]=function(){return(_FLAC__stream_encoder_set_compression_level=Module["_FLAC__stream_encoder_set_compression_level"]=Module["asm"]["FLAC__stream_encoder_set_compression_level"]).apply(null,arguments)};var _FLAC__stream_encoder_set_blocksize=Module["_FLAC__stream_encoder_set_blocksize"]=function(){return(_FLAC__stream_encoder_set_blocksize=Module["_FLAC__stream_encoder_set_blocksize"]=Module["asm"]["FLAC__stream_encoder_set_blocksize"]).apply(null,arguments)};var _FLAC__stream_encoder_set_total_samples_estimate=Module["_FLAC__stream_encoder_set_total_samples_estimate"]=function(){return(_FLAC__stream_encoder_set_total_samples_estimate=Module["_FLAC__stream_encoder_set_total_samples_estimate"]=Module["asm"]["FLAC__stream_encoder_set_total_samples_estimate"]).apply(null,arguments)};var _FLAC__stream_encoder_set_metadata=Module["_FLAC__stream_encoder_set_metadata"]=function(){return(_FLAC__stream_encoder_set_metadata=Module["_FLAC__stream_encoder_set_metadata"]=Module["asm"]["FLAC__stream_encoder_set_metadata"]).apply(null,arguments)};var _FLAC__stream_encoder_get_state=Module["_FLAC__stream_encoder_get_state"]=function(){return(_FLAC__stream_encoder_get_state=Module["_FLAC__stream_encoder_get_state"]=Module["asm"]["FLAC__stream_encoder_get_state"]).apply(null,arguments)};var _FLAC__stream_encoder_get_verify_decoder_state=Module["_FLAC__stream_encoder_get_verify_decoder_state"]=function(){return(_FLAC__stream_encoder_get_verify_decoder_state=Module["_FLAC__stream_encoder_get_verify_decoder_state"]=Module["asm"]["FLAC__stream_encoder_get_verify_decoder_state"]).apply(null,arguments)};var _FLAC__stream_encoder_get_verify=Module["_FLAC__stream_encoder_get_verify"]=function(){return(_FLAC__stream_encoder_get_verify=Module["_FLAC__stream_encoder_get_verify"]=Module["asm"]["FLAC__stream_encoder_get_verify"]).apply(null,arguments)};var _FLAC__stream_encoder_process=Module["_FLAC__stream_encoder_process"]=function(){return(_FLAC__stream_encoder_process=Module["_FLAC__stream_encoder_process"]=Module["asm"]["FLAC__stream_encoder_process"]).apply(null,arguments)};var _FLAC__stream_encoder_process_interleaved=Module["_FLAC__stream_encoder_process_interleaved"]=function(){return(_FLAC__stream_encoder_process_interleaved=Module["_FLAC__stream_encoder_process_interleaved"]=Module["asm"]["FLAC__stream_encoder_process_interleaved"]).apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return(___errno_location=Module["___errno_location"]=Module["asm"]["__errno_location"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["stackSave"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["stackRestore"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["stackAlloc"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["malloc"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["free"]).apply(null,arguments)};var __growWasmMemory=Module["__growWasmMemory"]=function(){return(__growWasmMemory=Module["__growWasmMemory"]=Module["asm"]["__growWasmMemory"]).apply(null,arguments)};Module["ccall"]=ccall;Module["cwrap"]=cwrap;Module["setValue"]=setValue;Module["getValue"]=getValue;if(memoryInitializer){if(!isDataURI(memoryInitializer)){memoryInitializer=locateFile(memoryInitializer)}if(ENVIRONMENT_IS_NODE||ENVIRONMENT_IS_SHELL){var data=readBinary(memoryInitializer);HEAPU8.set(data,GLOBAL_BASE)}else{addRunDependency("memory initializer");var applyMemoryInitializer=function(data){if(data.byteLength)data=new Uint8Array(data);HEAPU8.set(data,GLOBAL_BASE);if(Module["memoryInitializerRequest"])delete Module["memoryInitializerRequest"].response;removeRunDependency("memory initializer")};var doBrowserLoad=function(){readAsync(memoryInitializer,applyMemoryInitializer,function(){var e=new Error("could not load memory initializer "+memoryInitializer);throw e})};if(Module["memoryInitializerRequest"]){var useRequest=function(){var request=Module["memoryInitializerRequest"];var response=request.response;if(request.status!==200&&request.status!==0){console.warn("a problem seems to have happened with Module.memoryInitializerRequest, status: "+request.status+", retrying "+memoryInitializer);doBrowserLoad();return}applyMemoryInitializer(response)};if(Module["memoryInitializerRequest"].response){setTimeout(useRequest,0)}else{Module["memoryInitializerRequest"].addEventListener("load",useRequest)}}else{doBrowserLoad()}}}var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run();function _readStreamInfo(p_streaminfo){var min_blocksize=Module.getValue(p_streaminfo,"i32");var max_blocksize=Module.getValue(p_streaminfo+4,"i32");var min_framesize=Module.getValue(p_streaminfo+8,"i32");var max_framesize=Module.getValue(p_streaminfo+12,"i32");var sample_rate=Module.getValue(p_streaminfo+16,"i32");var channels=Module.getValue(p_streaminfo+20,"i32");var bits_per_sample=Module.getValue(p_streaminfo+24,"i32");var total_samples=Module.getValue(p_streaminfo+32,"i64");var md5sum=_readMd5(p_streaminfo+40);return{min_blocksize:min_blocksize,max_blocksize:max_blocksize,min_framesize:min_framesize,max_framesize:max_framesize,sampleRate:sample_rate,channels:channels,bitsPerSample:bits_per_sample,total_samples:total_samples,md5sum:md5sum}}function _readMd5(p_md5){var sb=[],v,str;for(var i=0,len=16;i<len;++i){v=Module.getValue(p_md5+i,"i8");if(v<0)v=256+v;str=v.toString(16);if(str.length<2)str="0"+str;sb.push(str)}return sb.join("")}function _readFrameHdr(p_frame,enc_opt){var blocksize=Module.getValue(p_frame,"i32");var sample_rate=Module.getValue(p_frame+4,"i32");var channels=Module.getValue(p_frame+8,"i32");var channel_assignment=Module.getValue(p_frame+12,"i32");var bits_per_sample=Module.getValue(p_frame+16,"i32");var number_type=Module.getValue(p_frame+20,"i32");var frame_number=Module.getValue(p_frame+24,"i32");var sample_number=Module.getValue(p_frame+24,"i64");var number=number_type===0?frame_number:sample_number;var numberType=number_type===0?"frames":"samples";var crc=Module.getValue(p_frame+36,"i8");var subframes;if(enc_opt&&enc_opt.analyseSubframes){var subOffset={offset:40};subframes=[];for(var i=0;i<channels;++i){subframes.push(_readSubFrameHdr(p_frame,subOffset,blocksize,enc_opt))}}return{blocksize:blocksize,sampleRate:sample_rate,channels:channels,channelAssignment:channel_assignment,bitsPerSample:bits_per_sample,number:number,numberType:numberType,crc:crc,subframes:subframes}}function _readSubFrameHdr(p_subframe,subOffset,block_size,enc_opt){var type=Module.getValue(p_subframe+subOffset.offset,"i32");subOffset.offset+=4;var data;switch(type){case 0:data={value:Module.getValue(p_subframe+subOffset.offset,"i32")};subOffset.offset+=284;break;case 1:data=Module.getValue(p_subframe+subOffset.offset,"i32");subOffset.offset+=284;break;case 2:data=_readSubFrameHdrFixedData(p_subframe,subOffset,block_size,false,enc_opt);break;case 3:data=_readSubFrameHdrFixedData(p_subframe,subOffset,block_size,true,enc_opt);break}var offset=subOffset.offset;var wasted_bits=Module.getValue(p_subframe+offset,"i32");subOffset.offset+=4;return{type:type,data:data,wastedBits:wasted_bits}}function _readSubFrameHdrFixedData(p_subframe_data,subOffset,block_size,is_lpc,enc_opt){var offset=subOffset.offset;var data={order:-1,contents:{parameters:[],rawBits:[]}};var entropyType=Module.getValue(p_subframe_data,"i32");offset+=4;var entropyOrder=Module.getValue(p_subframe_data+offset,"i32");data.order=entropyOrder;offset+=4;var partitions=1<<entropyOrder,params=data.contents.parameters,raws=data.contents.rawBits;var ppart=Module.getValue(p_subframe_data+offset,"i32");var pparams=Module.getValue(ppart,"i32");var praw=Module.getValue(ppart+4,"i32");data.contents.capacityByOrder=Module.getValue(ppart+8,"i32");for(var i=0;i<partitions;++i){params.push(Module.getValue(pparams+i*4,"i32"));raws.push(Module.getValue(praw+i*4,"i32"))}offset+=4;var order=Module.getValue(p_subframe_data+offset,"i32");offset+=4;var warmup=[],res;if(is_lpc){var qlp_coeff_precision=Module.getValue(p_subframe_data+offset,"i32");offset+=4;var quantization_level=Module.getValue(p_subframe_data+offset,"i32");offset+=4;var qlp_coeff=[];for(var i=0;i<order;++i){qlp_coeff.push(Module.getValue(p_subframe_data+offset,"i32"));offset+=4}data.qlp_coeff=qlp_coeff;data.qlp_coeff_precision=qlp_coeff_precision;data.quantization_level=quantization_level;offset=subOffset.offset+152;offset=_readSubFrameHdrWarmup(p_subframe_data,offset,warmup,order);if(enc_opt&&enc_opt.analyseResiduals){offset=subOffset.offset+280;res=_readSubFrameHdrResidual(p_subframe_data+offset,block_size,order)}}else{offset=_readSubFrameHdrWarmup(p_subframe_data,offset,warmup,order);offset=subOffset.offset+32;if(enc_opt&&enc_opt.analyseResiduals){res=_readSubFrameHdrResidual(p_subframe_data+offset,block_size,order)}}subOffset.offset+=284;return{partition:{type:entropyType,data:data},order:order,warmup:warmup,residual:res}}function _readSubFrameHdrWarmup(p_subframe_data,offset,warmup,order){for(var i=0;i<order;++i){warmup.push(Module.getValue(p_subframe_data+offset,"i32"));offset+=4}return offset}function _readSubFrameHdrResidual(p_subframe_data_res,block_size,order){var pres=Module.getValue(p_subframe_data_res,"i32");var res=[];for(var i=0,size=block_size-order;i<size;++i){res.push(Module.getValue(pres+i*4,"i32"))}return res}function _readConstChar(ptr,length,sb){sb.splice(0);var ch;for(var i=0;i<length;++i){ch=Module.getValue(ptr+i,"i8");if(ch===0){break}sb.push(String.fromCodePoint(ch))}return sb.join("")}function _readNullTerminatedChar(ptr,sb){sb.splice(0);var ch=1,i=0;while(ch>0){ch=Module.getValue(ptr+i++,"i8");if(ch===0){break}sb.push(String.fromCodePoint(ch))}return sb.join("")}function _readPaddingMetadata(p_padding_metadata){return{dummy:Module.getValue(p_padding_metadata,"i32")}}function _readSeekTableMetadata(p_seek_table_metadata){var num_points=Module.getValue(p_seek_table_metadata,"i32");var ptrPoints=Module.getValue(p_seek_table_metadata+4,"i32");var points=[];for(var i=0;i<num_points;++i){points.push({sample_number:Module.getValue(ptrPoints+i*24,"i64"),stream_offset:Module.getValue(ptrPoints+i*24+8,"i64"),frame_samples:Module.getValue(ptrPoints+i*24+16,"i32")})}return{num_points:num_points,points:points}}function _readVorbisComment(p_vorbiscomment){var length=Module.getValue(p_vorbiscomment,"i32");var entry=Module.getValue(p_vorbiscomment+4,"i32");var sb=[];var strEntry=_readConstChar(entry,length,sb);var num_comments=Module.getValue(p_vorbiscomment+8,"i32");var comments=[],clen,centry;var pc=Module.getValue(p_vorbiscomment+12,"i32");for(var i=0;i<num_comments;++i){clen=Module.getValue(pc+i*8,"i32");if(clen===0){continue}centry=Module.getValue(pc+i*8+4,"i32");comments.push(_readConstChar(centry,clen,sb))}return{vendor_string:strEntry,num_comments:num_comments,comments:comments}}function _readCueSheetMetadata(p_cue_sheet){var sb=[];var media_catalog_number=_readConstChar(p_cue_sheet,129,sb);var lead_in=Module.getValue(p_cue_sheet+136,"i64");var is_cd=Module.getValue(p_cue_sheet+144,"i8");var num_tracks=Module.getValue(p_cue_sheet+148,"i32");var ptrTrack=Module.getValue(p_cue_sheet+152,"i32");var tracks=[],trackOffset=ptrTrack;if(ptrTrack!==0){for(var i=0;i<num_tracks;++i){var tr=_readCueSheetMetadata_track(trackOffset,sb);tracks.push(tr);trackOffset+=32}}return{media_catalog_number:media_catalog_number,lead_in:lead_in,is_cd:is_cd,num_tracks:num_tracks,tracks:tracks}}function _readCueSheetMetadata_track(p_cue_sheet_track,sb){var typePremph=Module.getValue(p_cue_sheet_track+22,"i8");var num_indices=Module.getValue(p_cue_sheet_track+23,"i8");var indices=[];var track={offset:Module.getValue(p_cue_sheet_track,"i64"),number:Module.getValue(p_cue_sheet_track+8,"i8")&255,isrc:_readConstChar(p_cue_sheet_track+9,13,sb),type:typePremph&1?"NON_AUDIO":"AUDIO",pre_emphasis:!!(typePremph&2),num_indices:num_indices,indices:indices};var idx;if(num_indices>0){idx=Module.getValue(p_cue_sheet_track+24,"i32");for(var i=0;i<num_indices;++i){indices.push({offset:Module.getValue(idx+i*16,"i64"),number:Module.getValue(idx+i*16+8,"i8")})}}return track}function _readPictureMetadata(p_picture_metadata){var type=Module.getValue(p_picture_metadata,"i32");var mime=Module.getValue(p_picture_metadata+4,"i32");var sb=[];var mime_type=_readNullTerminatedChar(mime,sb);var desc=Module.getValue(p_picture_metadata+8,"i32");var description=_readNullTerminatedChar(desc,sb);var width=Module.getValue(p_picture_metadata+12,"i32");var height=Module.getValue(p_picture_metadata+16,"i32");var depth=Module.getValue(p_picture_metadata+20,"i32");var colors=Module.getValue(p_picture_metadata+24,"i32");var data_length=Module.getValue(p_picture_metadata+28,"i32");var data=Module.getValue(p_picture_metadata+32,"i32");var buffer=Uint8Array.from(Module.HEAPU8.subarray(data,data+data_length));return{type:type,mime_type:mime_type,description:description,width:width,height:height,depth:depth,colors:colors,data_length:data_length,data:buffer}}function __fix_write_buffer(heapOffset,newBuffer,applyFix){var dv=new DataView(newBuffer.buffer);var targetSize=newBuffer.length;var increase=!applyFix?1:2;var buffer=HEAPU8.subarray(heapOffset,heapOffset+targetSize*increase);var jump,isPrint;for(var i=0,j=0,size=buffer.length;i<size&&j<targetSize;++i,++j){if(i===size-1&&j<targetSize-1){buffer=HEAPU8.subarray(heapOffset,size+targetSize);size=buffer.length}if(applyFix&&(buffer[i]===0||buffer[i]===255)){jump=0;isPrint=true;if(i+1<size&&buffer[i]===buffer[i+1]){++jump;if(i+2<size){if(buffer[i]===buffer[i+2]){++jump}else{isPrint=false}}}if(isPrint){dv.setUint8(j,buffer[i]);if(jump===2&&i+3<size&&buffer[i]===buffer[i+3]){++jump;dv.setUint8(++j,buffer[i])}}else{--j}i+=jump}else{dv.setUint8(j,buffer[i])}}}var FLAC__STREAM_DECODER_READ_STATUS_CONTINUE=0;var FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM=1;var FLAC__STREAM_DECODER_READ_STATUS_ABORT=2;var FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE=0;var FLAC__STREAM_DECODER_WRITE_STATUS_ABORT=1;var FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS=2;var FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS=3;var FLAC__STREAM_ENCODER_WRITE_STATUS_OK=0;var FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR=1;var coders={};function getCallback(p_coder,func_type){if(coders[p_coder]){return coders[p_coder][func_type]}}function setCallback(p_coder,func_type,callback){if(!coders[p_coder]){coders[p_coder]={}}coders[p_coder][func_type]=callback}function _getOptions(p_coder){if(coders[p_coder]){return coders[p_coder]["options"]}}function _setOptions(p_coder,options){if(!coders[p_coder]){coders[p_coder]={}}coders[p_coder]["options"]=options}var enc_write_fn_ptr=addFunction(function(p_encoder,buffer,bytes,samples,current_frame,p_client_data){var retdata=new Uint8Array(bytes);retdata.set(HEAPU8.subarray(buffer,buffer+bytes));var write_callback_fn=getCallback(p_encoder,"write");try{write_callback_fn(retdata,bytes,samples,current_frame,p_client_data)}catch(err){console.error(err);return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR}return FLAC__STREAM_ENCODER_WRITE_STATUS_OK},"iiiiiii");var dec_read_fn_ptr=addFunction(function(p_decoder,buffer,bytes,p_client_data){var len=Module.getValue(bytes,"i32");if(len===0){return FLAC__STREAM_DECODER_READ_STATUS_ABORT}var read_callback_fn=getCallback(p_decoder,"read");var readResult=read_callback_fn(len,p_client_data);var readLen=readResult.readDataLength;Module.setValue(bytes,readLen,"i32");if(readResult.error){return FLAC__STREAM_DECODER_READ_STATUS_ABORT}if(readLen===0){return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM}var readBuf=readResult.buffer;var dataHeap=new Uint8Array(Module.HEAPU8.buffer,buffer,readLen);dataHeap.set(new Uint8Array(readBuf));return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE},"iiiii");var dec_write_fn_ptr=addFunction(function(p_decoder,p_frame,p_buffer,p_client_data){var dec_opts=_getOptions(p_decoder);var frameInfo=_readFrameHdr(p_frame,dec_opts);var channels=frameInfo.channels;var block_size=frameInfo.blocksize*(frameInfo.bitsPerSample/8);var isFix=frameInfo.bitsPerSample!==24;var padding=frameInfo.bitsPerSample/8%2;if(padding>0){block_size+=frameInfo.blocksize*padding}var data=[];var bufferOffset,_buffer;for(var i=0;i<channels;++i){bufferOffset=Module.getValue(p_buffer+i*4,"i32");_buffer=new Uint8Array(block_size);__fix_write_buffer(bufferOffset,_buffer,isFix);data.push(_buffer.subarray(0,block_size))}var write_callback_fn=getCallback(p_decoder,"write");var res=write_callback_fn(data,frameInfo);return res!==false?FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE:FLAC__STREAM_DECODER_WRITE_STATUS_ABORT},"iiiii");var DecoderErrorCode={0:"FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC",1:"FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER",2:"FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH",3:"FLAC__STREAM_DECODER_ERROR_STATUS_UNPARSEABLE_STREAM"};var dec_error_fn_ptr=addFunction(function(p_decoder,err,p_client_data){var msg=DecoderErrorCode[err]||"FLAC__STREAM_DECODER_ERROR__UNKNOWN__";var error_callback_fn=getCallback(p_decoder,"error");error_callback_fn(err,msg,p_client_data)},"viii");var metadata_fn_ptr=addFunction(function(p_coder,p_metadata,p_client_data){var type=Module.getValue(p_metadata,"i32");var is_last=Module.getValue(p_metadata+4,"i32");var length=Module.getValue(p_metadata+8,"i64");var meta_data={type:type,isLast:is_last,length:length,data:void 0};var metadata_callback_fn=getCallback(p_coder,"metadata");if(type===0){meta_data.data=_readStreamInfo(p_metadata+16);metadata_callback_fn(meta_data.data,meta_data)}else{var data;switch(type){case 1:data=_readPaddingMetadata(p_metadata+16);break;case 2:data=readApplicationMetadata(p_metadata+16);break;case 3:data=_readSeekTableMetadata(p_metadata+16);break;case 4:data=_readVorbisComment(p_metadata+16);break;case 5:data=_readCueSheetMetadata(p_metadata+16);break;case 6:data=_readPictureMetadata(p_metadata+16);break;default:{var cod_opts=_getOptions(p_coder);if(cod_opts&&cod_opts.enableRawMetadata){var buffer=Uint8Array.from(HEAPU8.subarray(p_metadata+16,p_metadata+16+length));meta_data.raw=buffer}}}meta_data.data=data;metadata_callback_fn(void 0,meta_data)}},"viii");var listeners={};var persistedEvents=[];var add_event_listener=function(eventName,listener){var list=listeners[eventName];if(!list){list=[listener];listeners[eventName]=list}else{list.push(listener)}check_and_trigger_persisted_event(eventName,listener)};var check_and_trigger_persisted_event=function(eventName,listener){var activated;for(var i=persistedEvents.length-1;i>=0;--i){activated=persistedEvents[i];if(activated&&activated.event===eventName){listener.apply(null,activated.args);break}}};var remove_event_listener=function(eventName,listener){var list=listeners[eventName];if(list){for(var i=list.length-1;i>=0;--i){if(list[i]===listener){list.splice(i,1)}}}};var do_fire_event=function(eventName,args,isPersist){if(_exported["on"+eventName]){_exported["on"+eventName].apply(null,args)}var list=listeners[eventName];if(list){for(var i=0,size=list.length;i<size;++i){list[i].apply(null,args)}}if(isPersist){persistedEvents.push({event:eventName,args:args})}};var _exported={_module:Module,_clear_enc_cb:function(enc_ptr){delete coders[enc_ptr]},_clear_dec_cb:function(dec_ptr){delete coders[dec_ptr]},setOptions:_setOptions,getOptions:_getOptions,isReady:function(){return _flac_ready},onready:void 0,on:add_event_listener,off:remove_event_listener,FLAC__stream_encoder_set_verify:function(encoder,is_verify){is_verify=is_verify?1:0;Module.ccall("FLAC__stream_encoder_set_verify","number",["number","number"],[encoder,is_verify])},FLAC__stream_encoder_set_compression_level:Module.cwrap("FLAC__stream_encoder_set_compression_level","number",["number","number"]),FLAC__stream_encoder_set_blocksize:Module.cwrap("FLAC__stream_encoder_set_blocksize","number",["number","number"]),FLAC__stream_encoder_get_verify_decoder_state:Module.cwrap("FLAC__stream_encoder_get_verify_decoder_state","number",["number"]),FLAC__stream_encoder_get_verify:Module.cwrap("FLAC__stream_encoder_get_verify","number",["number"]),create_libflac_encoder:function(sample_rate,channels,bps,compression_level,total_samples,is_verify,block_size){is_verify=typeof is_verify==="undefined"?1:is_verify+0;total_samples=typeof total_samples==="number"?total_samples:0;block_size=typeof block_size==="number"?block_size:0;var ok=true;var encoder=Module.ccall("FLAC__stream_encoder_new","number",[],[]);ok&=Module.ccall("FLAC__stream_encoder_set_verify","number",["number","number"],[encoder,is_verify]);ok&=Module.ccall("FLAC__stream_encoder_set_compression_level","number",["number","number"],[encoder,compression_level]);ok&=Module.ccall("FLAC__stream_encoder_set_channels","number",["number","number"],[encoder,channels]);ok&=Module.ccall("FLAC__stream_encoder_set_bits_per_sample","number",["number","number"],[encoder,bps]);ok&=Module.ccall("FLAC__stream_encoder_set_sample_rate","number",["number","number"],[encoder,sample_rate]);ok&=Module.ccall("FLAC__stream_encoder_set_blocksize","number",["number","number"],[encoder,block_size]);ok&=Module.ccall("FLAC__stream_encoder_set_total_samples_estimate","number",["number","number"],[encoder,total_samples]);if(ok){do_fire_event("created",[{type:"created",target:{id:encoder,type:"encoder"}}],false);return encoder}return 0},init_libflac_encoder:function(){console.warn("Flac.init_libflac_encoder() is deprecated, use Flac.create_libflac_encoder() instead!");return this.create_libflac_encoder.apply(this,arguments)},create_libflac_decoder:function(is_verify){is_verify=typeof is_verify==="undefined"?1:is_verify+0;var ok=true;var decoder=Module.ccall("FLAC__stream_decoder_new","number",[],[]);ok&=Module.ccall("FLAC__stream_decoder_set_md5_checking","number",["number","number"],[decoder,is_verify]);if(ok){do_fire_event("created",[{type:"created",target:{id:decoder,type:"decoder"}}],false);return decoder}return 0},init_libflac_decoder:function(){console.warn("Flac.init_libflac_decoder() is deprecated, use Flac.create_libflac_decoder() instead!");return this.create_libflac_decoder.apply(this,arguments)},init_encoder_stream:function(encoder,write_callback_fn,metadata_callback_fn,ogg_serial_number,client_data){var is_ogg=ogg_serial_number===true;client_data=client_data|0;if(typeof write_callback_fn!=="function"){return FLAC__STREAM_ENCODER_INIT_STATUS_INVALID_CALLBACKS}setCallback(encoder,"write",write_callback_fn);var __metadata_callback_fn_ptr=0;if(typeof metadata_callback_fn==="function"){setCallback(encoder,"metadata",metadata_callback_fn);__metadata_callback_fn_ptr=metadata_fn_ptr}var func_name="FLAC__stream_encoder_init_stream";var args_types=["number","number","number","number","number","number"];var args=[encoder,enc_write_fn_ptr,0,0,__metadata_callback_fn_ptr,client_data];if(typeof ogg_serial_number==="number"){is_ogg=true}else if(is_ogg){ogg_serial_number=1}if(is_ogg){func_name="FLAC__stream_encoder_init_ogg_stream";args.unshift(args[0]);args[1]=0;args_types.unshift(args_types[0]);args_types[1]="number";Module.ccall("FLAC__stream_encoder_set_ogg_serial_number","number",["number","number"],[encoder,ogg_serial_number])}var init_status=Module.ccall(func_name,"number",args_types,args);return init_status},init_encoder_ogg_stream:function(encoder,write_callback_fn,metadata_callback_fn,ogg_serial_number,client_data){if(typeof ogg_serial_number!=="number"){ogg_serial_number=true}return this.init_encoder_stream(encoder,write_callback_fn,metadata_callback_fn,ogg_serial_number,client_data)},init_decoder_stream:function(decoder,read_callback_fn,write_callback_fn,error_callback_fn,metadata_callback_fn,ogg_serial_number,client_data){client_data=client_data|0;if(typeof read_callback_fn!=="function"){return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS}setCallback(decoder,"read",read_callback_fn);if(typeof write_callback_fn!=="function"){return FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS}setCallback(decoder,"write",write_callback_fn);var __error_callback_fn_ptr=0;if(typeof error_callback_fn==="function"){setCallback(decoder,"error",error_callback_fn);__error_callback_fn_ptr=dec_error_fn_ptr}var __metadata_callback_fn_ptr=0;if(typeof metadata_callback_fn==="function"){setCallback(decoder,"metadata",metadata_callback_fn);__metadata_callback_fn_ptr=metadata_fn_ptr}var is_ogg=ogg_serial_number===true;if(typeof ogg_serial_number==="number"){is_ogg=true;Module.ccall("FLAC__stream_decoder_set_ogg_serial_number","number",["number","number"],[decoder,ogg_serial_number])}var init_func_name=!is_ogg?"FLAC__stream_decoder_init_stream":"FLAC__stream_decoder_init_ogg_stream";var init_status=Module.ccall(init_func_name,"number",["number","number","number","number","number","number","number","number","number","number"],[decoder,dec_read_fn_ptr,0,0,0,0,dec_write_fn_ptr,__metadata_callback_fn_ptr,__error_callback_fn_ptr,client_data]);return init_status},init_decoder_ogg_stream:function(decoder,read_callback_fn,write_callback_fn,error_callback_fn,metadata_callback_fn,ogg_serial_number,client_data){if(typeof ogg_serial_number!=="number"){ogg_serial_number=true}return this.init_decoder_stream(decoder,read_callback_fn,write_callback_fn,error_callback_fn,metadata_callback_fn,ogg_serial_number,client_data)},FLAC__stream_encoder_process_interleaved:function(encoder,buffer,num_of_samples){var numBytes=buffer.length*buffer.BYTES_PER_ELEMENT;var ptr=Module._malloc(numBytes);var heapBytes=new Uint8Array(Module.HEAPU8.buffer,ptr,numBytes);heapBytes.set(new Uint8Array(buffer.buffer,buffer.byteOffset,buffer.byteLength));var status=Module.ccall("FLAC__stream_encoder_process_interleaved","number",["number","number","number"],[encoder,heapBytes.byteOffset,num_of_samples]);Module._free(ptr);return status},FLAC__stream_encoder_process:function(encoder,channelBuffers,num_of_samples){var ptrInfo=this._create_pointer_array(channelBuffers);var pointerPtr=ptrInfo.pointerPointer;var status=Module.ccall("FLAC__stream_encoder_process","number",["number","number","number"],[encoder,pointerPtr,num_of_samples]);this._destroy_pointer_array(ptrInfo);return status},FLAC__stream_decoder_process_single:Module.cwrap("FLAC__stream_decoder_process_single","number",["number"]),FLAC__stream_decoder_process_until_end_of_stream:Module.cwrap("FLAC__stream_decoder_process_until_end_of_stream","number",["number"]),FLAC__stream_decoder_process_until_end_of_metadata:Module.cwrap("FLAC__stream_decoder_process_until_end_of_metadata","number",["number"]),FLAC__stream_decoder_get_state:Module.cwrap("FLAC__stream_decoder_get_state","number",["number"]),FLAC__stream_encoder_get_state:Module.cwrap("FLAC__stream_encoder_get_state","number",["number"]),FLAC__stream_decoder_set_metadata_respond:Module.cwrap("FLAC__stream_decoder_set_metadata_respond","number",["number","number"]),FLAC__stream_decoder_set_metadata_respond_application:Module.cwrap("FLAC__stream_decoder_set_metadata_respond_application","number",["number","number"]),FLAC__stream_decoder_set_metadata_respond_all:Module.cwrap("FLAC__stream_decoder_set_metadata_respond_all","number",["number"]),FLAC__stream_decoder_set_metadata_ignore:Module.cwrap("FLAC__stream_decoder_set_metadata_ignore","number",["number","number"]),FLAC__stream_decoder_set_metadata_ignore_application:Module.cwrap("FLAC__stream_decoder_set_metadata_ignore_application","number",["number","number"]),FLAC__stream_decoder_set_metadata_ignore_all:Module.cwrap("FLAC__stream_decoder_set_metadata_ignore_all","number",["number"]),FLAC__stream_encoder_set_metadata:function(encoder,metadataBuffersPointer,num_blocks){var status=Module.ccall("FLAC__stream_encoder_set_metadata","number",["number","number","number"],[encoder,metadataBuffersPointer.pointerPointer,num_blocks]);return status},_create_pointer_array:function(bufferArray){var size=bufferArray.length;var ptrs=[],ptrData=new Uint32Array(size);var ptrOffsets=new DataView(ptrData.buffer);var buffer,numBytes,heapBytes,ptr;for(var i=0,size;i<size;++i){buffer=bufferArray[i];numBytes=buffer.length*buffer.BYTES_PER_ELEMENT;ptr=Module._malloc(numBytes);ptrs.push(ptr);heapBytes=new Uint8Array(Module.HEAPU8.buffer,ptr,numBytes);heapBytes.set(new Uint8Array(buffer.buffer,buffer.byteOffset,buffer.byteLength));ptrOffsets.setUint32(i*4,ptr,true)}var nPointerBytes=ptrData.length*ptrData.BYTES_PER_ELEMENT;var pointerPtr=Module._malloc(nPointerBytes);var pointerHeap=new Uint8Array(Module.HEAPU8.buffer,pointerPtr,nPointerBytes);pointerHeap.set(new Uint8Array(ptrData.buffer));return{dataPointer:ptrs,pointerPointer:pointerPtr}},_destroy_pointer_array:function(pointerInfo){var pointerArray=pointerInfo.dataPointer;for(var i=0,size=pointerArray.length;i<size;++i){Module._free(pointerArray[i])}Module._free(pointerInfo.pointerPointer)},FLAC__stream_decoder_get_md5_checking:Module.cwrap("FLAC__stream_decoder_get_md5_checking","number",["number"]),FLAC__stream_decoder_set_md5_checking:function(decoder,is_verify){is_verify=is_verify?1:0;return Module.ccall("FLAC__stream_decoder_set_md5_checking","number",["number","number"],[decoder,is_verify])},FLAC__stream_encoder_finish:Module.cwrap("FLAC__stream_encoder_finish","number",["number"]),FLAC__stream_decoder_finish:Module.cwrap("FLAC__stream_decoder_finish","number",["number"]),FLAC__stream_decoder_reset:Module.cwrap("FLAC__stream_decoder_reset","number",["number"]),FLAC__stream_encoder_delete:function(encoder){this._clear_enc_cb(encoder);Module.ccall("FLAC__stream_encoder_delete","number",["number"],[encoder]);do_fire_event("destroyed",[{type:"destroyed",target:{id:encoder,type:"encoder"}}],false)},FLAC__stream_decoder_delete:function(decoder){this._clear_dec_cb(decoder);Module.ccall("FLAC__stream_decoder_delete","number",["number"],[decoder]);do_fire_event("destroyed",[{type:"destroyed",target:{id:decoder,type:"decoder"}}],false)}};if(typeof Object.defineProperty==="function"){_exported._onready=void 0;Object.defineProperty(_exported,"onready",{get(){return this._onready},set(newValue){this._onready=newValue;if(newValue&&this.isReady()){check_and_trigger_persisted_event("ready",newValue)}}})}else{console.warn("WARN: note that setting Flac.onready handler after Flac.isReady() is already true, will have no effect, that is, the handler function will not be triggered!")}if(expLib&&expLib.exports){expLib.exports=_exported}return _exported}); diff --git a/site/app/twine/libflac.min.js.mem b/site/app/twine/libflac.min.js.mem Binary files differnew file mode 100644 index 0000000..9e88419 --- /dev/null +++ b/site/app/twine/libflac.min.js.mem diff --git a/site/app/twine/mixer.js b/site/app/twine/mixer.js new file mode 100644 index 0000000..b98fa0e --- /dev/null +++ b/site/app/twine/mixer.js @@ -0,0 +1,149 @@ +var Mixer = function(twine) {
+ var mixer = this;
+ mixer.masterAmpChannel = "twine_masteramp";
+ var masterVu = null;
+ this.soloChannel = "twine_csolo";
+ this.ampChannel = "twine_masteramp";
+ target = $("#twine_mixer");
+
+ this.visible = false;
+
+ this.hide = function() {
+ masterVu = null;
+ mixer.visible = false;
+ target.empty().hide();
+ };
+
+ this.setVu = function(v) {
+ if (!masterVu) return;
+ masterVu.value = v;
+ };
+
+ this.bootAudio = function() {
+ app.setControlChannel(mixer.ampChannel, 0.8);
+ app.setControlChannel(mixer.soloChannel, -1);
+ };
+
+ var height = 150;
+ var width = 30;
+ this.show = async function () {
+ masterVu = null;
+ mixer.visible = true;
+ target.empty().show();
+ var soloChannels = [];
+ var tb = $("<tbody />").appendTo($("<table />").appendTo(target));
+ var trMuteSolo = $("<tr />").appendTo(tb);
+ var trPan = $("<tr />").appendTo(tb);
+ var trAmp = $("<tr />").appendTo(tb);
+ var trName = $("<tr />").appendTo(tb);
+ for (let c of twine.timeline.channels) {
+ trName.append($("<td />").css({"text-align": "center"}).text(c.name));
+ var tdMuteSolo = $("<td />").css({"border-left": "1px solid black", "text-align": "center"}).appendTo(trMuteSolo);
+ var tdPan = $("<td />").css({"border-left": "1px solid black", "text-align": "center"}).appendTo(trPan);
+ var tdAmp = $("<td />").css({"border-left": "1px solid black"}).appendTo(trAmp);
+ var elMuteSolo = $("<div />").appendTo(tdMuteSolo);
+ var elPan = $("<div />").appendTo(tdPan);
+ var elAmp = $("<div />").appendTo(tdAmp);
+
+ var coMute = new Control({
+ name: "Mute",
+ image: "SC_BTNDef5-MUTE_16",
+ target: elMuteSolo,
+ channel: c.defaultChannels.mute,
+ width: width * 0.5,
+ height: width * 0.5,
+ noTriggerInit: true,
+
+ });
+
+ var coSolo = new Control({
+ image: "SC_BTNDef5-SOLO_16",
+ target: elMuteSolo,
+ channel: c.defaultChannels.solo,
+ min: -1,
+ max: c.index,
+ width: width * 0.5,
+ height: width * 0.5,
+ noTriggerInit: true,
+ onChange: function(v, co) {
+ for (let s of soloChannels) {
+ s.value = false;
+ s.element.trigger("change");
+ }
+ if (v == c.index) {
+ co.value = true;
+ co.element.trigger("change");
+ }
+ }
+ });
+ soloChannels.push(coSolo);
+
+ var coPan = new Control({
+ name: "Pan",
+ image: "Timb&HY_Seq16x3v2_KNOB1FX3",
+ target: elPan,
+ channel: c.defaultChannels.pan,
+ width: width,
+ height: width,
+ noTriggerInit: true,
+ onReady: async function(coPan){
+ coPan.value = await app.getControlChannel(c.defaultChannels.pan);
+ },
+ onContextMenu: function(e) {
+ return twirl.contextMenu.show(e, [
+ {name: "Show automation", click: function(){
+ c.expand();
+ c.showAutomation(0, 1);
+ }}
+ ]);
+ }
+ });
+ var coAmp = new Control({
+ name: "Amp",
+ image: "Sexan_Timb-Slider_29334-128fr",
+ target: elAmp,
+ channel: c.defaultChannels.amp,
+ width: width,
+ height: height,
+ noTriggerInit: true,
+ onReady: async function(coAmp){
+ coAmp.value = await app.getControlChannel(c.defaultChannels.amp);
+ },
+ onContextMenu: function(e) {
+ return twirl.contextMenu.show(e, [
+ {name: "Show automation", click: function(){
+ c.expand();
+ c.showAutomation(0, 0);
+ }}
+ ]);
+ }
+ });
+ }
+ trName.append($("<td />"));
+ trName.append($("<td />"));
+ var tdm = $("<td />").css({"border-left": "2px solid black"}).appendTo(trAmp);
+ var tdvu = $("<td />").appendTo(trAmp);
+ var elm = $("<div />").appendTo(tdm);
+ var elmvu = $("<div />").appendTo(tdvu);
+ var mc = new Control({
+ name: "Master",
+ image: "Sexan_Timb-Slider_29334-128fr",
+ target: elm,
+ channel: mixer.masterAmpChannel,
+ width: width,
+ height: height,
+ noTriggerInit: true,
+ onReady: async function(mc) {
+ mc.value = await app.getControlChannel(mixer.masterAmpChannel);
+ }
+ });
+
+ masterVu = new Control({
+ name: "VU",
+ image: "Timb_MeterXRAYMANALOGDEF_8320-128",
+ target: elmvu,
+ width: 15,
+ height: height
+ });
+ }
+};
\ No newline at end of file diff --git a/site/app/twine/timeline.js b/site/app/twine/timeline.js new file mode 100644 index 0000000..9e33a4c --- /dev/null +++ b/site/app/twine/timeline.js @@ -0,0 +1,736 @@ +var Locators = function(timeline, elTimebar, elChannelOverlay) {
+ var locators = this;
+ var items = {
+ start: {
+ elMain: $("<div />").addClass("twine_timeline_timebar_locatorhead").appendTo(elTimebar),
+ elLine: $("<div />").addClass("twine_timeline_timebar_locatorline").appendTo(elChannelOverlay),
+ setLeft: function(px){
+ items.start.elMain.show().css("left", px - (items.start.elMain.width() / 2));
+ items.start.elLine.show().css("left", px);
+ },
+ hide: function() {
+ items.start.elMain.hide();
+ items.start.elLine.hide();
+ }
+ },
+ regionStart: {
+ elMain: $("<div />").addClass("twine_timeline_timebar_regionstart").appendTo(elTimebar),
+ elLine: $("<div />").addClass("twine_timeline_timebar_regionstart").appendTo(elChannelOverlay),
+ setLeft: function(px){
+ items.regionStart.elMain.show().css("left", px - (items.regionStart.elMain.width() / 2));
+ items.regionStart.elLine.show().css("left", px);
+ },
+ hide: function() {
+ items.regionStart.elMain.hide();
+ items.regionStart.elLine.hide();
+ }
+ },
+ regionEnd: {
+ elMain: $("<div />").addClass("twine_timeline_timebar_regionstart").appendTo(elTimebar),
+ elLine: $("<div />").addClass("twine_timeline_timebar_regionstart").appendTo(elChannelOverlay),
+ setLeft: function(px){
+ items.regionEnd.elMain.show().css("left", px - (items.regionEnd.elMain.width() / 2));
+ items.regionEnd.elLine.show().css("left", px);
+ },
+ hide: function() {
+ items.regionEnd.elMain.hide();
+ items.regionEnd.elLine.hide();
+ }
+ }
+ };
+
+
+ items.regionStart.elMain.on("mousedown", function(es) {
+ es.preventDefault();
+ es.stopPropagation();
+ var offset = elTimebar.offset().left;
+ var max = elTimebar.width();
+ var startLeft = parseFloat(items.regionStart.elLine.css("left"));
+ function mouseup() {
+ $("body").off("mousemove", mousemove).off("mouseup", mouseup);
+ }
+
+ function mousemove(e) {
+ var newPos = (e.clientX - es.clientX) + startLeft;
+ newPos = timeline.roundToGrid(newPos);
+ if (newPos < 0) {
+ newPos = 0;
+ } else if (newPos > max) {
+ newPos = max;
+ }
+
+ var offset = elTimebar.offset().left;
+ var beats = timeline.beatRegion[1] - timeline.beatRegion[0];
+ var beat = timeline.beatRegion[0] + (Math.round((newPos / (max - offset)) * beats * 100) / 100);
+ if (beat > timeline.data.beatEnd - 1) {
+ return;
+ }
+ items.regionStart.setLeft(newPos);
+ timeline.data.beatStart = beat;
+ }
+ $("body").on("mousemove", mousemove).on("mouseup", mouseup);
+ });
+
+ items.regionEnd.elMain.on("mousedown", function(es) {
+ es.preventDefault();
+ es.stopPropagation();
+ var offset = elTimebar.offset().left;
+ var max = elTimebar.width();
+ var startLeft = parseFloat(items.regionEnd.elLine.css("left"));
+ function mouseup() {
+ $("body").off("mousemove", mousemove).off("mouseup", mouseup);
+ }
+
+ function mousemove(e) {
+ var newPos = (e.clientX - es.clientX) + startLeft;
+ newPos = timeline.roundToGrid(newPos);
+ if (newPos < 0) {
+ newPos = 0;
+ } else if (newPos > max) {
+ newPos = max;
+ }
+
+ var offset = elTimebar.offset().left;
+ var beats = timeline.beatRegion[1] - timeline.beatRegion[0];
+ var beat = timeline.beatRegion[0] + (Math.round((newPos / (max - offset)) * beats * 100) / 100);
+ if (beat < timeline.data.beatStart + 1) {
+ return;
+ }
+ items.regionEnd.setLeft(newPos);
+ timeline.data.beatEnd = beat;
+ }
+ $("body").on("mousemove", mousemove).on("mouseup", mouseup);
+ });
+
+
+ items.start.elMain.on("mousedown", function(es) {
+ es.preventDefault();
+ es.stopPropagation();
+ var offset = elTimebar.offset().left;
+ var max = elTimebar.width();
+ var startLeft = parseFloat(items.start.elLine.css("left"));
+ function mouseup() {
+ $("body").off("mousemove", mousemove).off("mouseup", mouseup);
+ }
+
+ function mousemove(e) {
+ var newPos = (e.clientX - es.clientX) + startLeft;
+ newPos = timeline.roundToGrid(newPos);
+ if (newPos < 0) {
+ newPos = 0;
+ } else if (newPos > max) {
+ newPos = max;
+ }
+ items.start.setLeft(newPos);
+ var offset = elTimebar.offset().left;
+ var beats = timeline.beatRegion[1] - timeline.beatRegion[0];
+ var beat = timeline.beatRegion[0] + (Math.round((newPos / (max - offset)) * beats * 100) / 100);
+ timeline.startLocation = beat;
+ }
+ $("body").on("mousemove", mousemove).on("mouseup", mouseup);
+ });
+
+ this.redrawStart = function() {
+ if (timeline.startLocation >= timeline.beatRegion[1] || timeline.startLocation < timeline.beatRegion[0]) {
+ items.start.hide();
+ return;
+ }
+ var ratio = (timeline.startLocation - timeline.beatRegion[0]) / (timeline.beatRegion[1] - timeline.beatRegion[0]);
+ var eltWidth = elTimebar.width() - elTimebar.offset().left;
+ var px = ratio * eltWidth;
+ items.start.setLeft(px);
+ }
+}; // end locators
+
+
+
+var Timeline = function(twine, data) {
+ var timeline = this;
+ var elDragSelection;
+ timeline.selectedClips = [];
+ timeline.selectedChannel = null;
+ timeline.startLocation = 0;
+
+ Object.defineProperty(timeline, "selectedClip", {
+ get: function() {
+ return timeline.selectedClips[timeline.selectedClips.length - 1];
+ },
+ set: function(c) {
+ timeline.selectedClips = [c];
+ }
+ });
+
+ var container = $("#twine_timeline");
+ var elTimebarContainer = $("<div />").attr("id", "twine_timeline_timebar").appendTo(container);
+ var elTimebar = $("<div />").attr("id", "twine_timeline_timebar_inner").appendTo(elTimebarContainer);
+ this.element = $("<div />").attr("id", "twine_timeline_inner").appendTo(container);
+ $("<div />").attr("id", "twine_timelineoverlay").appendTo(timeline.element);
+ var elChannelOverlay = $("<div />").attr("id", "twine_timeline_channeloverlay").appendTo(container);
+ var elScrollOuter = $("<div />").attr("id", "twine_timeline_scroll_outer").appendTo(container);
+ var elScrollInner = $("<div />").attr("id", "twine_timeline_scroll_inner").appendTo(elScrollOuter);
+ var elIcons = $("<div />").attr("id", "twine_timeline_scroll_filler").appendTo(container);
+ var elPlayhead = $("<div />").attr("id", "twine_timeline_playposition").appendTo(elChannelOverlay);
+
+ var locators = new Locators(timeline, elTimebar, elChannelOverlay);
+
+ elIcons.append(twirl.createIcon({
+ label: "Zoom in",
+ size: 20,
+ icon: "zoomIn",
+ click: function() {
+ timeline.zoomIn();
+ }
+ }).el);
+
+ elIcons.append(twirl.createIcon({
+ label: "Zoom out",
+ size: 20,
+ icon: "zoomOut",
+ click: function() {
+ timeline.zoomOut();
+ }
+ }).el);
+
+ elIcons.append(twirl.createIcon({
+ label: "Show all",
+ size: 20,
+ icon: "showAll",
+ click: function() {
+ timeline.showAll();
+ }
+ }).el);
+
+ var channelIndex = 0;
+ this.channels = [];
+ this.gridPixels = 40;
+ this.pixelsPerBeat = 10;
+ this.beatRegion = [];
+ this.playbackBeatStart = 0;
+
+ if (data) {
+ this.data = data;
+ } else {
+ this.data = {
+ name: "New arrangement",
+ snapToGrid: 4,
+ gridVisible: true,
+ beatStart: 0,
+ beatEnd: 16,
+ bpm: 120,
+ timeSigMarker: 4,
+ regionStart: 0,
+ regionEnd: 1
+ };
+ }
+
+ elTimebar.click(function(e) {
+ var offset = elTimebar.offset().left;
+ var beats = timeline.beatRegion[1] - timeline.beatRegion[0];
+ var px = timeline.roundToGrid(e.clientX - offset);
+ var width = elTimebar.width() - offset; // ????
+ var beat = timeline.beatRegion[0] + (Math.round((px / width) * beats * 100) / 100);
+ timeline.startLocation = beat;
+ locators.redrawStart();
+ twine.stopAndPlay(beat);
+ });
+
+
+ this.getTotalBeatDuration = function() {
+ return timeline.data.beatEnd * (60 / timeline.data.bpm);
+ };
+
+ this.changeBeatEnd = function(newBeatEnd, noredraw) {
+ var original = timeline.data.beatEnd;
+ timeline.data.beatEnd = newBeatEnd;
+ for (let c of timeline.channels) {
+ c.changeBeatEnd(original, newBeatEnd, noredraw);
+ }
+ };
+
+ this.extend = function(newBeatEnd, noredraw) {
+ if (newBeatEnd > timeline.data.beatEnd) {
+ timeline.changeBeatEnd(newBeatEnd, noredraw);
+ }
+ };
+
+ this.reduce = function() {
+ var end = 0;
+ for (let ch of timeline.channels) {
+ for (let i in ch.clips) {
+ if (ch.clips[i]) {
+ var e = ch.clips[i].data.position + ch.clips[i].data.playLength;
+ if (e > end) {
+ end = e;
+ }
+ }
+ }
+ }
+ end += 8;
+ timeline.data.beatEnd = end;
+ };
+
+ this.exportData = async function() {
+ var saveData = {
+ channels: [],
+ data: timeline.data,
+ masterAmp: (await app.getControlChannel(twine.mixer.masterAmpChannel)),
+ ftables: {}
+ };
+ for (let c of timeline.channels) {
+ saveData.channels.push(await c.exportData());
+ }
+ for (let ch of saveData.channels) {
+ for (let cl of ch.clips) {
+ var fnL = cl.table[0];
+ var fnR = cl.table[1];
+ if (!saveData.ftables[fnL] && fnL > 0) {
+ saveData.ftables[fnL] = {
+ length: await app.getCsound().tableLength(fnL),
+ data: (await app.getCsound().tableCopyOut(fnL)).values().toArray()
+ };
+ }
+ if (!saveData.ftables[fnR] && fnR > 0) {
+ saveData.ftables[fnR] = {
+ length: await app.getCsound().tableLength(fnR),
+ data: (await app.getCsound().tableCopyOut(fnR)).values().toArray()
+ };
+ }
+ }
+ }
+ return saveData;
+ };
+
+ this.createFtable = async function(length) {
+ return new Promise(function(resolve, reject) {
+ var cbid = app.createCallback(function(ndata){
+ resolve(ndata.table);
+ });
+ app.insertScore("twine_createtable", [0, 1, cbid, length]);
+ });
+ };
+
+ this.copyNewTableIn = async function(data) {
+ var ftable = await timeline.createFtable(data.length);
+ await app.getCsound().tableCopyIn(ftable, data);
+ return ftable;
+ };
+
+ this.importData = async function(loadData) {
+ timeline.data = loadData.data;
+ await app.setControlChannel(twine.mixer.masterAmpChannel, loadData.masterAmp);
+ var ftMap = {};
+ console.log("load ftables", loadData.ftables);
+ for (let i in loadData.ftables) {
+ var fn = await timeline.copyNewTableIn(loadData.ftables[i].data);
+ console.log("copy into", fn, loadData.ftables[i]);
+ window.fn = loadData.ftables[i];
+ ftMap[i] = fn;
+ }
+
+ while (timeline.channels.length > 0) {
+ timeline.channels[0].remove();
+ }
+
+ timeline.channels = [];
+ var channelIndex = 0;
+ for (let c of loadData.channels) {
+ var channel = new Channel(timeline, channelIndex ++);
+ timeline.channels.push(channel);
+ await channel.importData(c, ftMap);
+ }
+ timeline.redraw();
+ };
+
+ var playheadInterval;
+ this.setPlaying = function(state) {
+ twine.ui.head.play.setValue(state);
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ if (state) {
+ playheadInterval = setInterval(async function(){
+ var val = await app.getControlChannel("twine_playpos");
+ var beat = (val * (timeline.data.bpm / 60)) + timeline.playbackBeatStart;
+ if (beat > timeline.beatRegion[1]) {
+ clearInterval(playheadInterval);
+ elPlayhead.hide();
+ }
+ var pos = beat * timeline.pixelsPerBeat;
+ elPlayhead.css("left", pos + "px");
+ }, 50);
+ elPlayhead.show();
+ } else {
+ elPlayhead.hide();
+ }
+ };
+
+ this.zoomIn = function() {
+ timeline.setRegion(
+ timeline.data.regionStart * 1.1,
+ timeline.data.regionEnd * 0.9
+ );
+ };
+
+ this.zoomOut = function() {
+ timeline.setRegion(
+ timeline.data.regionStart * 0.9,
+ timeline.data.regionEnd * 1.1
+ );
+ timeline.redraw();
+ };
+
+ this.showAll = function() {
+ timeline.setRegion(0, 1);
+ };
+
+ this.compileAutomationData = function(onready) {
+ var changed = false;
+ for (let c of timeline.channels) {
+ if (c.automationChanged()) {
+ changed = true;
+ break;
+ }
+ }
+ if (!changed) {
+ return onready(1);
+ }
+
+ var start = timeline.data.beatStart / (timeline.data.beatEnd - timeline.data.beatStart);
+ var instr = "instr twine_automaterun\n";
+ for (let c of timeline.channels) {
+ for (let a of c.getAutomationData(start, 1)) {
+ instr += a + "\n"
+ }
+ }
+ instr += "a_ init 0\nout a_\nendin\n";
+ console.log(instr);
+ app.compileOrc(instr).then(function(status){
+ if (status < 0) {
+ self.errorHandler("Cannot parse automation data");
+ } else {
+ onready(1);
+ }
+ });
+ };
+
+ function determineChannelForAdd() {
+ var channel;
+ if (!timeline.selectedChannel) {
+ if (timeline.channels.length == 0) {
+ channel = timeline.addChannel();
+ } else {
+ channel = timeline.channels[0];
+ }
+ } else {
+ channel = timeline.selectedChannel;
+ }
+ return channel;
+ }
+
+ this.addScriptClip = function() {
+ var channel = determineChannelForAdd();
+ var clip = new Clip(twine);
+ clip.data.position = timeline.playbackBeatStart; //timeline.beatRegion[0];
+ channel.addClip(clip);
+ clip.initScript();
+ clip.redraw();
+ };
+
+ this.addBlankClip = function() {
+ var el = $("<div />");
+ el.append($("<h4 />").text("New blank clip"));
+ let pStereo = new twirl.transform.Parameter({
+ definition: {
+ name: "Stereo",
+ description: "Whether the clip should be stereo or mono",
+ fireChanges: false, automatable: false,
+ min: 0, max: 1, step: 1, dfault: 1
+ },
+ host: twine
+ });
+ let pDuration = new twirl.transform.Parameter({
+ definition: {
+ name: "Duration",
+ description: "Duration of the clip in seconds",
+ fireChanges: false, automatable: false,
+ min: 0.1, max: 30, step: 0.01, dfault: 10
+ },
+ host: twine
+ });
+ var tb = $("<tbody />").appendTo($("<table />").appendTo(el));
+ tb.append(pStereo.getElementRow(true));
+ tb.append(pDuration.getElementRow(true));
+ twirl.prompt.show(el, function(){
+ var channel = determineChannelForAdd();
+ var clip = new Clip(twine);
+ clip.data.position = timeline.playbackBeatStart; //timeline.beatRegion[0];
+ channel.addClip(clip);
+ clip.createSilence(pStereo.getValue(), pDuration.getValue(), name);
+ });
+ };
+
+ this.addChannel = function() {
+ var channel = new Channel(timeline, channelIndex ++);
+ timeline.channels.push(channel);
+ timeline.drawGrid();
+ return channel;
+ };
+
+
+ this.contractChannels = function() {
+ for (let c of timeline.channels) {
+ c.contract();
+ }
+ };
+
+ this.roundToGrid = function(px) {
+ if (timeline.data.snapToGrid) {
+ return twine.roundToNearest(px, twine.timeline.gridPixels, twine.timeline.gridOffset);
+ } else {
+ return px;
+ }
+ };
+
+
+
+ this.roundToChannel = function(px) {
+ var total = 0;
+ var rounded = px;
+ for (let i in timeline.channels) {
+ var c = timeline.channels[i];
+ if (i == 0) rounded = c.height;
+ total += c.height + 1;
+ if (px > total) {
+ rounded = total;
+ }
+ }
+ return rounded;
+ };
+
+ this.determineChannelFromTop = function(posTop) {
+ var top = 0;
+ for (var c of timeline.channels) {
+ top += c.height;
+ if (posTop < top) {
+ return c;
+ }
+ }
+ return c;
+ };
+
+ function calcViewport() {
+ var cc = $(".twine_channelclips");
+ var width = $("#twine_timeline_channeloverlay").width(); //cc.width();
+ var d = timeline.data;
+ timeline.beatRegion = [
+ d.regionStart * d.beatEnd,
+ d.regionEnd * d.beatEnd
+ ];
+ var gridScale = 1;
+ var beats = timeline.beatRegion[1] - timeline.beatRegion[0];
+ timeline.pixelsPerBeat = width / beats;
+ timeline.gridPixels = timeline.pixelsPerBeat / parseInt(d.snapToGrid);
+ var beat = timeline.beatRegion[0];
+ timeline.gridOffset = (parseInt(beat) - beat) * timeline.pixelsPerBeat;
+ return {
+ minLeft: 0, //cc.offset().left,
+ width: width,
+ beat: beat
+ }
+ }
+
+
+ this.drawGrid = function() {
+ if (timeline.channels.length == 0) return;
+ $(".twine_timelinemarker").remove();
+ $(".twine_timelinetext").remove();
+ var vp = calcViewport();
+ if (!timeline.data.gridVisible) return;
+
+ var width;
+ var fontWeight;
+ beat = Math.floor(vp.beat);
+ for (var x = vp.minLeft + timeline.gridOffset; x < vp.width; x += timeline.pixelsPerBeat) {
+ if ((beat - 1) % timeline.data.timeSigMarker == 0) {
+ width = 2;
+ fontWeight = "bold";
+ } else {
+ width = 1;
+ fontWeight = "normal";
+ }
+ if (x >= 0) {
+ $("<div />").attr("class", "twine_vline twine_timelinemarker").appendTo(elChannelOverlay).css("width", width).css("left", x).css("top", "0px");
+ $("<div />").attr("class", "twine_timelinetext").appendTo(elChannelOverlay).css("font-weight", fontWeight).css("left", x + 2).text(beat);
+ }
+ beat ++;
+ }
+ locators.redrawStart();
+ }
+
+ var drawing;
+ this.redraw = function(noClipWaveRedraw) {
+ if (drawing) return;
+ drawing = true;
+ timeline.drawGrid();
+ for (let c of timeline.channels) {
+ c.redraw(noClipWaveRedraw);
+ }
+ drawing = false;
+ };
+
+ this.setRegion = function(start, end, noClipWaveRedraw) {
+ timeline.reduce();
+ if (end <= start) return;
+ if (end > 1) end = 1;
+ if (start < 0) start = 0;
+ timeline.data.regionStart = start;
+ timeline.data.regionEnd = end;
+ timeline.redraw(noClipWaveRedraw);
+ var elTbcw = elScrollOuter.width();
+ elScrollInner.css({left: (timeline.data.regionStart * elTbcw) + "px", right: ((1 - timeline.data.regionEnd) * elTbcw) + "px"});
+ if (self.onRegionChange) {
+ self.onRegionChange([timeline.data.regionStart, timeline.data.regionEnd]);
+ }
+ };
+
+ this.onRegionChange = function(region) {
+
+ };
+
+
+ function setScrollBarPosition(displayLeft, displayRight, setRegion) {
+ if (displayLeft >= 0 && displayRight >= 0) {
+ elScrollInner.css({left: displayLeft, right: displayRight});
+ var w = elScrollOuter.width();
+ if (setRegion) {
+ timeline.data.regionStart = displayLeft / w;
+ timeline.data.regionEnd = 1 - (displayRight / w);
+ if (self.onRegionChange) {
+ self.onRegionChange([timeline.data.regionStart, timeline.data.regionEnd]);
+ }
+ }
+ }
+ }
+
+ elScrollOuter.mousedown(function() {
+ var increment = 20;
+ var apos = event.pageX - elScrollOuter.offset().left;
+ var left = parseInt(elScrollInner.css("left"));
+ var right = parseInt(elScrollInner.css("right"));
+ var tbWidth = parseInt(elScrollInner.css("width"));
+ if (apos < left) {
+ left -= increment;
+ right += increment;
+ } else if (apos > left + tbWidth) {
+ left += increment;
+ right -= increment;
+ } else {
+ return;
+ }
+ setScrollBarPosition(left, right, true);
+ timeline.redraw();
+ });
+
+ elScrollInner.mousedown(function(e){
+ var pageX = e.pageX;
+ var offset = elScrollOuter.offset();
+ var cWidth = elScrollOuter.width();
+ var tbWidth = elScrollInner.width();
+ var sLeft = pageX - offset.left - parseInt(elScrollInner.css("left"));
+
+ function handleDrag(e) {
+ var left = ((e.pageX - pageX) + (pageX - offset.left));
+ left = left - sLeft;
+ var end = left + tbWidth;
+ var right = cWidth - end;
+ setScrollBarPosition(left, cWidth - end, true);
+ timeline.redraw(true);
+
+ }
+ function handleMouseUp(e) {
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp);
+ function ensureDraw() {
+ if (drawing) return setTimeout(ensureDraw, 20);
+ timeline.redraw();
+ }
+ ensureDraw();
+ }
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ });
+
+ this.deselectClips = function() {
+ timeline.selectedClips = [];
+ $(".twine_clip").css("outline", "none");
+ };
+
+ this.dragSelection = function(e){
+ var elChannelOverlay = $("#twine_timeline_channeloverlay");
+ var pageX = e.pageX;
+ var pageY = e.pageY;
+ var offset = elChannelOverlay.offset();
+ var width = elChannelOverlay.width();
+ var height = elChannelOverlay.height();
+ var left = (pageX - offset.left);
+ var top = (pageY - offset.top);
+ if (!elDragSelection) {
+ elDragSelection = $("<div />").addClass("drag_selection").appendTo(elChannelOverlay);
+ }
+ elDragSelection.hide().css({left: left + "px", top: top + "px"});
+
+ function handleDrag(e) {
+ elDragSelection.show();
+ var xMovement = e.pageX - pageX;
+ var yMovement = e.pageY - pageY;
+ if (xMovement < 0) {
+ elDragSelection.css({
+ left: (left + xMovement) + "px"
+ });
+ }
+ elDragSelection.css({
+ width: Math.abs(xMovement) + "px"
+ });
+
+ if (yMovement < 0) {
+ elDragSelection.css({
+ top: (top + yMovement) + "px"
+ });
+ }
+ elDragSelection.css({
+ height: Math.abs(yMovement) + "px"
+ });
+
+ }
+
+ function handleMouseUp(e) {
+ elDragSelection.hide();
+ var left = parseFloat(elDragSelection.css("left"));
+ var width = parseFloat(elDragSelection.css("width"));
+ var top = parseFloat(elDragSelection.css("top"));
+ var height = parseFloat(elDragSelection.css("height")) - 10;
+ var channelStart = timeline.determineChannelFromTop(top).index;
+ var channelEnd = timeline.determineChannelFromTop(top + height).index;
+
+ var beatStart = ((left / timeline.pixelsPerBeat) + timeline.beatRegion[0]) - 0.01;
+ var beatEnd = (((left + width) / timeline.pixelsPerBeat) + timeline.beatRegion[0]) + 0.01;
+ timeline.deselectClips();
+ for (let ch of timeline.channels) {
+ if (ch.index >= channelStart && ch.index <= channelEnd) {
+ for (let ci in ch.clips) {
+ var cl = ch.clips[ci];
+ if (cl) {
+ if (cl.data.position >= beatStart && cl.data.position + cl.data.playLength <= beatEnd) {
+ cl.markSelected();
+ timeline.selectedClips.push(cl);
+
+ }
+ }
+ }
+ }
+ }
+ $("body").off("mousemove", handleDrag).off("mouseup", handleMouseUp);
+ }
+ $("body").on("mouseup", handleMouseUp).on("mousemove", handleDrag);
+ };
+
+ timeline.drawGrid();
+};
diff --git a/site/app/twine/twine.csd b/site/app/twine/twine.csd new file mode 100644 index 0000000..1f31907 --- /dev/null +++ b/site/app/twine/twine.csd @@ -0,0 +1,413 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+#define ECP_NORECORDING ##
+
+;#include "scss/elasticlip_sequencer.udo"
+#include "/scss/elasticlip.udo"
+;#include "scss/mixer/base.udo"
+#include "/interop.udo"
+#include "/host_platform.udo"
+#include "/bussing.udo"
+#include "/table_tools.udo"
+#include "/lagdetect.udo"
+
+#include "/twigs/twigs.udo"
+#include "/twist/twist.udo"
+
+
+
+instr twine_automaterun
+endin
+
+opcode _twine_playrecurse, i, ikiioj
+ iplayfn, ktimes, imaxchannels, iplayfnsize, index, iusedchanfn xin
+ if (iusedchanfn == -1) then
+ iusedchanfn ftgentmp 0, 0, -imaxchannels, -2, 0
+ endif
+
+ iclipindex tab_i index, iplayfn
+ istart tab_i index + 1, iplayfn
+ iduration tab_i index + 2, iplayfn
+ ichannel tab_i index + 3, iplayfn
+ istartoffset tab_i index + 4, iplayfn
+ tabw_i 1, ichannel, iusedchanfn
+
+ if (ktimes >= istart && ktimes <= istart + iduration) then
+ if (iclipindex < 0) then
+ aL, aR subinstr sprintf("twinescript%d", -iclipindex), iduration, istartoffset
+ else
+ aL, aR subinstr "ecp_playback_tst", -1, iclipindex, iduration, istartoffset ; sort out channels
+ endif
+ bus_mix sprintf("mxchan%d", ichannel), aL, aR
+ endif
+
+ if (index + 5 < iplayfnsize) then
+ i_ _twine_playrecurse iplayfn, ktimes, imaxchannels, iplayfnsize, index + 5, iusedchanfn
+ endif
+ xout iusedchanfn
+endop
+
+opcode _twine_channelrecurse, 0, io
+ iusedchanfn, index xin
+ if (tab_i(index, iusedchanfn) == 1) then
+ a_ subinstr sprintf("twine_channel%d", index)
+ endif
+
+ if (index + 1 < ftlen(iusedchanfn)) then
+ _twine_channelrecurse iusedchanfn, index + 1
+ endif
+endop
+
+opcode twine_playback, aa, ikii
+ iplayfn, ktimes, imaxchannels, iplayfnsize xin
+ gitwst_tf_state[0] = 1
+ gitwst_tf_state[1] = 1
+ iusedchanfn _twine_playrecurse iplayfn, ktimes, imaxchannels, iplayfnsize
+ _twine_channelrecurse iusedchanfn
+ a_ subinstr "twine_automaterun"
+ aL, aR bus_read "twine_master"
+ kamp chnget "twine_masteramp"
+ aL *= kamp
+ aR *= kamp
+ xout aL, aR
+endop
+
+instr twine_masteroutput
+ aL, aR bus_read "twine_master"
+ outs aL, aR
+endin
+
+instr twine_createtable
+ icbid = p4
+ ilen = p5
+ ifn ftgen 0, 0, -ilen, -2, 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"table\":%d}", icbid, ifn))
+ turnoff
+endin
+
+
+instr twine_removetable
+ icbid = p4
+ ifn = p5
+ ftfree ifn, 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d}", icbid))
+ turnoff
+endin
+
+
+instr twine_removeclip
+ icbid = p4
+ iclipindex = p5
+ ecp_removeclip iclipindex
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ turnoff
+endin
+
+
+instr twine_render_complete
+ icbid = p4
+ ifnoutL = p5
+ ifnoutR = p6
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1,\"fnL\":%d,\"fnR\":%d}", icbid, ifnoutL, ifnoutR))
+ turnoff
+endin
+
+
+instr twine_convertsr_complete
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+ turnoff
+endin
+
+instr twine_convertsr
+ icbid = p4
+ iclipindex = p5
+ isourcesr = p6
+ ifndata = giecp_fnclips[iclipindex]
+ ifnL tab_i 0, ifndata
+ ifnR tab_i 1, ifndata
+ if (ifnR > 0) then
+ ifnnewL, ifnnewR, kdone tab_samplerateconvert ifnL, ifnR, 1, isourcesr
+ else
+ ifnnewL, kdone tab_samplerateconvert ifnL, 1, isourcesr
+ ifnnewR = 0
+ endif
+ tabw_i ifnnewL, 0, ifndata
+ tabw_i ifnnewR, 1, ifndata
+ if (kdone == 1) then
+ schedulek("twine_convertsr_complete", 0, 1, icbid)
+ turnoff
+ endif
+endin
+
+instr twine_render
+ icbid = p4
+ ifn = p5
+ imaxchannels = p6
+ iduration = p7
+ itarget = p8 ; 0 = ftable, 1 = file,
+ ifnsize = p9
+ ifreeplaybacktable = p11
+ if (itarget == 1) then
+ Spath = strget(p10)
+ ifnoutL = 0
+ ifnoutR = 0
+ else
+ Spath = ""
+ ioutlen = iduration * sr
+ if (ioutlen >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":-2}", icbid))
+ turnoff
+ endif
+ ifnoutL ftgen 0, 0, -ioutlen, -2, 0
+ ifnoutR ftgen 0, 0, -ioutlen, -2, 0
+ endif
+
+ if (ifreeplaybacktable == 1) then
+ ftfree ifn, 1
+ endif
+ p3 = 3600
+
+ iblocks = 100
+
+ ikcycles = round(iduration * kr)
+
+ if (ikcycles < iblocks) then
+ ikcyclesperblock = ikcycles
+ else
+ ikcyclesperblock = round(ikcycles / iblocks)
+ endif
+ ktotalcount init 0
+ klastpercent init 100
+
+ if (ktotalcount < ikcycles) then
+ kcount = 0
+ while (kcount < ikcyclesperblock) do
+ aL, aR twine_playback ifn, ktotalcount / kr, imaxchannels, ifnsize
+ if (itarget == 0) then
+ apos lphasor 1
+ tablew aL, apos, ifnoutL
+ tablew aR, apos, ifnoutR
+ else
+ fout Spath, 14, aL, aR
+ endif
+ kcount += 1
+ ktotalcount += 1
+ od
+ kpercent = round((100 / ikcycles) * ktotalcount)
+ if (kpercent != klastpercent) then
+ io_send "percent", kpercent
+ klastpercent = kpercent
+ endif
+ else
+ schedulek("twine_render_complete", 0, 1, icbid, ifnoutL, ifnoutR)
+ turnoff
+ endif
+endin
+
+instr twine_getsr
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"sr\":%d}", icbid, sr))
+ turnoff
+endin
+
+instr twine_playback_complete
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":0}", icbid))
+ turnoff
+endin
+
+instr twine_playback_lag
+ icbid = p4
+ turnoff2 "twine_playback", 0, 0
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":-1}", icbid))
+ turnoff
+endin
+
+instr twine_playback
+ icbid = p4
+ ifn = p5
+ imaxchannels = p6
+ ifnsize = p7
+ ifreeplaybacktable = p8
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":1}", icbid))
+
+ if (ifreeplaybacktable == 1) then
+ ftfree ifn, 1
+ endif
+
+ ktimes timeinsts
+ chnset ktimes, "twine_playpos"
+ aL, aR twine_playback ifn, ktimes, imaxchannels, ifnsize
+ klevel = rms:k((aL + aR) / 2) * 1.4
+ chnset klevel, "twine_mastervu"
+ outs aL, aR
+
+ klagging lagdetect 1.1
+ if (klagging == 1) then
+ schedulek("twine_playback_lag", 0, 1, icbid)
+ endif
+
+ kreleasing init 0
+ if (lastcycle:k() == 1 || (kreleasing == 0 && release:k() == 1)) then
+ kreleasing = 1
+ schedulek("twine_playback_complete", 0, 1, icbid)
+ endif
+endin
+
+instr twine_playback_complete
+ icbid = p4
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"status\":0}", icbid))
+ turnoff
+endin
+
+instr twine_playbackwatchdog
+ icbid = p4
+ kreleasing init 0
+ if (lastcycle:k() == 1 || (kreleasing == 0 && release:k() == 1)) then
+ kreleasing = 1
+ schedulek("twine_playback_complete", 0, 1, icbid)
+ endif
+endin
+
+
+instr twine_stopplayback
+ turnoff2 "ecp_playback", 0, 1
+ turnoff3 "ecp_playback"
+ turnoff2 "twine_playback", 0, 1
+ turnoff2 "twine_playbackwatchdog", 0, 1
+ turnoff
+endin
+
+
+
+instr twine_setbpm
+ ibpm = p4
+ gkseq_tempo init ibpm
+ turnoff
+endin
+
+
+instr twine_createblankclip
+ icbid = p4
+ istereo = p5
+ iduration = p6
+ ilen = iduration * sr
+ ifnL ftgen 0, 0, -ilen, 2, 0
+ if (istereo == 1) then
+ ifnR ftgen 0, 0, -ilen, 2, 0
+ else
+ ifnR = 0
+ endif
+
+ iclipindex ecp_addclip "", ifnL, ifnR, 4, 4
+ Sresponse = sprintf("{\"cbid\":%d,\"status\":1,\"data\":{\"clipindex\":%d,\"datatable\":%d}}", icbid, iclipindex, giecp_fnclips[iclipindex])
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+instr twine_importclip
+ icbid = p4
+ idatafn = p5
+ iclipindex ecp_importclip idatafn
+ Sresponse = sprintf("{\"cbid\":%d,\"status\":1,\"data\":{\"clipindex\":%d,\"datatable\":%d}}", icbid, iclipindex, idatafn)
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+instr twine_loadftables
+ icbid = p4
+ ifnL = p5
+ ifnR = p6
+ istatus = -10
+ Sdata = "{}"
+
+ if (ifnL <= 0) then
+ istatus = -1
+ goto complete
+ endif
+
+ iclipindex ecp_addclip "", ifnL, ifnR, 4, 4 ; name not really required any more, beats contentious, analyse and also set warp mode
+ Sdata = sprintf("{\"clipindex\":%d,\"datatable\":%d}", iclipindex, giecp_fnclips[iclipindex])
+
+complete:
+ Sresponse = sprintf("{\"cbid\":%d,\"status\":%d,\"data\":%s}", icbid, istatus, Sdata)
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+instr twine_loadpath
+ icbid = p4
+ Spath = strget(p5)
+ iforcemono = p6
+ istatus = -10
+ Sdata = "{}"
+
+ if (filevalid(Spath) != 1) then
+ istatus = -1
+ goto complete
+ endif
+
+ ifilesr = filesr(Spath)
+ ilens = filelen(Spath)
+ ilen = round(ilens * ifilesr)
+
+ if (ilen >= gihost_max32bitftlen || ilens * sr >= gihost_max32bitftlen) then ; limitation with WASM Csound build at the moment
+ istatus = -2
+ goto complete
+ endif
+
+ iclipindex ecp_loadsound Spath, 4, iforcemono ; beats contentious, analyse and also set warp mode, also SR conversion
+ Sdata = sprintf("{\"clipindex\":%d,\"datatable\":%d}", iclipindex, giecp_fnclips[iclipindex])
+
+ istatus = 1
+
+complete:
+ Sresponse = sprintf("{\"cbid\":%d,\"status\":%d,\"data\":%s}", icbid, istatus, Sdata)
+ io_sendstring("callback", Sresponse)
+ turnoff
+endin
+
+instr twine_setclipaudiounique
+ icbid = p4
+ iclipindex = p5
+ ecp_setaudiounique iclipindex
+ io_sendstring("callback", sprintf("{\"cbid\":%d}", icbid))
+ turnoff
+endin
+
+instr twine_cloneclip
+ icbid = p4
+ iclipindex = p5
+
+ inewclipindex ecp_cloneclip iclipindex
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"clipindex\":%d,\"datatable\":%d}", icbid, inewclipindex, giecp_fnclips[inewclipindex]))
+ turnoff
+endin
+
+
+instr twine_clipreplacetables
+ icbid = p4
+ iclipindex = p5
+ ifnL = p6
+ ifnR = p7
+ ecp_replacetables iclipindex, ifnL, ifnR
+ io_sendstring("callback", sprintf("{\"cbid\":%d,\"clipindex\":%d,\"datatable\":%d}", icbid, iclipindex, giecp_fnclips[iclipindex]))
+ turnoff
+endin
+
+
+</CsInstruments>
+<CsScore>
+f0 z
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/twine/twine.css b/site/app/twine/twine.css new file mode 100644 index 0000000..da01ad7 --- /dev/null +++ b/site/app/twine/twine.css @@ -0,0 +1,438 @@ +#twist {
+ display: none;
+}
+
+#twigs {
+ display: none;
+}
+
+#twine_start {
+ z-index: 300;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: var(--bgColor2);
+ cursor: pointer;
+}
+
+#twine_startinner {
+ z-index: 202;
+ text-align: centre;
+ margin: 0px;
+ position: absolute;
+ top: 20%;
+ left: 20%;
+ width: 60%;
+ height: 40%;
+}
+
+#twine_mixer {
+ overflow-x: auto;
+ overflow-y: hidden;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+#twine_startbig {
+ font-size: 48pt;
+}
+
+td {
+ font-size: var(--fontSizeSmall);
+}
+
+body {
+ font-family: var(--fontFace);
+ color: var(--fgColor1);
+ font-size: var(--fontSizeDefault);
+ user-select: none;
+ cursor: arrow;
+ font-size: 11pt;
+}
+
+#twine_menubar {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ right: 0px;
+ height: 20px;
+ z-index: 6;
+}
+
+.slider {
+ background: var(--bgColor3);
+ accent-color: var(--fgColor2);
+}
+
+#twine_timeline_playposition {
+ position: absolute;
+ width: 1px;
+ opacity: 0.8;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+ background-color: var(--waveformPlayheadColor);
+ z-index: 50;
+ display: none;
+}
+
+.twine_timelinetext {
+ font-size: var(--fontSizeSmall);
+ opacity: 0.9;
+ position: absolute;
+ color: var(--fgColor3);
+ top: 2px;
+ z-index: 4;
+}
+
+#twine_timeline_channeloverlay {
+ position: absolute;
+ left: 10%;
+ right: 0px;
+ top: 0px;
+ height: 100%;
+ user-select: none;
+ pointer-events: none;
+}
+
+.twine_vline {
+ position: absolute;
+ width: 1px;
+ opacity: 0.8;
+ background-color: #bdbdbd;
+ height: 100%;
+ z-index: 4;
+}
+
+
+
+#twine_timeline {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ bottom: 30%;
+ right: 0px;
+ background-color: #dadada;
+}
+
+#twine_main {
+ position: absolute;
+ top: 50px;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+}
+
+#twine_header {
+ position: absolute;
+ top: 20px;
+ height: 30px;
+ left: 0px;
+ width: 100%;
+ background-color: var(--bgColor1);
+ overflow: none;
+}
+
+.knoblabel {
+ font-size: 8pt;
+ text-align: center;
+}
+
+#twine_timelineoverlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ left: 10%;
+ top: 0px;
+ z-index: 50;
+ display: none;
+}
+
+#twine_details {
+ position: absolute;
+ left: 0px;
+ bottom: 0px;
+ width: 100%;
+ height: 30%;
+ background-color: var(--bgColor1);
+}
+
+.twine_clipdetailsleft {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 30%;
+ height: 100%;
+ font-size: var(--fontSizeSmall);
+ background-color: var(--bgColor2);
+}
+
+.twine_clipdetailsright {
+ position: absolute;
+ left: 30%;
+ top: 0px;
+ width: 70%;
+ height: 100%;
+ background-color: var(--bgColor3);
+}
+
+#twine_headertable {
+ height: 30px;
+}
+
+#twine_clipdetails {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ display: none;
+}
+
+#twine_channeldetails {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ display: none;
+ overflow-x: auto;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+.twine_channeldetails_insert {
+ position: absolute;
+ font-size: var(--fontSizeSmall);
+ width: 500px;
+ border-left: 1px solid var(--fgColor3);
+ height: 100%;
+ top: 0px;
+ bottom: 0px;
+ overflow-y: auto;
+ background-color: var(--bgColor1);
+ scrollbar-color: var(--scrollbarColor);
+}
+
+.twine_channeldetails_inserts {
+ position: absolute;
+ left: 200px;
+ right: 0px;
+ height: 100%;
+ top: 0px;
+ overflow-y: scroll;
+ background-color: var(--bgColor2);
+ scrollbar-color: var(--scrollbarColor);
+}
+
+.twine_channeldetails_insertnew {
+ position: absolute;
+ width: 200px;
+ height: 100%;
+ top: 0px;
+ bottom: 0px;
+ overflow-y: auto;
+ background-color: var(--bgColor3);
+ scrollbar-color: var(--scrollbarColor);
+}
+
+.drag_selection {
+ position: absolute;
+ background-color: #323232;
+ opacity: 0.5;
+ user-select: none;
+ z-index: 101;
+}
+
+#twine_timeline_timebar {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ height: 20px;
+ right: 0px;
+ background-color: var(--bgColor2);
+ z-index: 4;
+}
+
+#twine_timeline_timebar_inner {
+ position: absolute;
+ left: 10%;
+ top: 0px;
+ height: 20px;
+ right: 0px;
+ cursor: text;
+ z-index: 4;
+}
+
+.twine_timeline_timebar_locatorhead {
+ position: absolute;
+ /*width: 14px;
+ border-radius: 0px 0px 4px 4px;
+ background-color: var(--waveformLocationColor);
+ height: 100%;
+ */
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ border-left: 14px solid var(--waveformLocationColor);
+ top: 0px;
+ opacity: 0.6;
+ cursor: ew-resize;
+ z-index: 5;
+}
+
+.twine_timeline_timebar_locatorline {
+ position: absolute;
+ width: 1px;
+ background-color: var(--waveformLocationColor);
+ height: 100%;
+ top: 0px;
+ width: 2px;
+ opacity: 0.6;
+ pointer-events: none;
+}
+
+.twine_timeline_timebar_regionstart {
+ position: absolute;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ border-left: 14px solid var(--waveformMarkerColor);
+ top: 0px;
+ opacity: 0.6;
+ cursor: ew-resize;
+ z-index: 5;
+}
+
+.twine_timeline_timebar_regionend {
+ position: absolute;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ border-right: 14px solid var(--waveformMarkerColor);
+ top: 0px;
+ opacity: 0.6;
+ cursor: ew-resize;
+ z-index: 5;
+}
+
+
+#twine_timeline_inner {
+ position: absolute;
+ left: 0px;
+ top: 20px;
+ bottom: 20px;
+ width: 100%;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+#twine_timeline_scroll_filler {
+ position: absolute;
+ background-color: var(--bgColor1);
+ left: 0px;
+ bottom: 0px;
+ width: 10%;
+ height: 20px;
+}
+
+#twine_timeline_scroll_outer {
+ position: absolute;
+ background-color: var(--bgColor2);
+ left: 10%;
+ bottom: 0px;
+ width: 90%;
+ height: 20px;
+ z-index: 7;
+}
+
+#twine_timeline_scroll_inner {
+ position: absolute;
+ background-color: var(--fgColor1);
+ left: 0px;
+ top: 4px;
+ bottom: 4px;
+ right: 0px;
+}
+
+.twine_channel {
+ position: relative;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ height: 40px;
+ font-size: var(--fontSizeSmall);
+ border-bottom: 1px solid black;
+}
+
+.twine_channelclips {
+ position: absolute;
+ left: 10%;
+ width: 90%;
+ background-color: var(--bgColor3);
+ height: 100%;
+ top: 0px;
+ overflow: hidden;
+ user-select: none;
+}
+
+.twine_spline {
+ position: absolute;
+ width: 100%;
+ left: 0px;
+ height: 100%;
+ top: 0px;
+}
+
+.twine_automationselectors {
+ padding: 10px;
+}
+
+.twine_automationselect {
+ padding: 0px;
+ font-size: var(--fontSizeSmall);
+}
+
+.twine_channelcontrol {
+ position: absolute;
+ background-color: var(--bgColor2);
+ left: 0px;
+ width: 10%;
+ height: 100%;
+ top: 0px;
+}
+
+.twine_clip {
+ user-select: none;
+ position: absolute;
+ left: 100px;
+ width: 400px;
+ z-index: 30;
+ overflow: hidden;
+}
+
+.twine_clip_edge_left {
+ position: absolute;
+ cursor: e-resize;
+ height: 100%;
+ top: 0px;
+ width: 5px;
+ left: 0px;
+}
+
+.twine_clip_edge_right {
+ position: absolute;
+ cursor: e-resize;
+ height: 100%;
+ top: 0px;
+ width: 5px;
+ right: 0px;
+}
+
+.twine_clip_centre {
+ position: absolute;
+ cursor: move;
+ height: 100%;
+ top: 0px;
+ left: 5px;
+ right: 5px;
+}
diff --git a/site/app/twine/twine.js b/site/app/twine/twine.js new file mode 100644 index 0000000..c81cc66 --- /dev/null +++ b/site/app/twine/twine.js @@ -0,0 +1,517 @@ +var Twine = function() {
+ var twine = this;
+ var hrefSplit = window.location.href.split("?");
+ if (hrefSplit.length == 2 && hrefSplit[1] == "offline") {
+ twine.offline = true;
+ } else {
+ twine.offline = false;
+ }
+ twine.version = 1;
+ twirl.init();
+ twine.visible = true;
+ var playing = false;
+ var onStop;
+ twine.timeline = new Timeline(twine);
+ twine.ui = new TwineUI(twine);
+ twine.mixer = new Mixer(twine);
+ twine.sr = null;
+ twine.arrangementName = "New twine arrangement";
+ var undoHistory = [];
+ var playbackTable;
+ var playbackTableLength;
+
+ twine.ui.head.name.element.val(twine.arrangementName);
+ twine.ui.head.grid.setValue(1, true);
+ twine.ui.head.snap.setValue(1, true);
+
+ twine.storage = localStorage.getItem("twine");
+ if (twine.storage) {
+ twine.storage = JSON.parse(twine.storage);
+ } else {
+ twine.storage = {
+ showMasterVu: 0,
+ showClipWaveforms: 1
+ };
+ }
+
+ this.saveStorage = function() {
+ localStorage.setItem("twine", JSON.stringify(twine.storage));
+ };
+
+ var maxID = 0;
+ this.getNewID = function() {
+ return maxID++;
+ };
+
+ twine.undo = {
+ add: function(name, func) {
+ undoHistory.push({name: name, func: func});
+ },
+ apply: function() {
+ var item = undoHistory.pop();
+ item.func();
+ //twine.timeline.redraw(); // should be handled in the undo func
+ },
+ clear: function() {
+ undoHistory = [];
+ },
+ has: function() {
+ return (undoHistory.length > 0);
+ },
+ lastName: function() {
+ var name = "";
+ if (undoHistory.length > 0) {
+ name = undoHistory[undoHistory.length - 1].name;
+ }
+ return name ;
+ }
+ };
+
+ this.setPlaying = function(state) {
+ playing = state;
+ playHandler(state);
+ twine.timeline.setPlaying(playing);
+ };
+
+ this.roundToNearest = function(val, multiple, offset) {
+ if (!offset) offset = 0;
+ return (Math.round((val - offset) / multiple) * multiple) + offset;
+ };
+
+ this.stop = function() {
+ if (!playing) return;
+ app.insertScore("twine_stopplayback", [0, 1]);
+ };
+
+ this.exportData = async function() {
+ var saveData = {
+ timeline: await twine.timeline.exportData(),
+ maxID: maxID,
+ arrangementName: twine.arrangementName,
+ version: twine.version,
+ sr: twine.sr
+ }
+ return saveData;
+ };
+
+ this.importData = async function(loadData) {
+ maxID = loadData.maxID;
+ twine.undo.clear();
+ twine.arrangementName = loadData.arrangementName;
+ await twine.timeline.importData(loadData.timeline);
+ twine.ui.head.name.element.val(twine.arrangementName);
+ };
+
+ this.downloadExportData = async function() {
+ twirl.loading.show();
+ const saveData = await twine.exportData();
+ const stream = new Blob([JSON.stringify(saveData)], {type: "application/json"}).stream();
+ const crs = stream.pipeThrough(new CompressionStream("gzip"));
+ const resp = await new Response(crs);
+ const blob = await resp.blob();
+ var name = twine.arrangementName + ".twine";
+ var url = window.URL.createObjectURL(blob);
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a[0].click();
+ twirl.loading.hide();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ }, 20000);
+ };
+
+ this.uploadImportData = async function(blob, onComplete) {
+ twirl.loading.show();
+ // const stream = new Blob([data], {type: "application/json"});
+ const stream = blob.stream();
+ const crs = stream.pipeThrough(new DecompressionStream("gzip"));
+ const resp = await new Response(crs);
+ const dblob = await resp.blob();
+ await twine.importData(JSON.parse(await dblob.text()));
+ if (onComplete) {
+ onComplete();
+ }
+ twirl.loading.hide();
+ };
+
+ this.showMixer = function() {
+ twine.ui.showPane(twine.ui.pane.MIXER);
+ twine.mixer.show();
+ };
+
+ var playHandlerInterval;
+ function playHandler(playing) {
+ if (playHandlerInterval) {
+ clearInterval(playHandlerInterval);
+ }
+ if (playing) {
+ if (twine.storage.showMasterVu) {
+ playHandlerInterval = setInterval(async function(){
+ if (twine.mixer.visible) {
+ twine.mixer.setVu(await app.getControlChannel("twine_mastervu"));
+ }
+ }, 50);
+ }
+ }
+ }
+
+ async function setPlaybackArtefacts(beatStart, beatEnd, onReady) {
+ if (!beatStart) beatStart = 0;
+ twine.timeline.playbackBeatStart = beatStart;
+ var data = [];
+ var time;
+ var playLength;
+ var reltime;
+ var maxbeat = 0;
+ var beatTime = 60 / twine.timeline.data.bpm;
+ for (let ch of twine.timeline.channels) {
+ for (let i in ch.clips) {
+ var cl = ch.clips[i];
+ if (!cl) continue;
+ time = cl.data.position;
+ playLength = cl.data.playLength;
+ if (time + playLength >= beatStart && (!beatEnd || (time <= beatEnd))) {
+ if (time >= beatStart) {
+ offset = 0;
+ } else {
+ offset = beatStart - time;
+ }
+ reltime = time - beatStart;
+ if (reltime + playLength > maxbeat) {
+ maxbeat = reltime + playLength;
+ }
+ if (cl.isAudio) {
+ data.push(cl.data.clipindex);
+ } else {
+ data.push(-cl.data.id);
+ }
+ data.push(Math.max(0, reltime) * beatTime);
+ data.push(playLength * beatTime);
+ data.push(cl.channel.index);
+ data.push(offset * beatTime);
+
+ console.log(
+ "clipindex " + cl.data.clipindex + ", " +
+ "channel " + cl.channel.index + ", " +
+ "beat " + reltime + ", " +
+ "len " + playLength + ", " +
+ "offset " + offset
+ );
+ }
+ }
+ }
+ console.log(data);
+ if (data.length == 0) return;
+ async function doPlay() {
+ await app.getCsound().tableCopyIn(playbackTable, data);
+ onReady(maxbeat * beatTime, data.length);
+ }
+
+ twine.timeline.compileAutomationData(function(){
+ if (data.length > playbackTableLength) {
+ app.insertScore("twine_removetable", [0, 1, playbackTable, async function(ndata){
+ createPlaybackTable(playbackTableLength * 2, doPlay);
+ }]);
+ } else {
+ doPlay();
+ }
+ });
+ }
+
+ var bounceNumber = 1;
+ this.renderToClip = function(beatStart, beatEnd) {
+ if (playing) return;
+ twirl.loading.show("Rendering", true);
+ setPlaybackArtefacts(beatStart, beatEnd, function(maxtime, maxtablen){
+ var cbid = app.createCallback(function(ndata2){
+ if (ndata2.status == 1) {
+ var channel = twine.timeline.addChannel();
+ var clip = new Clip(twine);
+ clip.data.position = beatStart;
+ clip.data.playLength = beatEnd - beatStart;
+ channel.addClip(clip);
+ clip.loadFromFtables("Bounce " + (bounceNumber ++), [ndata2.fnL, ndata2.fnR]);
+ } else if (ndata2.status == -2) {
+ twirl.errorHandler("Resulting output is too long");
+ } else {
+ twirl.errorHandler("Render cannot be completed");
+ }
+ twirl.loading.hide();
+ });
+ app.insertScore("twine_render", [0, 1, cbid, playbackTable, twine.timeline.channels.length, maxtime, 0, maxtablen]);
+ });
+ };
+
+ var saveNumber = 1;
+ this.renderToFile = function(beatStart, beatEnd, name) {
+ if (playing) return;
+ if (!name) {
+ name = twine.arrangementName + ".wav";
+ }
+ // HACK TODO: WASM can't overwrite files
+ name = name.substr(0, name.lastIndexOf(".")) + "." + (saveNumber ++) + name.substr(name.lastIndexOf("."));
+ // END HACK
+ var path = "/" + name;
+ twirl.loading.show("Rendering", true);
+ setPlaybackArtefacts(beatStart, beatEnd, function(maxtime, maxtablen){
+ var cbid = app.createCallback(async function(ndata2){
+ if (ndata2.status == 1) {
+ var content = await app.readFile(path);
+ var blob = new Blob([content], {type: "audio/wav"});
+ var url = window.URL.createObjectURL(blob);
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a[0].click();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ app.unlinkFile(path);
+ }, 20000);
+ twirl.loading.hide();
+ } else {
+ twirl.errorHandler("Could not save file");
+ }
+ });
+ app.insertScore("twine_render", [0, 1, cbid, playbackTable, twine.timeline.channels.length, maxtime, 1, maxtablen, path]);
+ });
+ };
+
+
+ this.play = function() {
+ if (playing) return;
+ setPlaybackArtefacts(twine.timeline.startLocation, null, function(maxtime, maxtablen){
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status <= 0) {
+ twine.setPlaying(false);
+ app.removeCallback(ndata.cbid);
+ if (ndata.status == -1) {
+ twirl.prompt.show("Not enough processing power to play in realtime");
+ } else {
+ if (onStop) {
+ setTimeout(function(){
+ onStop(ndata);
+ onStop = null;
+ }, 100); // race condition on ftable somehow
+ }
+ }
+ } else {
+ twine.setPlaying(true);
+ }
+ }, true);
+ app.insertScore("twine_playback", [0, maxtime, cbid, playbackTable, twine.timeline.channels.length, maxtablen]);
+ });
+
+ };
+ /*
+ this.play = function(beatStart, beatEnd) {
+ if (playing) return;
+ if (!beatStart) beatStart = 0;
+ var time;
+ var reltime;
+ var maxtime = 0;
+ var beatTime = 60 / twine.timeline.data.bpm;
+ for (let ch of twine.timeline.channels) {
+ for (let i in ch.clips) {
+ var cl = ch.clips[i];
+ time = cl.data.position;
+ if (time > beatStart && (!beatEnd || (time <= beatEnd))) {
+ reltime = time - beatStart;
+ if (reltime + cl.duration > maxtime) {
+ maxtime = reltime + cl.duration;
+ }
+ app.insertScore("ecp_playback", cl.getPlaybackArgs(-1, reltime * beatTime));
+ }
+ }
+ }
+ var cbid = app.createCallback(function() {
+ twine.setPlaying(false);
+ });
+ app.insertScore("twine_playbackwatchdog", [0, maxtime, cbid]);
+ };
+ */
+ this.stop = function(onStopFunc) {
+ if (!playing) return;
+ onStop = onStopFunc;
+ app.insertScore("twine_stopplayback");
+ };
+
+ this.stopAndPlay = function(beatStart, beatEnd) {
+ function doPlay() {
+ twine.play(beatStart, beatEnd);
+ }
+ if (playing) {
+ twine.stop(doPlay);
+ } else {
+ doPlay();
+ }
+ };
+
+ this.setVisible = function(state) {
+ var el = $("#twine");
+ if (state) {
+ el.show();
+ } else {
+ el.hide();
+ }
+ };
+
+ async function handleFileDrop(e, posTop, posLeft, colour) {
+ e.preventDefault();
+ twirl.loading.show();
+ var channel = twine.timeline.determineChannelFromTop(posTop);
+ if (!channel) {
+ channel = twine.timeline.addChannel();
+ }
+ var relPosition = 0;
+ for (const item of e.originalEvent.dataTransfer.files) {
+ if (item.name.endsWith(".twine")) {
+ window.ass = item;
+ twine.uploadImportData(item);
+ return;
+ }
+ if (!twirl.audioTypes.includes(item.type)) {
+ return twirl.errorHandler("Unsupported file type");
+ }
+ if (item.size > twirl.maxFileSize) {
+ return twirl.errorHandler("File too large");
+ }
+
+ errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ if (!twine.offline) await app.getCsound().fs.writeFile(item.name, buffer);
+
+ var clip = new Clip(twine);
+ posLeft = twine.timeline.roundToGrid(posLeft);
+ var position = (posLeft / twine.timeline.pixelsPerBeat) + twine.timeline.beatRegion[0];
+ clip.data.position = Math.max(0, position + relPosition);
+ channel.addClip(clip);
+ clip.loadFromPath(item.name, colour);
+ relPosition += 1;
+ }
+ if (twine.offline) twirl.loading.hide();
+ }
+
+ this.randomColour = function() {
+ return "rgb(" + ([Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255)].join(",")) + ")";
+
+ };
+
+ function fileDropHandler() {
+ var tempclip = null;
+
+ function calcPosition(e) {
+ var tlo = $("#twine_timelineoverlay").show();
+ var o = tlo.offset();
+ var top = e.pageY - o.top;
+ var left = e.pageX - o.left;
+ var visible = true;
+ if (top < 0 || left < 0 || top > tlo.height() || left > tlo.width()) {
+ visible = false;
+ }
+ return {
+ overlay: tlo,
+ left: left,
+ top: top,
+ visible: visible
+ }
+ }
+ window.addEventListener("resize", twine.timeline.redraw);
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ var pos = calcPosition(e);
+
+ if (!tempclip) {
+ tempclip = $("<div />").addClass("twine_clip").css({"background-color": twine.randomColour(), height: "25px", width: "100px"}).text("New Clip");
+ pos.overlay.append(tempclip);
+ }
+ if (!pos.visible) {
+ tempclip.hide();
+ } else {
+ tempclip.show().css("top", pos.top + "px").css("left", pos.left + "px");
+ }
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ if (e.currentTarget.contains(e.relatedTarget)) return;
+ $("#twine_timelineoverlay").hide();
+ if (tempclip) {
+ tempclip.remove();
+ tempclip = null;
+ }
+ }).on("drop", function(e) {
+ var pos = calcPosition(e);
+ $("#twine_timelineoverlay").hide();
+ var colour = tempclip.css("background-color");
+ if (tempclip) {
+ tempclip.remove();
+ tempclip = null;
+ }
+ if (pos.visible) {
+ handleFileDrop(e, pos.top, pos.left, colour);
+ }
+ });
+ }
+
+ function createPlaybackTable(length, onComplete) {
+ if (twine.offline) return;
+ if (!length) length = 5000;
+ app.insertScore("twine_createtable", [0, 1, app.createCallback(function(ndata){
+ playbackTable = ndata.table;
+ playbackTableLength = length;
+ if (onComplete) onComplete();
+ }), length]);
+ }
+
+ this.bootAudio = async function() {
+ for (var i = 0; i < 8; i++) {
+ twine.timeline.addChannel();
+ }
+ if (!twine.offline) {
+ twine.mixer.bootAudio();
+ twine.sr = (await app.getCsound().getSr());
+ }
+ createPlaybackTable();
+ };
+
+ this.boot = function() {
+ fileDropHandler();
+ };
+};
+
+function twine_start() {
+ var elStart = $("#twine_start");
+ function boot() {
+ elStart.hide();
+ twirl.boot();
+ twine.boot();
+ if (!twine.offline) {
+ twirl.loading.show("Preparing audio engine");
+ app.play(function(text){
+ twirl.loading.show(text);
+ twirl.latencyCorrection = twirl.audioContext.outputLatency * 1000;
+ }, twirl.audioContext);
+ }
+ }
+
+ window.twine = new Twine();
+ window.twigs = new Twigs();
+ window.twist = new Twist();
+ if (twine.offline) {
+ window.app = null;
+ boot();
+ twine.bootAudio();
+ } else {
+ window.app = new CSApplication({
+ csdUrl: "twine.csd",
+ onPlay: function() {
+ twine.bootAudio();
+ twigs.bootAudio();
+ twirl.loading.hide();
+ },
+ errorHandler: twirl.errorHandler
+ });
+ $("#twine_start").click(boot);
+ }
+}
\ No newline at end of file diff --git a/site/app/twine/twine_ui.js b/site/app/twine/twine_ui.js new file mode 100644 index 0000000..3a98c75 --- /dev/null +++ b/site/app/twine/twine_ui.js @@ -0,0 +1,506 @@ +var twineTopMenuData = [
+ {name: "File", contents: [
+ {name: "Save", disableOnPlay: true, shortcut: {name: "Ctrl S", ctrlKey: true, key: "s"}, click: function(twine) {
+ twine.downloadExportData();
+ }},
+ ]},
+ {name: "Edit", contents: [
+ {shortcut: {name: "Ctrl Z", ctrlKey: true, key: "z"}, click: function(twine) {
+ twine.undo.apply();
+ }, condition: function(twine) {
+ return twine.undo.has();
+ }, name: function(twine) {
+ return "Undo " + twine.undo.lastName();
+ }},
+ {name: "Copy", shortcut: {name: "Ctrl C", ctrlKey: true, key: "c"}, click: function(twine) {
+ twine.copySelected();
+ }, condition: function(twine) {
+ return twine.timeline.selectedClips.length > 0;
+ }}
+ ]},
+ {name: "View", contents: [
+ {name: "Zoom in", shortcut: {name: ",", key: ","}, click: function(twine){
+ twine.timeline.zoomIn();
+ }},
+ {name: "Zoom out", shortcut: {name: ".", key: "."}, click: function(twine){
+ twine.timeline.zoomOut();
+ }},
+ {name: "Show all", shortcut: {name: "/", key: "/"}, click: function(twine){
+ twine.timeline.showAll();
+ }},
+ {preset: "divider"},
+ {name: "Mixer", shortcut: {name: "M", key: "m"}, click: function(twine){
+ twine.showMixer();
+ }},
+ {name: "Contract channels", shortcut: {name: "C", key: "c"}, click: function(twine) {
+ twine.timeline.contractChannels();
+ }}
+ ]},
+ {name: "Action", contents: [
+ {name: "Play/stop", shortcut: {name: "Space", key: "space"}, click: function(twine) {
+ twine.ui.head.play.element.click();
+ }},
+ {preset: "divider"},
+ {name: "Add channel", shortcut: {name: "A", key: "a"}, click: function(twine) {
+ twine.timeline.addChannel();
+ }},
+ {name: "Add script clip", click: function(twine) {
+ twine.timeline.addScriptClip();
+ }},
+ {name: "Add blank clip", click: function(twine) {
+ twine.timeline.addBlankClip();
+ }},
+ {preset: "divider"},
+ {name: "Delete clip(s)", shortcut: {name: "Del", key: "delete"}, click: function(twine) {
+ twine.timeline.selectedClips.forEach(function(clip){
+ clip.destroy();
+ });
+ twine.ui.showPane(twine.ui.pane.NONE);
+ }, condition: function(twine){
+ return twine.timeline.selectedClips.length > 0;
+ }},
+ {preset: "divider"},
+ {name: "Render to file", click: function(twine) {
+ twine.renderToFile();
+ }},
+ {name: "Bounce", shortcut: {name: "A", key: "a"}, click: function(twine) {
+ twine.renderToClip();
+ }}
+ ]},
+ {name: "Options", contents: [
+ {name: "Settings", click: function(twine) {
+ twine.ui.showSettings();
+ }}
+ ]},
+ {name: "Help", contents: [
+ {name: "Help", click: function(twine){
+ $("#twist_documentation")[0].click();
+ }},
+ {name: "About", click: function(twine) {
+ twine.ui.showAbout();
+ }},
+ ]}
+];
+
+
+var TwineUI = function(twine) {
+ var ui = this;
+ ui.topMenu = new twirl.TopMenu(twine, twineTopMenuData, $("#twine_menubar"));
+
+ ui.showSettings = function() {
+ var settings = [
+ {
+ name: "Show master VU meter",
+ description: "Show the master VU mixer in the mixer view",
+ bool: true,
+ storageKey: "showMasterVu"
+ },
+ {
+ name: "Show clip waveforms",
+ description: "Show waveforms in clips",
+ bool: true,
+ storageKey: "showClipWaveforms"
+ }
+ ];
+ twirl.showSettings(twine, settings);
+ };
+
+ this.pane = {NONE: -1, MIXER: 0, CHANNEL: 1, CLIPAUDIO: 2, CLIPSCRIPT: 3};
+ this.showPane = function(pane) {
+ var chd = $("#twine_channeldetails");
+ var cld = $("#twine_clipdetails");
+ if (pane == ui.pane.MIXER) {
+ twine.mixer.show();
+ chd.hide();
+ cld.hide();
+
+ } else if (pane == ui.pane.CHANNEL) {
+ twine.mixer.hide();
+ chd.show();
+ cld.hide();
+
+ } else if (pane >= 2) {
+ twine.mixer.hide();
+ chd.hide();
+ cld.show();
+ var cda = $("#twine_clipdetailsaudio");
+ var cds = $("#twine_clipdetailsscript");
+ if (pane == ui.pane.CLIPAUDIO) {
+ cda.show();
+ cds.hide();
+ } else {
+ cda.hide();
+ cds.show();
+ }
+ } else if (pane == ui.pane.NONE) {
+ twine.mixer.hide();
+ chd.hide();
+ cld.hide();
+ };
+ };
+
+ ui.showAbout = function() {
+ var el = $("<div />");
+ var x = $("<div />").appendTo(el);
+ var string = "twine";
+ var intervals = [];
+
+ function addChar(c, left) {
+ left = Math.min(Math.max(left, 30), 70);
+ var elC = $("<h2 />").text(c).css({position: "absolute", left: left + "%"}).appendTo(x);
+ var rate = (Math.random() * 0.1) + 0.15;
+ var leftDirection = Boolean(Math.round(Math.random()));
+ setTimeout(function(){
+ intervals.push(setInterval(function(){
+ if (leftDirection) {
+ if (left < 70) {
+ left += rate;
+ } else {
+ leftDirection = false;
+ }
+ } else {
+ if (left > 30) {
+ left -= rate;
+ } else {
+ leftDirection = true;
+ }
+ }
+ //console.log(left, rate, leftDirection);
+ elC.css("left", left + "%");
+ }, (Math.random() * 20) + 20));
+ }, (Math.random() * 1000) + 500);
+ }
+ var widthPercent = (40 / (string.length));
+ for (let c in string) {
+ intervals.push(addChar(string[c], (widthPercent * c) + 30));
+ }
+
+ $("<br />").appendTo(el);
+ $("<br />").appendTo(el);
+ $("<p />").text("Version " + twine.version.toFixed(1)).appendTo(el);
+ $("<p />").css("font-size", "12px").text("By Richard Knight 2024").appendTo(el);
+
+ twirl.prompt.show(el, function(){
+ for (let i of intervals) clearInterval(i);
+ });
+ };
+
+ function refreshWarpParams() {
+ var warp = ui.clip.warp.element.val();
+ var warpMode = ui.clip.warpMode.element.val();
+
+ ui.clip.warpMode.hide();
+ ui.clip.fftSize.hide();
+ ui.clip.phaseLock.hide();
+ ui.clip.txtWinSize.hide();
+ ui.clip.txtRandom.hide();
+ ui.clip.txtOverlap.hide();
+ ui.clip.txtWinType.hide();
+
+ if (!warp) return;
+ ui.clip.warpMode.show();
+
+ if (warpMode == 1) {
+ ui.clip.txtWinSize.show();
+ ui.clip.txtRandom.show();
+ ui.clip.txtOverlap.show();
+ ui.clip.txtWinType.show();
+ } else if (warpMode > 1) {
+ ui.clip.fftSize.show();
+ ui.clip.phaseLock.show();
+ }
+ }
+
+ function applyValToSelectedFunc(dataKey, applyFunc, undoName, noApplyUndo) {
+ if (!undoName) undoName = dataKey;
+ var func = function(val) {
+ if (!noApplyUndo) {
+ var selected = [...twine.timeline.selectedClips];
+ var values = [];
+ }
+ twine.timeline.selectedClips.forEach(async function(clip){
+ if (!noApplyUndo) {
+ values.push(clip.data[dataKey]);
+ }
+ applyFunc(clip, val);
+ });
+ if (!noApplyUndo) {
+ twine.undo.add("clip " + undoName, function(){
+ for (var i in selected) {
+ applyFunc(selected[i], values[i]);
+ if (twine.timeline.selectedClip == selected[i]) {
+ ui.clip[dataKey].setValue(values[i]);
+ }
+ }
+ });
+ }
+ };
+ return func;
+ }
+
+ ui.clip = {
+ scriptEdit: new twirl.stdui.TextArea({
+ target: "twine_clip_scriptedit",
+ height: "100%",
+ width: "100%"
+
+ }),
+ scriptAudition: new twirl.stdui.PlayButton({
+ target: "twine_clip_scriptaudition",
+ change: function(v, obj) {
+ if (obj.state == true) {
+
+ } else {
+ app.insertScore("twine_scriptstop");
+ }
+ }
+ }),
+ scriptApply: new twirl.stdui.StandardButton({
+ target: "twine_clip_scriptapply",
+ label: "Apply script",
+ change: function() {
+ twine.timeline.selectedClip.setScript(
+ ui.clip.scriptEdit.element.val(),
+ function() {
+ twirl.prompt.show("Script successfully compiled");
+ }
+ );
+ }
+ }),
+ audition: new twirl.stdui.PlayButton({
+ target: "twine_clip_audition",
+ tooltip: "Audition clip",
+ change: function(v, obj) {
+ if (obj.state == true) {
+ twine.timeline.selectedClip.play(function(ndata) {
+ if (ndata.status == 0) {
+ obj.setValue(false);
+ }
+ });
+ } else {
+ twine.timeline.selectedClip.stop();
+ }
+ }
+ }),
+ name: new twirl.stdui.TextInput({
+ target: "twine_clip_name",
+ change: applyValToSelectedFunc("name", function(clip, val){
+ clip.setData("name", val);
+ }),
+ css: {
+ border: "none"
+ }
+ }),
+ colour: new twirl.stdui.ColourInput({
+ target: "twine_clip_colour",
+ change: applyValToSelectedFunc("colour", function(clip, val){
+ clip.colour = val;
+ }),
+ css: {
+ border: "none"
+ }
+ }),
+ editTwist: new twirl.stdui.StandardButton({
+ label: "Twist",
+ target: "twine_clip_edittwist",
+ change: function(e) {
+ twirl.contextMenu.show(e, [
+ {name: "Edit all references", click: function(){
+ twine.timeline.selectedClip.editInTwist();
+ }},
+ {name: "Edit as unique", click: function(){
+ twine.timeline.selectedClip.editInTwist(true);
+ }}
+ ]);
+ }
+ }),
+ editTwigs: new twirl.stdui.StandardButton({
+ label: "Twigs",
+ target: "twine_clip_edittwigs",
+ change: function(e) {
+ twirl.contextMenu.show(e, [
+ {name: "Edit all references", click: function(){
+ twine.timeline.selectedClip.editInTwigs();
+ }},
+ {name: "Edit as unique", click: function(){
+ twine.timeline.selectedClip.editInTwigs(true);
+ }}
+ ]);
+ }
+ }),
+ warp: new twirl.stdui.StandardToggle({
+ label: "Warp",
+ target: "twine_clip_warp",
+ change: applyValToSelectedFunc("warp", function(clip, val){
+ clip.setWarp(val);
+ }),
+ stateAlter: function(val) {
+ refreshWarpParams();
+ }
+ }),/*
+ loop: new twirl.stdui.StandardToggle({
+ label: "Loop",
+ target: "twine_clip_loop",
+ change: function(val) {
+ twine.timeline.selectedClip.setLoop(val);
+ }
+ }),*/
+ warpMode: new twirl.stdui.ComboBox({
+ target: "twine_clip_warpmode",
+ options: [
+ "Repitch", "Grain", "Mince" //, "FFTab"
+ ],
+ change: applyValToSelectedFunc("warpMode", function(clip, val){
+ clip.setWarpMode(val);
+ }, "warp mode"),
+ stateAlter: function(val) {
+ refreshWarpParams();
+ }
+ }),
+ amp: new twirl.stdui.Slider({
+ label: "Gain",
+ valueLabel: true,
+ value: 1,
+ min: 0,
+ max: 2,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ input: applyValToSelectedFunc("amp", function(clip, val){
+ clip.setData("amp", val);
+ }, "gain", true),
+ change: applyValToSelectedFunc("amp", function(clip, val){
+ clip.setData("amp", val);
+ }, "gain")
+ }),
+ pitch: new twirl.stdui.Slider({
+ label: "Pitch",
+ valueLabel: true,
+ min: -12,
+ max: 12,
+ step: 1,
+ value: 0,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ input: applyValToSelectedFunc("pitch", function(clip, val){
+ clip.setPitch(val);
+ }, null, true),
+ change: applyValToSelectedFunc("pitch", function(clip, val){
+ clip.setPitch(val);
+ })
+ }),
+ fftSize: new twirl.stdui.ComboBox({
+ label: "FFT Size",
+ asRow: true,
+ target: "twine_clipparamsbottom",
+ options: [
+ "256", "512", "1024", "2048"
+ ],
+ asValue: true,
+ change: applyValToSelectedFunc("fftSize", function(clip, val){
+ clip.setData("fftSize", val);
+ }, "FFT size")
+ }),
+ phaseLock: new twirl.stdui.StandardToggle({
+ label: "Phase lock",
+ target: "twine_clipparamsbottom",
+ change: applyValToSelectedFunc("phaseLock", function(clip, val){
+ clip.setData("phaseLock", val);
+ }, "phase lock"),
+ stateAlter: function(val) {
+ refreshWarpParams();
+ }
+ }),
+ txtWinSize: new twirl.stdui.Slider({
+ label: "Window size",
+ valueLabel: true,
+ min: 44,
+ max: 4410,
+ step: 1,
+ value: 4410,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: applyValToSelectedFunc("txtWinSize", function(clip, val){
+ clip.setData("txtWinSize", val);
+ }, "window size")
+ }),
+ txtRandom: new twirl.stdui.Slider({
+ label: "Window random",
+ valueLabel: true,
+ min: 0,
+ max: 441,
+ step: 1,
+ value: 441,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: applyValToSelectedFunc("txtRandom", function(clip, val){
+ clip.setData("txtRandom", val);
+ }, "window random")
+ }),
+ txtOverlap: new twirl.stdui.Slider({
+ label: "Window overlap",
+ valueLabel: true,
+ min: 0,
+ max: 16,
+ step: 1,
+ value: 4,
+ size: 32,
+ target: "twine_clipparamsbottom",
+ change: applyValToSelectedFunc("txtOverlap", function(clip, val){
+ clip.setData("txtOverlap", val);
+ }, "window overlap")
+ }),
+ txtWinType: new twirl.stdui.ComboBox({
+ label: "Window type",
+ asRow: true,
+ target: "twine_clipparamsbottom",
+ options: [
+ "Hanning", "Hamming", "Half sine"
+ ],
+ change: applyValToSelectedFunc("txtWinType", function(clip, val){
+ clip.setData("txtWinType", val);
+ }, "window type")
+ })
+ };
+
+ ui.head = {
+ play: new twirl.stdui.PlayButton({
+ target: "twine_head_play",
+ fontsize: "14pt",
+ change: function(v, obj) {
+ if (obj.state == true) {
+ twine.play();
+ } else {
+ twine.stop();
+ obj.setValue(false);
+ }
+ }
+ }),
+ snap: new twirl.stdui.StandardToggle({
+ label: "Snap",
+ target: "twine_head_snap",
+ change: function(val) {
+ val = (val) ? 4 : 0;
+ twine.timeline.data.snapToGrid = val;
+ }
+ }),
+ grid: new twirl.stdui.StandardToggle({
+ label: "Grid",
+ target: "twine_head_showgrid",
+ change: function(val) {
+ twine.timeline.data.gridVisible = val;
+ twine.timeline.redraw();
+ }
+ }),
+ name: new twirl.stdui.TextInput({
+ target: "twine_head_name",
+ css: {
+ border: "none",
+ "font-family": "var(--fontFace)",
+ "font-size": "var(--fontSizeLarge)",
+ },
+ change: function(val) {
+ twine.timeline.arrangementName = val;
+ }
+ })
+ };
+};
\ No newline at end of file diff --git a/site/app/twirl/appdata.js b/site/app/twirl/appdata.js new file mode 100644 index 0000000..b417c3f --- /dev/null +++ b/site/app/twirl/appdata.js @@ -0,0 +1,1427 @@ +twirl.appdata = {
+ version: 1.0,
+ modulations: [
+ {
+ name: "LFO",
+ instr: "twst_mod_lfo",
+ parameters: [
+ {name: "Rate", description: "Rate in Hz", dfault: 1, min: 0.1, max: 20},
+ {name: "Base value", description: "Base value", hostrange: true},
+ {name: "Gain", description: "Gain", dfault: 0.2},
+ {preset: "wave"},
+ {name: "Min", preset: "hostrangemin", hidden: true},
+ {name: "Max", preset: "hostrangemax", hidden: true}
+ ]
+ },
+ {
+ name: "Line",
+ instr: "twst_mod_line",
+ parameters: [
+ {name: "First point", channel: "first", description: "First point value", hostrange: true, automatable: false},
+ {name: "Last point", channel: "last", description: "Last point value", hostrange: true, automatable: false},
+ ]
+ },
+ {
+ name: "Random",
+ instr: "twst_mod_random",
+ parameters: [
+ {name: "Rate", description: "Rate in Hz", min: 0.1, max: 20, dfault: 1},
+ {name: "Min", hostrange: true, dfault: "hostrangemin"},
+ {name: "Max", hostrange: true, dfault: "hostrangemax"},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0.1, min: 0, max: 0.5},
+
+ ]
+ },
+ {
+ name: "Jitter",
+ instr: "twst_mod_jitter",
+ parameters: [
+ {name: "Base value", description: "Base value", hostrange: true},
+ {name: "Amplitude", channel: "amp", dfault: 1},
+ {name: "Rate minimum", description: "Rate in Hz", channel: "freqmin", dfault: 1, min: 0.1, max: 20},
+ {name: "Rate maximum", description: "Rate in Hz", channel: "freqmax", dfault: 1, min: 0.1, max: 20},
+ {name: "Min", hostrange: true, dfault: "hostrangemin"},
+ {name: "Max", hostrange: true, dfault: "hostrangemax"}
+
+ ]
+ },
+ {
+ name: "Parametric jitter",
+ instr: "twst_mod_jitter2",
+ parameters: [
+ {name: "Base value", description: "Base value", hostrange: true},
+ {name: "Total amplitude", channel: "totalamp", dfault: 1},
+ {name: "Amp 1", channel: "amp1", dfault: 0.5},
+ {name: "Rate 1", description: "Rate in Hz", channel: "freq1", dfault: 1, min: 0.1, max: 20},
+ {name: "Amp 2", channel: "amp2", dfault: 0.5},
+ {name: "Rate 2", description: "Rate in Hz", channel: "freq2", dfault: 1, min: 0.1, max: 20},
+ {name: "Amp 3", channel: "amp3", dfault: 0.5},
+ {name: "Rate 3", description: "Rate in Hz", channel: "freq3", dfault: 1, min: 0.1, max: 20},
+ {name: "Min", preset: "hostrangemin", hidden: true},
+ {name: "Max", preset: "hostrangemax", hidden: true}
+ ]
+ },
+ {
+ name: "Crossadaptive RMS",
+ instr: "twst_xa_rms",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", channel: "xrmsinstance"},
+ {preset: "instanceloop", channel: "xrmslooptype"},
+ {name: "Scaling", channel: "xrmsscale", description: "Scaling", hostrange: true},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0, min: 0, max: 0.2}
+ ]
+ },
+ {
+ name: "Crossadaptive AMDF pitch",
+ instr: "twst_xa_pitchamdf",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", channel: "xpitchinstance"},
+ {preset: "instanceloop", channel: "xpitchlooptype"},
+ {name: "Scaling", channel: "xpitchscale", description: "Scaling", hostrange: true},
+ {name: "Minimum frequency", channel: "xpitchmin", description: "Minimum frequency in analysis", min: 20, max: 1000, step: 1, dfault: 20, automatable: false},
+ {name: "Maximum frequency", channel: "xpitchmax", description: "Maximum frequency in analysis", min: 1000, max: 10000, step: 1, dfault: 10000, automatable: false},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0, min: 0, max: 0.2},
+ ]
+ },
+ {
+ name: "Crossadaptive pitch 1",
+ instr: "twst_xa_pitch1",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", channel: "xpitchinstance"},
+ {preset: "instanceloop", channel: "xpitchlooptype"},
+ {name: "Scaling", channel: "xpitchscale", description: "Scaling", hostrange: true},
+ {name: "Hop size root", channel: "xpitchhopsize", description: "Square root of hop size", min: 6, max: 12, dfault: 8, step: 1, automatable: false},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0, min: 0, max: 0.2},
+ ]
+ },
+ {
+ name: "Crossadaptive pitch 2",
+ instr: "twst_xa_pitch2",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", channel: "xpitchinstance"},
+ {preset: "instanceloop", channel: "xpitchlooptype"},
+ {name: "Scaling", channel: "xpitchscale", description: "Scaling", hostrange: true},
+ {name: "Minimum frequency", channel: "xpitchmin", description: "Minimum frequency in analysis", min: 20, max: 1000, step: 1, dfault: 20, automatable: false},
+ {name: "Maximum frequency", channel: "xpitchmax", description: "Maximum frequency in analysis", min: 1000, max: 10000, step: 1, dfault: 10000, automatable: false},
+ {name: "Analysis period", channel: "xpitchperiod", description: "Analysis period in seconds", min: 0.001, max: 0.1, dfault: 0.05, automatable: false},
+ {name: "Amplitude threshold", channel: "xpitchampthresh", description: "Analysis amplitude threshold in decibels", min: 1, max: 30, dfault: 10, automatable: false},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0, min: 0, max: 0.2},
+ ]
+ },
+ {
+ name: "Crossadaptive spectral centroid",
+ instr: "twst_xa_centroid",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", channel: "xcentroidinstance"},
+ {preset: "instanceloop", channel: "xcentroidlooptype"},
+ {name: "Scaling", channel: "xcentroidscale", description: "Scaling", hostrange: true},
+ {name: "Analysis period", channel: "xcentroidperiod", description: "Analysis period in seconds", min: 0.001, max: 0.3, dfault: 0.05},
+ {preset: "fftsize", channel: "xcentroidfftsize"},
+ {name: "Portamento time", channel: "porttime", description: "Value glide time in seconds", dfault: 0, min: 0, max: 0.2}
+ ]
+ },
+ ],
+ transforms: [
+ {
+ name: "General",
+ contents: [
+ {
+ name: "Reverse",
+ description: "Reverse sample region",
+ instr: "twst_tfi_reverse",
+ parameters: []
+ }
+ ]
+ },
+ {
+ name: "Generate",
+ contents: [
+ {
+ name: "Silence",
+ instr: "twst_tf_gensilence",
+ description: "Replace region with silence",
+ parameters: []
+ },
+ {
+ name: "Oscillator",
+ instr: "twst_tf_gentone",
+ description: "Simple interpolating oscillator",
+ parameters: [
+ {presetgroup: "notefreq"},
+ {preset: "amp"},
+ {preset: "wave", automatable: true},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "FM",
+ instr: "twst_tf_genfm",
+ description: "Frequency modulation synthesis",
+ parameters: [
+ {presetgroup: "notefreq"},
+ {preset: "amp"},
+ {name: "Carrier factor", channel: "carrier", min: 0.1, max: 8, dfault: 1},
+ {name: "Modulator factor", channel: "modulator", min: 0.1, max: 8, dfault: 1},
+ {name: "Modulation index", channel: "index", min: 0.1, max: 10, dfault: 2},
+ {preset: "wave"},
+ {name: "Stereo variance", channel: "stereovar", min: 0.5, max: 1.5, dfault: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "FM model",
+ instr: "twst_tf_genfmmodel",
+ description: "Frequency modulation physical models",
+ parameters: [
+ {name: "Type", channel: "fmtype", options: ["Organ", "Bell", "Flute", "Rhodes", "Wurlitzer", "Random"]},
+ {presetgroup: "notefreq"},
+ {preset: "amp"},
+ {name: "Modulation index", channel: "control1", min: 0.1, max: 10, dfault: 2},
+ {name: "Oscillator crossfade", channel: "control2", min: 0.1, max: 10, dfault: 2},
+ {name: "Vibrato depth", channel: "vibdepth", min: 0, max: 1, dfault: 0.05},
+ {name: "Vibrato rate", channel: "vibrate", min: 0, max: 20, dfault: 2},
+ {preset: "wave", channel: "wave1", name: "Wave 1"},
+ {preset: "wave", channel: "wave2", name: "Wave 2"},
+ {preset: "wave", channel: "wave3", name: "Wave 3"},
+ {preset: "wave", channel: "wave4", name: "Wave 4"},
+ {preset: "wave", channel: "vibwave", name: "Vibrato wave"},
+ {name: "Stereo variance", channel: "stereovar", min: 0.5, max: 1.5, dfault: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "String pluck",
+ instr: "twst_tf_genrepluck",
+ description: "String pluck physical model",
+ parameters: [
+ {presetgroup: "notefreq"},
+ {preset: "amp"},
+ {name: "Pluck point", channel: "pluckpoint", description: "String pluck point ratio", dfault: 0.3, automatable: false},
+ {name: "Pickup point", channel: "pickpoint", description: "Pickup point ratio", dfault: 0.6, automatable: false},
+ {name: "Reflection", channel: "reflection", description: "Reflection coefficient", min: 0.0001, max: 0.9999, dfault: 0.4},
+ {name: "Exciter mode", channel: "excitemode", options: ["Noise", "Oscillator"], dfault: 1},
+ {preset: "wave", channel: "excitewave", name: "Exciter waveform", conditions:[{channel: "excitemode", operator: "eq", value: 1}]},
+ {presetgroup: "notefreq", channelprepend: "excite", nameprepend: "Exciter", conditions: [{channel: "excitemode", operator: "eq", value: 1}]},
+ {name: "Exciter amplitude", channel: "exciteamp", description: "Exciter amplitude", dfault: 1, min: 0, max: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Stochastic additive",
+ instr: "twst_tf_genadditive",
+ description: "Aleatoric additive synthesis",
+ parameters: [
+ {preset: "amp", automatable: false},
+ {presetgroup: "notefreq", nameprepend: "Minimum", dfault: 440, channelprepend: "min", automatable: false, lagHint: 1},
+ {presetgroup: "notefreq", nameprepend: "Maximum", dfault: 8000, channelprepend: "max", automatable: false, lagHint: -1},
+ {name: "Frequency increment", channel: "step", automatable: false, min: 1.001, max: 1.5, dfault: 1.1, lagHint: -1},
+ {name: "Frequency randomness", channel: "steprand", automatable: false, min: 1, max: 1.5, dfault: 1},
+ {name: "Amplitude increment", channel: "ampmult", automatable: false, min: 0.2, max: 1, dfault: 0.6},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Noise",
+ instr: "twst_tf_gennoise",
+ description: "Noise generation",
+ parameters: [
+ {preset: "amp"},
+ {name: "Type", options: ["White", "Pink"], description: "Type of noise"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Bamboo",
+ instr: "twst_tf_genbamboo",
+ description: "Bamboo shaker physical model",
+ parameters: [
+ {preset: "amp"},
+ {name: "Number of resonators", channel: "number", min: 0, max: 10, step: 1, dfault: 0, automatable: false},
+ {presetgroup: "notefreq", nameprepend: "Resonator 1", dfault: 440, channelprepend: "r1", automatable: false},
+ {presetgroup: "notefreq", nameprepend: "Resonator 2", dfault: 440, channelprepend: "r2", automatable: false},
+ {presetgroup: "notefreq", nameprepend: "Resonator 3", dfault: 440, channelprepend: "r3", automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "WG bow",
+ instr: "twst_tf_genwgbow",
+ description: "Physical modelling waveguide bowed string",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "notefreq"},
+ {name: "Bow pressure", channel: "pressure", min: 0, max: 5, dfault: 3},
+ {name: "Bow position", channel: "position", min: 0.025, max: 0.23, dfault: 0.127236},
+ {name: "Vibrato rate", channel: "vibfreq", min: 0, max: 12, dfault: 0},
+ {name: "Vibrato rate", channel: "vibamp", min: 0, max: 1, dfault: 0},
+ {name: "Vibrato waveform", preset: "wave"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Feedback",
+ instr: "twst_tf_genfeedback",
+ description: "Feedback modelling",
+ added: "2025-04-17",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "notefreq"},
+ {name: "Feedback", min: 0.1, max: 10, dfault: 1.1},
+ {name: "Filter bandwidth", channel: "bandwidth", min: 10, max: 500, dfault: 125},
+ {name: "Post gain", channel: "postgain", min: 0.1, max: 2, dfault: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Additive",
+ instr: "twst_tf_gensimpleadditive",
+ description: "Simple additive synthesis",
+ added: "2025-04-17",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "notefreq"},
+ {name: "Frequency step multiplier", channel: "multiplier", min: 1.0001, max: 2, dfault: 1.1},
+ {name: "Frequency multiplier", channel: "stepmultiplier", min: 0.5, max: 2, dfault: 1},
+ {name: "Amplitude smoothing", channel: "ampprofile", min: 0, max: 1, step: 1, dfault: 1},
+ {name: "Harmonics", min: 2, max: 256, dfault: 64, automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ }
+ /* not quite right, don't create sound as expected
+ {
+ name: "WG bowed bar",
+ instr: "twst_tf_genwgbowedbar",
+ description: "Physical modelling waveguide bowed bar",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "notefreq"},
+ {name: "Bow pressure", channel: "pressure", min: 0, max: 5, dfault: 3},
+ {name: "Bow position", channel: "position", min: 0.025, max: 0.23, dfault: 0.127236},
+ {name: "Filter gain", channel: "filtergain", min: 0, max: 1, dfault: 0.809},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "WG brass",
+ instr: "twst_tf_genwgbrass",
+ description: "Physical modelling waveguide brass",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "notefreq"},
+ {name: "Lip tension", channel: "tension", min: 0, max: 1, dfault: 0.4},
+ {name: "Attack", channel: "position", min: 0, max: 1, dfault: 0.1, automatable: false},
+ {name: "Vibrato rate", channel: "vibfreq", min: 0, max: 12, dfault: 0},
+ {name: "Vibrato rate", channel: "vibamp", min: 0, max: 1, dfault: 0},
+ {name: "Vibrato waveform", preset: "wave"},
+ {presetgroup: "applymode"}
+ ]
+ },*/
+ ]
+ },
+ {
+ name: "Amplitude",
+ contents: [
+ {
+ name: "Normalise",
+ instr: "twst_tf_normalise",
+ description: "Normalise region",
+ parameters: [
+ {name: "Scale", description: "Scaling of normalisation", dfault: 1, min: 0, max: 1, automatable: false},
+ {name: "Stereo equal", channel: "equal", description: "Normalise stereo channels equally", dfault: 1, min: 0, max: 1, step: 1, automatable: false},
+ ]
+ },
+ {
+ name: "Amplitude",
+ instr: "twst_tf_amplitude",
+ description: "Gain alteration",
+ twine: true,
+ parameters: [
+ {name: "Gain", description: "Gain amount", dfault: 1, min: 0, max: 2},
+ {name: "Balance", description: "Left and right balance", dfault: 0.5, min: 0, max: 1}
+ ]
+ },
+ {
+ name: "Bit crush",
+ instr: "twst_tf_bitcrush",
+ description: "Sample level bit reduction",
+ twine: true,
+ parameters: [
+ {name: "Crush depth", channel: "crush", description: "Bit depth", dfault: 16, min: 1, max: 64, step: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Suppressor",
+ instr: "twst_tf_suppress",
+ description: "Wrap, mirror or limit amplitude",
+ twine: true,
+ parameters: [
+ {name: "Mode", channel: "mode", options: ["Limit", "Wrap", "Mirror"], automatable: true, dfault: 0},
+ {name: "Threshold", dfault: 0.8},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Linear clip",
+ instr: "twst_tf_pdclip",
+ description: "Phase distortion linear clipping",
+ twine: true,
+ parameters: [
+ {name: "Width", min: 0, max: 1, dfault: 0.2},
+ {name: "Centre", description: "Clipping offset", min: -1, max: 1, dfault: 0},
+ {name: "Bipolar", min: 0, max: 1, step: 1, dfault: 0, automatable: false},
+ {name: "Fullscale", min: 0, max: 1, dfault: 1, automatable: false},
+ ]
+ },
+ {
+ name: "Distortion",
+ instr: "twst_tf_distort",
+ description: "Waveshaping distortion",
+ twine: true,
+ parameters: [
+ {name: "Amount", min: 0, max: 1, dfault: 0.2},
+ {preset: "wave"},
+ {name: "Half power point", channel: "halfpower", min: 0, max: 100, dfault: 10, automatable: false},
+ ]
+ },
+ {
+ name: "HT Distortion",
+ instr: "twst_tf_distort1",
+ description: "Hyperbolic tangent distortion",
+ twine: true,
+ parameters: [
+ {name: "Pre gain", channel: "pregain", min: 0, max: 5, dfault: 1},
+ {name: "Post gain", channel: "postgain", min: 0, max: 1, dfault: 1},
+ {name: "Positive shape", channel: "shape1", min: 0, max: 1, dfault: 0.2},
+ {name: "Negative shape", channel: "shape2", min: 0, max: 1, dfault: 0.2},
+ ]
+ },
+ {
+ name: "Strobe",
+ instr: "twst_tf_strobe",
+ description: "Automatic amplitude attenuation",
+ twine: true,
+ added: "2025-04-17",
+ parameters: [
+ {name: "Rate", description: "Rate of action in Hz", dfault: 4, min: 0.1, max: 30},
+ {name: "Hold time", channel: "holdtime", description: "Hold time in seconds", dfault: 0.1, min: 0.01, max: 0.5},
+ {name: "Windowed", description: "Whether to apply windowing", dfault: 0, min: 0, max: 1, step: 1}
+ ]
+ },
+ ]
+ },
+ {
+ name: "Filter",
+ contents: [
+ {
+ name: "Low pass",
+ instr: "twst_tf_lpf",
+ description: "Butterworth low pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", description: "Filter frequency", max: 22000, min: 20, dfault: 1000},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "High pass",
+ instr: "twst_tf_hpf",
+ description: "Butterworth high pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", description: "Filter frequency", max: 22000, min: 20, dfault: 1000},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Band pass",
+ instr: "twst_tf_bpf",
+ description: "Butterworth band pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", description: "Filter frequency", max: 22000, min: 20, dfault: 1000},
+ {name: "Bandwidth", description: "Filter bandwidth", max: 5000, min: 1, dfault: 200},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Parametric",
+ instr: "twst_tf_pareq",
+ description: "Parametric EQ",
+ twine: true,
+ parameters: [
+ {name: "Frequency", description: "Filter frequency", max: 22000, min: 20, dfault: 1000},
+ {name: "Gain", description: "Filter gain factor", max: 4, min: 0, dfault: 1},
+ {name: "Q", description: "Filter Q", max: 0.9, min: 0.5, dfault: 0.707},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "DC Block",
+ instr: "twst_tf_dcblock",
+ description: "Remove DC offset from signal",
+ twine: true,
+ parameters: [
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Moog high pass",
+ instr: "twst_tf_mooghpf",
+ description: "Emulated Moog high pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 10, max: 10000, dfault: 800},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Moog low pass",
+ instr: "twst_tf_mooglpf",
+ description: "Emulated Moog low pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 10, max: 10000, dfault: 800},
+ {name: "Resonance", min: 0, max: 1, dfault: 0.6},
+ {name: "Mode", min: 0, max: 2, dfault: 1, step: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "TB303 low pass",
+ instr: "twst_tf_tbvcf",
+ description: "Emulated TB303 low pass filter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 1000, max: 15000, dfault: 1500},
+ {name: "Resonance", min: 0, max: 2, dfault: 0.6},
+ {name: "Distortion", min: 0.5, max: 3, dfault: 2},
+ {name: "Resonance asymmetry ", min: 0, max: 1, dfault: 0.5},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Waveguide",
+ instr: "twst_tf_waveguide1",
+ description: "Waveguide filter",
+ twine: true,
+ parameters: [
+ {name: "Rate", channel: "freq", min: 10, max: 4000, dfault: 100},
+ {name: "Filter cutoff", channel: "cutoff", min: 400, max: 20000, dfault: 4000},
+ {name: "Feedback", dfault: 0.5},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Frequency", contents: [
+ {
+ name: "Frequency shift 1",
+ instr: "twst_tf_freqshift1",
+ description: "Hilbert frequency shifter",
+ twine: true,
+ parameters: [
+ {name: "Shift", description: "Shift frequency in Hz", dfault: 0, min: -1000, max: 1000},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Frequency shift 2",
+ instr: "twst_tf_freqshift2",
+ description: "Biquadratic frequency shifter",
+ twine: true,
+ parameters: [
+ {name: "Shift", description: "Shift frequency in Hz", dfault: 0, min: -1000, max: 1000},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Ring modulator",
+ instr: "twst_tf_ringmod",
+ description: "Ring modulator",
+ twine: true,
+ parameters: [
+ {name: "Frequency", description: "Modulation frequency in Hz", dfault: 440, min: 20, max: 18000},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Exciter",
+ instr: "twst_tf_exciter",
+ description: "Non-linear signal excitation",
+ twine: true,
+ parameters: [
+ {presetgroup: "notefreq", nameprepend: "Lower", channelprepend: "low"},
+ {presetgroup: "notefreq", nameprepend: "Upper", channelprepend: "high"},
+ {name: "Harmonics", description: "Number of harmonics", min: 0.1, max: 10, dfault: 6, lagHint: -1},
+ {name: "Blend", description: "Harmonic blending", min: -10, max: 10, dfault: 10},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Delay", contents: [
+ {
+ name: "Dynamic delay",
+ instr: "twst_tf_vdelay",
+ description: "Variable delay",
+ twine: true,
+ parameters: [
+ {name: "Delay time", channel: "delay", description: "Delay time in seconds", dfault: 0.3, min: 0.001, max: 1, lagHint: -1},
+ {name: "Feedback", description: "Feedback gain", dfault: 0.5},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Flanger",
+ instr: "twst_tf_flanger",
+ twine: true,
+ parameters: [
+ {name: "Delay", max: 0.02, dfault: 0.01, lagHint: -1},
+ {name: "Feedback", dfault: 0.3},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "First order phaser",
+ instr: "twst_tf_phaser1",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 10, max: 10000, dfault: 3000},
+ {name: "Order", min: 1, max: 24, step: 1, dfault: 4, automatable: false, lagHint: -1},
+ {name: "Feedback", dfault: 0.3},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Second order phaser",
+ instr: "twst_tf_phaser2",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 10, max: 10000, dfault: 3000},
+ {name: "Q", min: 0.2, max: 1.5, dfault: 0.67},
+ {name: "Order", min: 1, max: 2499, step: 1, dfault: 800, automatable: false, lagHint: -1},
+ {name: "Mode", min: 1, max: 2, dfault: 1, step: 1, automatable: false},
+ {name: "Separation", channel: "sep", min: 0.01, max: 4, dfault: 1, lagHint: 1},
+ {name: "Feedback", min: -1, max: 1, dfault: 0.3},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Reverb", contents: [
+ {
+ name: "Room",
+ instr: "twst_tf_reverb3",
+ twine: true,
+ parameters: [
+ {name: "Room size", channel: "roomsize", description: "Room size", dfault: 0.5, min: 0, max: 1, lagHint: -1},
+ {name: "Damping", channel: "hfdamp", description: "High frequency damping", dfault: 0.5, min: 0, max: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Midverb",
+ instr: "twst_tf_reverb2",
+ twine: true,
+ parameters: [
+ {name: "Length", channel: "time", description: "Decay time", dfault: 1, min: 0.1, max: 10, lagHint: -1},
+ {name: "Damping", channel: "hfdamp", description: "High frequency damping", dfault: 0.5, min: 0, max: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Basicverb",
+ instr: "twst_tf_reverb1",
+ twine: true,
+ parameters: [
+ {name: "Length", channel: "time", description: "Decay time", dfault: 1, min: 0.1, max: 10, lagHint: -1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "FDNverb",
+ instr: "twst_tf_reverb4",
+ twine: true,
+ parameters: [
+ {name: "Feedback", channel: "feedback", description: "Feedback amount equating to decay time", dfault: 0.5, min: 0.1, max: 1, lagHint: -1},
+ {name: "Damping", channel: "hfdamp", description: "High frequency damping", dfault: 0.5, min: 0, max: 1},
+ {name: "Pitch variation", channel: "pitchmod", description: "Pitch variation", dfault: 1, min: 0, max: 10, automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Baboverb",
+ instr: "twst_tf_reverb5",
+ description: "Physical model reverberator",
+ twine: true,
+ parameters: [
+ {name: "Room width", channel: "width", description: "Room width in metres", dfault: 14.39, min: 2, max: 100, automatable: false, lagHint: -1},
+ {name: "Room depth", channel: "depth", description: "Room depth in metres", dfault: 11.86, min: 2, max: 100, automatable: false, lagHint: -1},
+ {name: "Room height", channel: "height", description: "Room height in metres", dfault: 10, min: 2, max: 100, automatable: false, lagHint: -1},
+ {name: "X position", channel: "posx", description: "X position of listener", dfault: 0.5, min: 0, max: 1},
+ {name: "Y position", channel: "posy", description: "Y position of listener", dfault: 0.5, min: 0, max: 1},
+ {name: "Z position", channel: "posz", description: "Z position of listener", dfault: 0.5, min: 0, max: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ ]
+ },
+ {
+ name: "Granular", contents: [
+ {
+ name: "Autoglitch",
+ instr: "twst_tf_autoglitch",
+ description: "Automatic aleatoric sample reading with modifications",
+ twine: true,
+ parameters: [
+ {name: "Minimum ratio", channel: "minratio", description: "Minimum time ratio of original", dfault: 0.5, min: 0, max: 1, lagHint: 1},
+ {name: "Change rate", channel: "changerate", description: "Rate of change in Hz", dfault: 0.5, min: 0.1, max: 10, lagHint: -1},
+ {name: "Change chance", channel: "changechance", description: "Chance of change", dfault: 0.5, min: 0, max: 1},
+ {name: "Portamento time", channel: "porttime", description: "Reading position glide", dfault: 0.1, min: 0.001, max: 0.5},
+ {name: "Distortion", channel: "distortion", description: "Apply distortion", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Amp change", channel: "ampchange", description: "Apply amplitude changes", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Buffer size", channel: "buflens", description: "Buffer size in seconds", dfault: 0.5, min: 0.1, max: 4, automatable: false, lagHint: -1},
+ {name: "Read mode", channel: "readmode", description: "Reading mode", dfault: 0, options: ["Direct", "Texture", "FFT"], automatable: false, lagHint: {option: 0}},
+ {name: "Stereo unique", channel: "stereounique", description: "Whether channels are glitched independently", dfault: 1, min: 0, max: 1, step: 1, automatable: false},
+ {presetgroup: "applymode"}
+
+ ]
+ },
+ {
+ name: "Syncgrain",
+ instr: "twst_tfi_syncgrain",
+ description: "Synchronous granular synthesis",
+ parameters: [
+ {preset: "amp"},
+ {name: "Frequency", description: "Grains per second", channel: "freq", step: 1, min: 1, max: 100, dfault: 20, lagHint: -1},
+ {presetgroup: "pitchscale"},
+ {name: "Grain size", channel: "grainsize", min: 0.01, max: 0.5, dfault: 0.1, lagHint: 1},
+ {name: "Overlaps", min: 1, max: 8, step: 1, dfault: 1},
+ {name: "Time scale", min: 0.1, max: 10, dfault: 1, channel: "timescale"},
+ {preset: "wintype"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Grain",
+ instr: "twst_tfi_grain",
+ description: "Granular synthesis",
+ parameters: [
+ {preset: "amp"},
+ {presetgroup: "pitchscale"},
+ {name: "Density", description: "Grains per second", channel: "density", step: 1, min: 1, max: 100, dfault: 20, lagHint: -1},
+ {name: "Grain size", channel: "grainsize", min: 0.01, max: 0.5, dfault: 0.1, lagHint: 1},
+ {name: "Amplitude variation", channel: "ampvar", min: 0, max: 1, dfault: 0},
+ {name: "Pitch variation", channel: "pitchvar", min: 0, max: 1, dfault: 0},
+ {name: "Random readpoint", min: 0, max: 1, step: 1, dfault: 1},
+ {preset: "wintype"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Retrigger",
+ instr: "twst_tfi_retriglitch",
+ description: "Repeated window reader",
+ parameters: [
+ {name: "Read mode", channel: "readmode", description: "Sample reading type", options: ["Linear", "Direct", "Scale", "Reverse", "Random"], dfault: 0},
+ {name: "Read position", channel: "readtime", description: "Read time ratio", dfault: 0.5, conditions: [{channel: "readmode", operator: "eq", value: 1}]},
+ {name: "Time scaling", channel: "timescale", description: "Time scaling factor", dfault: 1, min: 0.1, max: 16, conditions: [{channel: "readmode", operator: "eq", value: 2}], automatable: false},
+ {presetgroup: "pitchscale"},
+ {name: "Retrigger length", channel: "triglen", min: 0.01, max: 1, dfault: 0.2, lagHint: 1},
+ {name: "Apply windowing", channel: "applywindowing", step: 1, dfault: 0},
+ {preset: "wintype", conditions:[{channel: "applywindowing", operator: "eq", value: 1}]},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Sample rearrange",
+ instr: "twst_tfi_rearrange",
+ description: "Aleatoric sample range rearrangement",
+ parameters: [
+ {name: "Number of chops", description: "Number of sample rearrangements to apply", channel: "chopnumber", step: 1, min: 1, max: 128, dfault: 16, automatable: false},
+ {name: "Minimum samples", description: "Minimum number of samples to rearrange with each chop", channel: "chopmin", step: 1, min: 1, max: 1000, dfault: 400, automatable: false},
+ {name: "Maximum samples", description: "Maximum number of samples to rearrange with each chop", channel: "chopmax", step: 1, min: 64, max: 10000, dfault: 5000, automatable: false},
+ {name: "Stereo unique", description: "Whether to chop channels independently", channel: "stereounique", step: 1, min: 0, max: 1, dfault: 0, automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Harmonic", contents: [
+ {
+ name: "Parallel resonators",
+ instr: "twst_tf_resony",
+ twine: true,
+ parameters: [
+ {presetgroup: "notefreq"},
+ {name: "Bandwidth", description: "Bandwidth in Hz", dfault: 100, min: 1, max: 500},
+ {name: "Number", channel: "num", description: "Number of resonators", dfault: 8, min: 1, max: 64, step: 1, automatable: false, lagHint: -1},
+ {name: "Separation", description: "Band separation octaves", dfault: 1, min: 1, max: 6, step: 1, lagHint: 1},
+ {name: "Separation mode", channel: "sepmode", description: "Separation mode", options: ["Logarithmic", "Linear"], dfault: 0},
+ {name: "Balance output", channel: "balance", description: "Balance output level to input level", dfault: 1, min: 0, max: 1, step: 1, automatable: 0},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Resonator stack",
+ instr: "twst_tf_resonx",
+ twine: true,
+ parameters: [
+ {presetgroup: "notefreq"},
+ {name: "Bandwidth", description: "Bandwidth in Hz", dfault: 100, min: 1, max: 500},
+ {name: "Number", channel: "num", description: "Number of resonators", dfault: 8, min: 1, max: 64, step: 1, automatable: false, lagHint: -1},
+ {name: "Balance output", channel: "balance", description: "Balance output level to input level", dfault: 1, min: 0, max: 1, step: 1, automatable: 0},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "String resonator",
+ instr: "twst_tf_streson",
+ twine: true,
+ parameters: [
+ {presetgroup: "notefreq"},
+ {name: "Feedback", description: "Feedback gain", dfault: 0.6, min: 0, max: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "MVM resonator",
+ instr: "twst_tf_mvmfilter",
+ twine: true,
+ parameters: [
+ {name: "Frequency", channel: "freq", min: 10, max: 10000, dfault: 800},
+ {name: "Decay time", channel: "decay", min: 0.1, max: 0.8, dfault: 0.2, lagHint: -1},
+ {name: "Balance", channel: "balance", min: 0, max: 1, step: 1, dfault: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Autoharmoniser",
+ instr: "twst_tf_harmon",
+ twine: true,
+ parameters: [
+ {name: "Estimated frequency", channel: "estfreq", min: 10, max: 4000, dfault: 440},
+ {name: "Maximum variance", channel: "maxvar", dfault: 0.2},
+ {name: "Frequency 1 ratio", channel: "genfreq1", min: 0, max: 8, dfault: 2},
+ {name: "Frequency 2 ratio", channel: "genfreq2", min: 0, max: 8, dfault: 4},
+ {name: "Minimum analysis frequency", channel: "minfreq", min: 200, max: 4000, step: 1, dfault: 300, automatable: false, lagHint: 1},
+ {name: "Analysis time", channel: "minfreq", min: 0.01, max: 0.1, dfault: 0.03, automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Formant autoharmoniser",
+ instr: "twst_tf_formantharmon",
+ twine: true,
+ parameters: [
+ {name: "Frequency 1 ratio", channel: "genfreq1", min: 0, max: 8, dfault: 2},
+ {name: "Frequency 2 ratio", channel: "genfreq2", min: 0, max: 8, dfault: 3},
+ {name: "Frequency 3 ratio", channel: "genfreq3", min: 0, max: 8, dfault: 4},
+ {name: "Frequency 4 ratio", channel: "genfreq4", min: 0, max: 8, dfault: 5},
+ {name: "Minimum frequency", channel: "minfreq", min: 20, max: 4000, step: 1, dfault: 100, automatable: false},
+ {name: "Polarity", min: 0, max: 1, step: 1, dfault: 1, automatable: false},
+ {name: "Analysis window time", channel: "pupdate", min: 0.001, max: 0.1, dfault: 0.01, automatable: false, lagHint: 1},
+ {name: "Analysis bottom frequency", channel: "plowfreq", min: 20, max: 1000, dfault: 100, automatable: false, lagHint: 1},
+ {name: "Analysis top frequency", channel: "phighfreq", min: 1000, max: 22000, dfault: 20000, automatable: false, lagHint: -1},
+ {name: "Analysis threshold", channel: "pthresh", min: 0, max: 1, dfault: 0.4, automatable: false},
+ {name: "Analysis octave divisions", channel: "pfrqs", min: 1, max: 120, dfault: 12, step: 1, automatable: false, lagHint: 1},
+ {name: "Analysis confirmations", channel: "pconfirms", min: 1, max: 40, dfault: 10, step: 1, automatable: false, lagHint: -1},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Warping", contents: [
+ {
+ name: "Paulstretch",
+ instr: "twst_tfi_paulstretch",
+ description: "Extreme timestretch",
+ parameters: [
+ {name: "Stretch ratio", channel: "stretch", description: "Ratio to stretch by", dfault: 2, min: 1, max: 20, automatable: false},
+ {name: "Window size", channel: "winsize", description: "Window size used for stretch", dfault: 0.5, min: 0.1, max: 5, automatable: false, lagHint: -1}
+ ]
+ },
+ {
+ name: "Freeze",
+ instr: "twst_tf_freeze",
+ description: "Frequency domain freezing",
+ twine: true,
+ parameters: [
+ {name: "Freeze amp", channel: "freezeamp", description: "Freeze amplitudes", min: 0, max: 1, dfault: 1, step: 1},
+ {name: "Freeze frequency", channel: "freezefreq", description: "Freeze frequencies", min: 0, max: 1, dfault: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Waveset",
+ instr: "twst_tf_waveset",
+ description: "Repeat wave cycles",
+ twine: true,
+ parameters: [
+ {name: "Repetitions", channel: "reps", description: "Number of samples repetition in stretch", min: 1, max: 64, dfault: 2, step: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Blur",
+ instr: "twst_tf_blur",
+ description: "Frequency domain time blurring",
+ twine: true,
+ parameters: [
+ {name: "Blur time", channel: "time", description: "Blur time in seconds", min: 0.01, max: 3, dfault: 0.4, lagHint: -1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Spectral pitch scale",
+ instr: "twst_tf_fftpitchscale",
+ description: "Formant preserving pitch shifter",
+ twine: true,
+ parameters: [
+ {presetgroup: "pitchscale"},
+ {name: "Keep formants", channel: "formants", description: "Preserve formants", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Formant coefficients", channel: "formantcoefs", description: "Number of formants in preservation", dfault: 80, min: 1, max: 120, step: 1, conditions: [{channel: "formants", operator: "eq", value: 1}]},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Hilbert pitch scale",
+ instr: "twst_tf_hilbertpitchscale",
+ description: "Hilbert transform based pitch shifter",
+ twine: true,
+ parameters: [
+ {presetgroup: "pitchscale"},
+ {preset: "fftsize"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Autotune",
+ instr: "twst_tf_autotune",
+ description: "Formant preserving autotune pitch shifter",
+ twine: true,
+ parameters: [
+ {name: "Threshold", channel: "threshold", description: "Pitch detection threshold", dfault: 0.01, min: 0.001, max: 0.2},
+ {name: "Keep formants", channel: "formants", description: "Preserve formants", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Formant coefficients", channel: "formantcoefs", description: "Number of formants in preservation", dfault: 80, min: 1, max: 120, step: 1, conditions: [{channel: "formants", operator: "eq", value: 1}]},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Window reader",
+ instr: "twst_tfi_sndwarp",
+ description: "Windowed playback",
+ parameters: [
+ {name: "Read mode", channel: "readmode", description: "Sample reading type", options: ["Linear", "Direct", "Scale", "Reverse"], dfault: 0},
+ {name: "Read position", channel: "readtime", description: "Read time ratio", dfault: 0.5, conditions: [{channel: "readmode", operator: "eq", value: 1}]},
+ {name: "Time scaling", channel: "timescale", description: "Time scaling factor", dfault: 1, min: 0.1, max: 16, conditions: [{channel: "readmode", operator: "eq", value: 2}], automatable: false},
+ {presetgroup: "pitchscale"},
+ {name: "Window size", channel: "winsize", description: "Window size", min: 256, max: 10000, dfault: 4410, step: 1, automatable: false, lagHint: -1},
+ {name: "Window randomness", channel: "winrand", description: "Randomness in window size", min: 0, max: 1000, dfault: 441, step: 1, automatable: false},
+ {name: "Window overlap", channel: "overlap", description: "Overlap number", min: 1, max: 32, dfault: 4, step: 1, automatable: false, lagHint: -1},
+ {preset: "wintype"}
+ ]
+ },
+ {
+ name: "FFT reader",
+ instr: "twst_tfi_mincer",
+ description: "Frequency domain playback",
+ parameters: [
+ {name: "Read mode", channel: "readmode", description: "Sample reading type", options: ["Linear", "Direct", "Scale", "Reverse"], dfault: 0},
+ {name: "Read position", channel: "readtime", description: "Read time ratio", dfault: 0.5, conditions: [{channel: "readmode", operator: "eq", value: 1}]},
+ {name: "Time scaling", channel: "timescale", description: "Time scaling factor", dfault: 1, min: 0.1, max: 16, conditions: [{channel: "readmode", operator: "eq", value: 2}], automatable: false},
+ {presetgroup: "pitchscale"},
+ {name: "Phase lock", channel: "phaselock", description: "Lock phase when resynthesising", dfault: 0, min: 0, max: 1, step: 1},
+ {preset: "fftsize"},
+ {name: "Overlap decimation", options: [2, 4, 8, 16], asvalue: true, dfault: 1, channel: "decimation", automatable: false, lagHint: -1}
+ ]
+ },
+ {
+ name: "Sample holder",
+ instr: "twst_tf_smphold",
+ twine: true,
+ parameters: [
+ {name: "Ratio", description: "Inverse ratio of samples to be held in a block period", min: 0.000001},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Cross processing", contents: [
+ {
+ name: "Cross synth",
+ instr: "twst_tf_crosssynth",
+ description: "Amplitude based cross synthesis",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"},
+ {name: "Current amp", channel: "amp1", description: "Ratio of current amplitude to use", dfault: 1, min: 0, max: 1},
+ {name: "Target amp", channel: "amp2", description: "Ratio of target amplitude to use", dfault: 1, min: 0, max: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Direct convolution",
+ instr: "twst_tf_directconvolve",
+ description: "Convolution",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "amp"},
+ {name: "Size ratio", min: 0.00001, max: 1, dfault: 0.1, lagHint: -1, channel: "sizeratio", automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Block convolution",
+ instr: "twst_tf_blockconvolve",
+ description: "Short term frequency domain convolution",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"},
+ {preset: "fftsize", dfault: 2},
+ {name: "Overlap", min: 1, max: 8, step: 1, dfault: 2, lagHint: -1},
+ {presetgroup: "applymode"}
+ ]
+ }, /* not in WASM at current
+ {
+ name: "DFT/FIR convolve",
+ instr: "twst_tf_tvconv",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"},
+ {name: "Update source", channel: "apply1", min: 0, max: 1, step: 1, dfault: 1},
+ {name: "Update destination", channel: "apply2", min: 0, max: 1, step: 1, dfault: 1},
+ {name: "Mode", options: ["DFT", "FIR"]},
+ {name: "Partition size", channel: "parts", options: [16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192], dfault: 5, asvalue: true, conditions: [{channel: "mode", operator: "eq", value: 0}]},
+ {name: "Filter size", channel: "dftfiltersize", options: [16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192], dfault: 5, asvalue: true, conditions: [{channel: "mode", operator: "eq", value: 0}]},
+ {name: "Filter size", channel: "firfiltersize", min: 2, max: 8192, dfault: 512, conditions: [{channel: "mode", operator: "eq", value: 1}]},
+ {presetgroup: "applymode"}
+ ]
+ }, */
+ {
+ name: "Morph",
+ instr: "twst_tf_morph",
+ description: "Amplitude and frequency cross synthesis",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", name: "Cross instance"},
+ {preset: "instanceloop"},
+ {name: "Amplitude amount", channel: "amp", description: "Amplitude interpolation", dfault: 1, min: 0, max: 1},
+ {name: "Frequency amount", channel: "freq", description: "Frequency interpolation", dfault: 1, min: 0, max: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Concatenative resynthesis",
+ instr: "twst_tf_mfccmatch",
+ description: "Map nearest perceptually similar segments",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", name: "Corpus"},
+ {preset: "instanceloop"},
+ {preset: "fftsize"},
+ {name: "Minimum frequency", channel: "freqmin", description: "Minimum frequency to account for", dfault: 100, min: 30, max: 1000, automatable: false, lagHint: 1},
+ {name: "Maximum frequency", channel: "freqmax", description: "Maximum frequency to account for", dfault: 4000, min: 1000, max: 20000, automatable: false, lagHint: -1},
+ {name: "Bands", channel: "bands", description: "Number of frequency bands to use", dfault: 3, options:[2, 4, 8, 16, 32, 64], asvalue: true, automatable: false, lagHint: -1},
+ {name: "Stretch", channel: "stretch", description: "Read stretch", dfault: 0.35, min: 0.1, max: 2.5},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Cross rearrange",
+ instr: "twst_tf_crossrearrange",
+ description: "Select chunks from all open instances",
+ added: "2025-04-17",
+ parameters: [
+ {name: "Minimum samples", channel: "minsamples", description: "Minimum number of samples to chop", dfault: 4410, min: 10, max: 10000},
+ {name: "Maximum samples", channel: "maxsamples", description: "Maximum number of samples to chop", dfault: 10000, min: 1000, max: 50000},
+ {name: "Change rate", channel: "rate", description: "Rate of rearrangement change", dfault: 4, min: 0.1, max: 20},
+ {name: "Stereo unique", channel: "stereounique", description: "Stereo independent rearrangement", dfault: 1, min: 0, max: 1, step: 1},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ },
+ {
+ name: "Spectral", contents: [
+ {
+ name: "Spectral autoglitch",
+ instr: "twst_tf_spectralautoglitch",
+ description: "Automatic frequency domain glitcher",
+ twine: true,
+ parameters: [
+ {name: "Change rate", channel: "changerate", description: "Rate of change", dfault: 1, min: 0.1, max: 10, lagHint: -1},
+ {name: "Change chance", channel: "changechance", description: "Chance of change", dfault: 0.5, min: 0, max: 1, lagHint: -1},
+ {name: "Portamento time", channel: "porttime", description: "Reading position glide", dfault: 0.1, min: 0.001, max: 0.5},
+ {name: "Alter pitch", channel: "pitchalter", description: "Apply pitch alterations", dfault: 0, min: 0, max: 1, step: 1},
+ {preset: "fftsize"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Delay",
+ instr: "twst_tf_spectraldelay",
+ description: "Frequency domain bin-independent delay",
+ unstable: true,
+ parameters: [
+ {name: "Delay time", channel: "time", description: "Delay time in seconds", dfault: 0.03, min: 0.01, max: 0.4, lagHint: -1},
+ {name: "Delay time add", channel: "add", description: "Delay time addition with each step", dfault: 0.001, min: 0, max: 0.2, lagHint: -1},
+ {name: "Portamento", channel: "porttime", description: "Resynthesis oscillator portamento time in seconds", dfault: 0.01, min: 0.01, max: 0.1},
+ {presetgroup: "pitchscale"},
+ {name: "Frequency bottom ratio", automatable: false, channel: "start", description: "Resynthesis bin start", dfault: 0, lagHint: 1},
+ {name: "Frequency top ratio", automatable: false, channel: "end", description: "Resynthesis bin end", dfault: 0.3, lagHint: -1},
+ {name: "Resynthesis waveform", preset: "wave"},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },/* not in WASM
+ {
+ name: "Trace",
+ instr: "twst_tf_trace",
+ twine: true,
+ description: "Retain only a selected number of the loudest bins",
+ parameters: [
+ {name: "Number of bins (ratio)", description: "Number of frequency bins to retain", dfault: 0.5, min: 0, max: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },*/
+ {
+ name: "Isolator",
+ instr: "twst_tf_isolator",
+ description: "Isolate an analysis bin",
+ twine: true,
+ parameters: [
+ {name: "Bin (ratio)", description: "Bin to use", dfault: 0.1, min: 0, max: 1, channel: "bin"},
+ {name: "Attenuation", description: "Bin attenuation", dfault: 1, min: 0, max: 1},
+ {name: "Accentuation", description: "Bin accentuation", dfault: 1, min: 0, max: 2},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Shift",
+ instr: "twst_tf_spectralshift",
+ description: "Frequency shifter in the spectral domain",
+ twine: true,
+ parameters: [
+ {name: "Shift", channel: "freqincr", description: "Frequency addition per bin", dfault: 0, min: -100, max: 100},
+ {name: "Portamento", channel: "porttime", description: "Resynthesis oscillator portamento time in seconds", dfault: 0.01, min: 0.01, max: 0.1},
+ {presetgroup: "pitchscale"},
+ {name: "Frequency bottom ratio", automatable: false, channel: "start", description: "Resynthesis bin start", dfault: 0, lagHint: 1},
+ {name: "Frequency top ratio", dfault: 0.3, automatable: false, channel: "end", description: "Resynthesis bin end", lagHint: -1},
+ {name: "Resynthesis waveform", preset: "wave"},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Gate",
+ instr: "twst_tf_spectralgate",
+ description: "Analysis bin-independent gate",
+ twine: true,
+ parameters: [
+ {name: "Threshold", description: "Gate threshold", dfault: 0.01, min: 0, max: 0.2},
+ {name: "Hold", description: "Hold or decay frequencies", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Portamento", channel: "porttime", description: "Resynthesis oscillator portamento time in seconds", dfault: 0.01, min: 0.01, max: 0.1},
+ {presetgroup: "pitchscale"},
+ {name: "Frequency bottom ratio", automatable: false, channel: "start", description: "Resynthesis bin start", dfault: 0, lagHint: 1},
+ {name: "Frequency top ratio", dfault: 0.3, automatable: false, channel: "end", description: "Resynthesis bin end", lagHint: -1},
+ {name: "Resynthesis waveform", preset: "wave"},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Granular",
+ instr: "twst_tfi_spectralgrain1",
+ description: "Frequency domain granular synthesis",
+ parameters: [
+ {name: "Grain duration", channel: "graindur", description: "Duration of grains in seconds", min: 0.05, max: 2, dfault: 0.2},
+ {name: "Overlaps", channel: "layers", description: "Layers of grains", min: 1, max: 6, dfault: 1, step: 1, automatable: false},
+ {name: "Rate randomness", channel: "freqrand", description: "Read rate randomness", min: 1, max: 3, dfault: 1},
+ {name: "Duration randomness", channel: "durrand", description: "Grain duration randomness", min: 1, max: 3, dfault: 1},
+ {name: "Pitch randomness", channel: "pitchrand", description: "Grain pitch randomness", min: 1, max: 3, dfault: 1},
+ {name: "Read mode", channel: "readmode", description: "Grain reading mode", options: ["Linear", "Direct", "Scale", "Reverse"], dfault: 0},
+ {name: "Read position", channel: "readtime", description: "Read time ratio", dfault: 0.5, conditions: [{channel: "readmode", operator: "eq", value: 1}]},
+ {name: "Time scaling", channel: "timescale", description: "Time scaling factor", dfault: 1, min: 0.1, max: 10, conditions: [{channel: "readmode", operator: "eq", value: 2}], automatable: false},
+ {name: "Portamento", channel: "porttime", description: "Resynthesis oscillator portamento time in seconds", dfault: 0.01, min: 0.01, max: 0.1},
+ {presetgroup: "pitchscale"},
+ {name: "Frequency bottom ratio", automatable: false, channel: "start", description: "Resynthesis bin start", dfault: 0, lagHint: 1},
+ {name: "Frequency top ratio", dfault: 0.3, automatable: false, channel: "end", description: "Resynthesis bin end", lagHint: -1},
+ {name: "Resynthesis waveform", preset: "wave"},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Residuals",
+ instr: "twst_tf_residual",
+ description: "Spectral resynthesis residuals",
+ twine: true,
+ parameters: [
+ {preset: "fftsize"}
+ ]
+ },
+ /*{
+ name: "Stencil",
+ instr: "twst_tf_stencil",
+ unstable: true,
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"},
+ {name: "Gain", description: "Pre processing gain", dfault: 1},
+ {name: "Level", description: "Level of transformation", dfault: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+
+ },*/
+ {
+ name: "Bubble",
+ instr: "twst_tf_tpvbubble",
+ description: "Randomly reset bin amplitudes to zero",
+ twine: true,
+ parameters: [
+ {name: "Chance", description: "Chance of resetting bin amplitudes to 0", dfault: 0.5},
+ {name: "Stereo unique", channel: "stereounique", description: "Whether to apply channel independently", dfault: 1, min: 0, max: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Smear",
+ instr: "twst_tf_tpvsmear",
+ description: "Delay bin amplitudes",
+ twine: true,
+ parameters: [
+ {name: "Maximum frames", channel: "maxframes", description: "Maximum number of frames to be used", automatable: false, min: 4, max: 32, step: 1, dfault: 16},
+ {name: "Frames", description: "Number of frames to be used", min: 4, max: 32, step: 1, dfault: 16},
+ {name: "Average frequencies", channel: "avgfreqs", description: "Average frequencies as well as smearing amplitudes", min: 0, max: 1, step: 1, dfault: 1},
+ {name: "Include original", channel: "includeoriginal", description: "Include original frames in output", min: 0, max: 1, step: 1, dfault: 0},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Read",
+ instr: "twst_tf_spectralread",
+ description: "Frequency domain sample reader",
+ parameters: [
+ {name: "Read position", channel: "readtime", description: "Read time ratio", dfault: 0},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Partial reconstruction",
+ instr: "twst_tf_partialreconstruction",
+ description: "Streaming partials resynthesis",
+ twine: true,
+ parameters: [
+ {name: "Threshold", description: "Analysis threshold factor", dfault: 0.5},
+ {name: "Minimum points", channel: "minpoints", description: "Minimum analysis points", dfault: 1, min: 1, max: 10, lagHint: 1},
+ {name: "Maximum gap", channel: "maxgap", description: "Maximum gap between analysis points", dfault: 3, min: 1, max: 10, lagHint: 1},
+ {name: "Maximum analysis tracks", channel: "anlmaxtracks", description: "Maximum number of frequency tracks in analysis", automatable: false, lagHint: -1},
+ {name: "Amplitude scale", channel: "ampscale", description: "Amplitude scaling"},
+ {presetgroup: "pitchscale"},
+ {name: "Maximum resynth tracks", channel: "resmaxtracks", description: "Maximum number of frequency tracks in resynthesis", lagHint: -1},
+ {preset: "fftsize"},
+ {preset: "wave"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Invert",
+ instr: "twst_tf_tpvinvert",
+ description: "Invert frequency and/or amplitude",
+ twine: true,
+ parameters: [
+ {name: "Invert frequency", channel: "invertfreq", description: "Perform inversion of frequency", dfault: 1, min: 0, max: 1, step: 1},
+ {name: "Invert amplitude", channel: "invertamp", description: "Perform inversion of amplitude", dfault: 1, min: 0, max: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth", dfault: 1},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Scramble",
+ instr: "twst_tf_tpvscramble",
+ twine: true,
+ description: "Randomly reassign amplitude and/or frequency",
+ parameters: [
+ {name: "Sanity", channel: "step", description: "Retention of sanity in scrambling", dfault: 0, min: 0, max: 1},
+ {name: "Amplitude", channel: "scrambleamp", description: "Apply scrambling to amplitude", dfault: 1, min: 0, max: 1, step: 1},
+ {name: "Frequency", channel: "scramblefreq", description: "Apply scrambling to frequency", dfault: 1, min: 0, max: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Frame gate",
+ instr: "twst_tf_tpvthreshold",
+ twine: true,
+ description: "Bin-independent spectral gate",
+ parameters: [
+ {name: "Threshold", description: "Amplitude threshold", dfault: 0.5, min: 0, max: 1},
+ {name: "Direction", description: "Apply to above or below threshold", dfault: 0, min: 0, max: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Frame freeze",
+ instr: "twst_tf_tpvfreeze",
+ twine: true,
+ description: "Freeze analysis frames",
+ parameters: [
+ {name: "Freeze amount", channel: "freeze", description: "Freeze amount", dfault: 1, min: 0, max: 1},
+ {name: "Freeze amplitude", channel: "freezeamp", description: "Apply amplitude freeze", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Freeze frequency", channel: "freezefreq", description: "Apply amplitude freeze", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Apply crossfades", channel: "crossfade", dfault: 0, min: 0, max: 1, step: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Average",
+ instr: "twst_tf_tpvaverage",
+ twine: true,
+ description: "Time-average frequency and/or amplitudes",
+ parameters: [
+ {name: "Average amplitudes", channel: "avgamp", dfault: 0, min: 0, max: 1, step: 1},
+ {name: "Average frequencies", channel: "avgfreq", dfault: 1, min: 0, max: 1, step: 1},
+ {name: "Maximum frames", description: "Maximum frames in average window", channel: "maxframes", dfault: 16, min: 2, max: 512, step: 1, lagHint: -1},
+ {name: "Rate", description: "Rate of averaging in Hz", dfault: 1, min: 0.1, max: 10, lagHint: -1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Wrap",
+ instr: "twst_tf_tpvwrap",
+ twine: true,
+ description: "Wrap amplitude and/or frequency bins",
+ parameters: [
+ {name: "Amplitude wrap bin ratio", channel: "wrapampbin", dfault: 0, min: 0, max: 3},
+ {name: "Frequency wrap bin ratio", channel: "wrapfreqbin", dfault: 1, min: 0, max: 3},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Swap",
+ instr: "twst_tf_tpvswap",
+ twine: true,
+ description: "Swap amplitude and/or frequency bin ranges",
+ parameters: [
+ {name: "Amplitude start bin ratio", channel: "ampstart"},
+ {name: "Amplitude length bin ratio", channel: "amplength", dfault: 0.1},
+ {name: "Amplitude target bin ratio", channel: "amptarget"},
+ {name: "Frequency start bin ratio", channel: "freqstart"},
+ {name: "Frequency length bin ratio", channel: "freqlength", dfault: 0.1},
+ {name: "Frequency target bin ratio", channel: "freqtarget"},
+ {name: "Wrap mode", channel: "wrapmode", options: ["Limit", "Wrap"], dfault: 1, automatable: true},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Centroid oscillator",
+ instr: "twst_tf_centroidoscillator",
+ twine: true,
+ description: "Oscillate at the analysed spectral centroid",
+ parameters: [
+ {preset: "wave", automatable: true},
+ {presetgroup: "pitchscale"},
+ {name: "Portamento time", channel: "porttime", description: "Reading position glide", dfault: 0.01, min: 0.001, max: 0.3},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Bin oscillator",
+ instr: "twst_tf_binoscillator",
+ twine: true,
+ description: "Resynthesise a single analysis bin",
+ parameters: [
+ {name: "Bin ratio", channel: "bin", description: "Frequency bin ratio", dfault: 0.1, min: 0, max: 1},
+ {preset: "wave", automatable: true},
+ {presetgroup: "pitchscale"},
+ {name: "Portamento time", channel: "porttime", description: "Reading position glide", dfault: 0.01, min: 0.001, max: 0.3},
+ {presetgroup: "pvanal"},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Stochastic subtractive",
+ instr: "twst_tf_subtractive",
+ description: "Parametric aleatoric subtractive synthesis",
+ twine: true,
+ unstable: true,
+ parameters: [
+ {preset: "amp", automatable: false},
+ {presetgroup: "notefreq", nameprepend: "Minimum", dfault: 440, channelprepend: "min", automatable: false, lagHint: 1},
+ {presetgroup: "notefreq", nameprepend: "Maximum", dfault: 8000, channelprepend: "max", automatable: false, lagHint: -1},
+ {name: "Frequency increment", channel: "step", automatable: false, min: 1.1, max: 2, dfault: 1, lagHint: 1},
+ {name: "Frequency randomness", channel: "steprand", automatable: false, min: 1, max: 1.5, dfault: 1},
+ {name: "Amplitude increment", channel: "ampmult", automatable: false, min: 0.2, max: 1, dfault: 0.6},
+ {presetgroup: "applymode"}
+ ]
+ },
+ {
+ name: "Phase masher",
+ instr: "twst_tf_phasemash",
+ twine: true,
+ description: "Phase modification and reset",
+ parameters: [
+ {name: "Replace phase", min: 0, max: 1, step: 1, dfault: 0, channel: "phasereplace"},
+ {name: "Phase alteration", min: 0, max: 1, dfault: 0.5, channel: "phasevalue"},
+ {preset: "fftsize"},
+ {presetgroup: "applymode"}
+ ]
+ }
+ ]
+ }
+ ]
+};
\ No newline at end of file diff --git a/site/app/twirl/font/Chicago.woff b/site/app/twirl/font/Chicago.woff Binary files differnew file mode 100644 index 0000000..0ae3393 --- /dev/null +++ b/site/app/twirl/font/Chicago.woff diff --git a/site/app/twirl/font/JosefinSans.ttf b/site/app/twirl/font/JosefinSans.ttf Binary files differnew file mode 100644 index 0000000..00ea1e7 --- /dev/null +++ b/site/app/twirl/font/JosefinSans.ttf diff --git a/site/app/twirl/font/NationalPark-Regular.woff b/site/app/twirl/font/NationalPark-Regular.woff Binary files differnew file mode 100644 index 0000000..7766e9b --- /dev/null +++ b/site/app/twirl/font/NationalPark-Regular.woff diff --git a/site/app/twirl/font/Nouveau_IBM.woff b/site/app/twirl/font/Nouveau_IBM.woff Binary files differnew file mode 100644 index 0000000..0912b18 --- /dev/null +++ b/site/app/twirl/font/Nouveau_IBM.woff diff --git a/site/app/twirl/icon/areaSelect.svg b/site/app/twirl/icon/areaSelect.svg new file mode 100644 index 0000000..dc0549c --- /dev/null +++ b/site/app/twirl/icon/areaSelect.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-dashed-mouse-pointer"><path d="M12.034 12.681a.498.498 0 0 1 .647-.647l9 3.5a.5.5 0 0 1-.033.943l-3.444 1.068a1 1 0 0 0-.66.66l-1.067 3.443a.5.5 0 0 1-.943.033z"/><path d="M5 3a2 2 0 0 0-2 2"/><path d="M19 3a2 2 0 0 1 2 2"/><path d="M5 21a2 2 0 0 1-2-2"/><path d="M9 3h1"/><path d="M9 21h2"/><path d="M14 3h1"/><path d="M3 9v1"/><path d="M21 9v2"/><path d="M3 14v1"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/arrowsUpDown.svg b/site/app/twirl/icon/arrowsUpDown.svg new file mode 100644 index 0000000..8ecaa91 --- /dev/null +++ b/site/app/twirl/icon/arrowsUpDown.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-down"><path d="m21 16-4 4-4-4"/><path d="M17 20V4"/><path d="m3 8 4-4 4 4"/><path d="M7 4v16"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/audition.svg b/site/app/twirl/icon/audition.svg new file mode 100644 index 0000000..d4a3dea --- /dev/null +++ b/site/app/twirl/icon/audition.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-volume-2"><path d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"/><path d="M16 9a5 5 0 0 1 0 6"/><path d="M19.364 18.364a9 9 0 0 0 0-12.728"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/automate.svg b/site/app/twirl/icon/automate.svg new file mode 100644 index 0000000..16a9705 --- /dev/null +++ b/site/app/twirl/icon/automate.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chart-spline"><path d="M3 3v16a2 2 0 0 0 2 2h16"/><path d="M7 16c.5-2 1.5-7 4-7 2 0 2 3 4 3 2.5 0 4.5-5 5-7"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/brightnessDecrease.svg b/site/app/twirl/icon/brightnessDecrease.svg new file mode 100644 index 0000000..4685dae --- /dev/null +++ b/site/app/twirl/icon/brightnessDecrease.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sun-dim"><circle cx="12" cy="12" r="4"/><path d="M12 4h.01"/><path d="M20 12h.01"/><path d="M12 20h.01"/><path d="M4 12h.01"/><path d="M17.657 6.343h.01"/><path d="M17.657 17.657h.01"/><path d="M6.343 17.657h.01"/><path d="M6.343 6.343h.01"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/brightnessIncrease.svg b/site/app/twirl/icon/brightnessIncrease.svg new file mode 100644 index 0000000..12f688b --- /dev/null +++ b/site/app/twirl/icon/brightnessIncrease.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-sun-medium"><circle cx="12" cy="12" r="4"/><path d="M12 3v1"/><path d="M12 20v1"/><path d="M3 12h1"/><path d="M20 12h1"/><path d="m18.364 5.636-.707.707"/><path d="m6.343 17.657-.707.707"/><path d="m5.636 5.636.707.707"/><path d="m17.657 17.657.707.707"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/close.svg b/site/app/twirl/icon/close.svg new file mode 100644 index 0000000..fa22a65 --- /dev/null +++ b/site/app/twirl/icon/close.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-x"><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/commit.svg b/site/app/twirl/icon/commit.svg new file mode 100644 index 0000000..b00c67b --- /dev/null +++ b/site/app/twirl/icon/commit.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-import"><path d="M12 3v12"/><path d="m8 11 4 4 4-4"/><path d="M8 5H4a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/copy.svg b/site/app/twirl/icon/copy.svg new file mode 100644 index 0000000..84d777d --- /dev/null +++ b/site/app/twirl/icon/copy.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard-copy"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/><path d="M16 4h2a2 2 0 0 1 2 2v4"/><path d="M21 14H11"/><path d="m15 10-4 4 4 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/crossfade.svg b/site/app/twirl/icon/crossfade.svg new file mode 100644 index 0000000..ca5f34e --- /dev/null +++ b/site/app/twirl/icon/crossfade.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-flip-horizontal-2"><path d="m3 7 5 5-5 5V7"/><path d="m21 7-5 5 5 5V7"/><path d="M12 20v2"/><path d="M12 14v2"/><path d="M12 8v2"/><path d="M12 2v2"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/cut.svg b/site/app/twirl/icon/cut.svg new file mode 100644 index 0000000..ca0a485 --- /dev/null +++ b/site/app/twirl/icon/cut.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scissors"><circle cx="6" cy="6" r="3"/><path d="M8.12 8.12 12 12"/><path d="M20 4 8.12 15.88"/><circle cx="6" cy="18" r="3"/><path d="M14.8 14.8 20 20"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/delete.svg b/site/app/twirl/icon/delete.svg new file mode 100644 index 0000000..b1d974f --- /dev/null +++ b/site/app/twirl/icon/delete.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-delete"><path d="M10 5a2 2 0 0 0-1.344.519l-6.328 5.74a1 1 0 0 0 0 1.481l6.328 5.741A2 2 0 0 0 10 19h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z"/><path d="m12 9 6 6"/><path d="m18 9-6 6"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/develop.svg b/site/app/twirl/icon/develop.svg new file mode 100644 index 0000000..9d3f535 --- /dev/null +++ b/site/app/twirl/icon/develop.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-codepen"><polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"/><line x1="12" x2="12" y1="22" y2="15.5"/><polyline points="22 8.5 12 15.5 2 8.5"/><polyline points="2 15.5 12 8.5 22 15.5"/><line x1="12" x2="12" y1="2" y2="8.5"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/ear.svg b/site/app/twirl/icon/ear.svg new file mode 100644 index 0000000..d2cb61a --- /dev/null +++ b/site/app/twirl/icon/ear.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ear"><path d="M6 8.5a6.5 6.5 0 1 1 13 0c0 6-6 6-6 10a3.5 3.5 0 1 1-7 0"/><path d="M15 8.5a2.5 2.5 0 0 0-5 0v1a2 2 0 1 1 0 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/fileVolume.svg b/site/app/twirl/icon/fileVolume.svg new file mode 100644 index 0000000..ee81c71 --- /dev/null +++ b/site/app/twirl/icon/fileVolume.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-volume-2"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M8 15h.01"/><path d="M11.5 13.5a2.5 2.5 0 0 1 0 3"/><path d="M15 12a5 5 0 0 1 0 6"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/hand.svg b/site/app/twirl/icon/hand.svg new file mode 100644 index 0000000..b258330 --- /dev/null +++ b/site/app/twirl/icon/hand.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-hand"><path d="M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2"/><path d="M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2"/><path d="M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8"/><path d="M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/hide.svg b/site/app/twirl/icon/hide.svg new file mode 100644 index 0000000..1b66ce0 --- /dev/null +++ b/site/app/twirl/icon/hide.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"/><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"/><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"/><path d="m2 2 20 20"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/horizontalArrows.svg b/site/app/twirl/icon/horizontalArrows.svg new file mode 100644 index 0000000..3187142 --- /dev/null +++ b/site/app/twirl/icon/horizontalArrows.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-move-horizontal"><path d="m18 8 4 4-4 4"/><path d="M2 12h20"/><path d="m6 8-4 4 4 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/horizontalFold.svg b/site/app/twirl/icon/horizontalFold.svg new file mode 100644 index 0000000..4c80762 --- /dev/null +++ b/site/app/twirl/icon/horizontalFold.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-fold-horizontal"><path d="M2 12h6"/><path d="M22 12h-6"/><path d="M12 2v2"/><path d="M12 8v2"/><path d="M12 14v2"/><path d="M12 20v2"/><path d="m19 9-3 3 3 3"/><path d="m5 15 3-3-3-3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/lasso.svg b/site/app/twirl/icon/lasso.svg new file mode 100644 index 0000000..bbf7602 --- /dev/null +++ b/site/app/twirl/icon/lasso.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lasso"><path d="M7 22a5 5 0 0 1-2-4"/><path d="M3.3 14A6.8 6.8 0 0 1 2 10c0-4.4 4.5-8 10-8s10 3.6 10 8-4.5 8-10 8a12 12 0 0 1-5-1"/><path d="M5 18a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/loop.svg b/site/app/twirl/icon/loop.svg new file mode 100644 index 0000000..b5eef47 --- /dev/null +++ b/site/app/twirl/icon/loop.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-repeat-2"><path d="m2 9 3-3 3 3"/><path d="M13 18H7a2 2 0 0 1-2-2V6"/><path d="m22 15-3 3-3-3"/><path d="M11 6h6a2 2 0 0 1 2 2v10"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/modulate.svg b/site/app/twirl/icon/modulate.svg new file mode 100644 index 0000000..891ded8 --- /dev/null +++ b/site/app/twirl/icon/modulate.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-audio-waveform"><path d="M2 13a2 2 0 0 0 2-2V7a2 2 0 0 1 4 0v13a2 2 0 0 0 4 0V4a2 2 0 0 1 4 0v13a2 2 0 0 0 4 0v-4a2 2 0 0 1 2-2"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/move.svg b/site/app/twirl/icon/move.svg new file mode 100644 index 0000000..1f839f4 --- /dev/null +++ b/site/app/twirl/icon/move.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-move"><path d="M12 2v20"/><path d="m15 19-3 3-3-3"/><path d="m19 9 3 3-3 3"/><path d="M2 12h20"/><path d="m5 9-3 3 3 3"/><path d="m9 5 3-3 3 3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/paste.svg b/site/app/twirl/icon/paste.svg new file mode 100644 index 0000000..0f94433 --- /dev/null +++ b/site/app/twirl/icon/paste.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard-paste"><path d="M15 2H9a1 1 0 0 0-1 1v2c0 .6.4 1 1 1h6c.6 0 1-.4 1-1V3c0-.6-.4-1-1-1Z"/><path d="M8 4H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2M16 4h2a2 2 0 0 1 2 2v2M11 14h10"/><path d="m17 10 4 4-4 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/pasteSpecial.svg b/site/app/twirl/icon/pasteSpecial.svg new file mode 100644 index 0000000..387b56b --- /dev/null +++ b/site/app/twirl/icon/pasteSpecial.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-clipboard-pen"><rect width="8" height="4" x="8" y="2" rx="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-5.5"/><path d="M4 13.5V6a2 2 0 0 1 2-2h2"/><path d="M13.378 15.626a1 1 0 1 0-3.004-3.004l-5.01 5.012a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506z"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/pencil.svg b/site/app/twirl/icon/pencil.svg new file mode 100644 index 0000000..8d5e050 --- /dev/null +++ b/site/app/twirl/icon/pencil.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/play.svg b/site/app/twirl/icon/play.svg new file mode 100644 index 0000000..f089aa1 --- /dev/null +++ b/site/app/twirl/icon/play.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-play"><polygon points="6 3 20 12 6 21 6 3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/pointer.svg b/site/app/twirl/icon/pointer.svg new file mode 100644 index 0000000..2180fb9 --- /dev/null +++ b/site/app/twirl/icon/pointer.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mouse-pointer"><path d="M12.586 12.586 19 19"/><path d="M3.688 3.037a.497.497 0 0 0-.651.651l6.5 15.999a.501.501 0 0 0 .947-.062l1.569-6.083a2 2 0 0 1 1.448-1.479l6.124-1.579a.5.5 0 0 0 .063-.947z"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/randomise.svg b/site/app/twirl/icon/randomise.svg new file mode 100644 index 0000000..73e0c43 --- /dev/null +++ b/site/app/twirl/icon/randomise.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-dices"><rect width="12" height="12" x="2" y="10" rx="2" ry="2"/><path d="m17.92 14 3.5-3.5a2.24 2.24 0 0 0 0-3l-5-4.92a2.24 2.24 0 0 0-3 0L10 6"/><path d="M6 18h.01"/><path d="M10 14h.01"/><path d="M15 6h.01"/><path d="M18 9h.01"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/record.svg b/site/app/twirl/icon/record.svg new file mode 100644 index 0000000..726d9f1 --- /dev/null +++ b/site/app/twirl/icon/record.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mic"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" x2="12" y1="19" y2="22"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/redo.svg b/site/app/twirl/icon/redo.svg new file mode 100644 index 0000000..c6dbd45 --- /dev/null +++ b/site/app/twirl/icon/redo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-redo"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/reset.svg b/site/app/twirl/icon/reset.svg new file mode 100644 index 0000000..f28f3db --- /dev/null +++ b/site/app/twirl/icon/reset.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-list-restart"><path d="M21 6H3"/><path d="M7 12H3"/><path d="M7 18H3"/><path d="M12 18a5 5 0 0 0 9-3 4.5 4.5 0 0 0-4.5-4.5c-1.33 0-2.54.54-3.41 1.41L11 14"/><path d="M11 10v4h4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/rewind.svg b/site/app/twirl/icon/rewind.svg new file mode 100644 index 0000000..4aa6f48 --- /dev/null +++ b/site/app/twirl/icon/rewind.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rewind"><polygon points="11 19 2 12 11 5 11 19"/><polygon points="22 19 13 12 22 5 22 19"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/save.svg b/site/app/twirl/icon/save.svg new file mode 100644 index 0000000..1fec9b0 --- /dev/null +++ b/site/app/twirl/icon/save.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-save"><path d="M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z"/><path d="M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7"/><path d="M7 3v4a1 1 0 0 0 1 1h7"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/script.svg b/site/app/twirl/icon/script.svg new file mode 100644 index 0000000..85069c6 --- /dev/null +++ b/site/app/twirl/icon/script.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scroll-text"><path d="M15 12h-5"/><path d="M15 8h-5"/><path d="M19 17V5a2 2 0 0 0-2-2H4"/><path d="M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/show.svg b/site/app/twirl/icon/show.svg new file mode 100644 index 0000000..8ca30ae --- /dev/null +++ b/site/app/twirl/icon/show.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/showAll.svg b/site/app/twirl/icon/showAll.svg new file mode 100644 index 0000000..ceb57c5 --- /dev/null +++ b/site/app/twirl/icon/showAll.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-fullscreen"><path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><rect width="10" height="8" x="7" y="8" rx="1"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/stop.svg b/site/app/twirl/icon/stop.svg new file mode 100644 index 0000000..f5e9c24 --- /dev/null +++ b/site/app/twirl/icon/stop.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square"><rect width="18" height="18" x="3" y="3" rx="2"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/trim.svg b/site/app/twirl/icon/trim.svg new file mode 100644 index 0000000..d7664d1 --- /dev/null +++ b/site/app/twirl/icon/trim.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-scissors"><rect width="20" height="20" x="2" y="2" rx="2"/><circle cx="8" cy="8" r="2"/><path d="M9.414 9.414 12 12"/><path d="M14.8 14.8 18 18"/><circle cx="8" cy="16" r="2"/><path d="m18 6-8.586 8.586"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/undo.svg b/site/app/twirl/icon/undo.svg new file mode 100644 index 0000000..0bc90dd --- /dev/null +++ b/site/app/twirl/icon/undo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-undo"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/verticalArrows.svg b/site/app/twirl/icon/verticalArrows.svg new file mode 100644 index 0000000..518673d --- /dev/null +++ b/site/app/twirl/icon/verticalArrows.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-move-vertical"><path d="M12 2v20"/><path d="m8 18 4 4 4-4"/><path d="m8 6 4-4 4 4"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/verticalFold.svg b/site/app/twirl/icon/verticalFold.svg new file mode 100644 index 0000000..a21f94b --- /dev/null +++ b/site/app/twirl/icon/verticalFold.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-fold-vertical"><path d="M12 22v-6"/><path d="M12 8V2"/><path d="M4 12H2"/><path d="M10 12H8"/><path d="M16 12h-2"/><path d="M22 12h-2"/><path d="m15 19-3-3-3 3"/><path d="m15 5-3 3-3-3"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/waves.svg b/site/app/twirl/icon/waves.svg new file mode 100644 index 0000000..5cccfbf --- /dev/null +++ b/site/app/twirl/icon/waves.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-waves"><path d="M2 6c.6.5 1.2 1 2.5 1C7 7 7 5 9.5 5c2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1"/><path d="M2 12c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1"/><path d="M2 18c.6.5 1.2 1 2.5 1 2.5 0 2.5-2 5-2 2.6 0 2.4 2 5 2 2.5 0 2.5-2 5-2 1.3 0 1.9.5 2.5 1"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/zoomIn.svg b/site/app/twirl/icon/zoomIn.svg new file mode 100644 index 0000000..deaf812 --- /dev/null +++ b/site/app/twirl/icon/zoomIn.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zoom-in"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="11" x2="11" y1="8" y2="14"/><line x1="8" x2="14" y1="11" y2="11"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/zoomOut.svg b/site/app/twirl/icon/zoomOut.svg new file mode 100644 index 0000000..0dab381 --- /dev/null +++ b/site/app/twirl/icon/zoomOut.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zoom-out"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="8" x2="14" y1="11" y2="11"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/icon/zoomSelection.svg b/site/app/twirl/icon/zoomSelection.svg new file mode 100644 index 0000000..76100e1 --- /dev/null +++ b/site/app/twirl/icon/zoomSelection.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-scan-search"><path d="M3 7V5a2 2 0 0 1 2-2h2"/><path d="M17 3h2a2 2 0 0 1 2 2v2"/><path d="M21 17v2a2 2 0 0 1-2 2h-2"/><path d="M7 21H5a2 2 0 0 1-2-2v-2"/><circle cx="12" cy="12" r="3"/><path d="m16 16-1.9-1.9"/></svg>
\ No newline at end of file diff --git a/site/app/twirl/notedata.json b/site/app/twirl/notedata.json new file mode 100644 index 0000000..696eae0 --- /dev/null +++ b/site/app/twirl/notedata.json @@ -0,0 +1 @@ +{"notes": [[0, "", 8.18],[1, "", 8.66],[2, "", 9.18],[3, "", 9.72],[4, "", 10.30],[5, "", 10.91],[6, "", 11.56],[7, "", 12.25],[8, "", 12.98],[9, "", 13.75],[10, "", 14.57],[11, "", 15.43],[12, "", 16.35],[13, "", 17.32],[14, "", 18.35],[15, "", 19.45],[16, "", 20.60],[17, "", 21.83],[18, "", 23.12],[19, "", 24.50],[20, "", 25.96],[21, "A0", 27.50],[22, "A#0/Bb0", 29.14],[23, "B0", 30.87],[24, "C1", 32.70],[25, "C#1/Db1", 34.65],[26, "D1", 36.71],[27, "D#1/Eb1", 38.89],[28, "E1", 41.20],[29, "F1", 43.65],[30, "F#1/Gb1", 46.25],[31, "G1", 49.00],[32, "G#1/Ab1", 51.91],[33, "A1", 55.00],[34, "A#1/Bb1", 58.27],[35, "B1", 61.74],[36, "C2", 65.41],[37, "C#2/Db2", 69.30],[38, "D2", 73.42],[39, "D#2/Eb2", 77.78],[40, "E2", 82.41],[41, "F2", 87.31],[42, "F#2/Gb2", 92.50],[43, "G2", 98.00],[44, "G#2/Ab2", 103.83],[45, "A2", 110.00],[46, "A#2/Bb2", 116.54],[47, "B2", 123.47],[48, "C3", 130.81],[49, "C#3/Db3", 138.59],[50, "D3", 146.83],[51, "D#3/Eb3", 155.56],[52, "E3", 164.81],[53, "F3", 174.61],[54, "F#3/Gb3", 185.00],[55, "G3", 196.00],[56, "G#3/Ab3", 207.65],[57, "A3", 220.00],[58, "A#3/Bb3", 233.08],[59, "B3", 246.94],[60, "C4", 261.63],[61, "C#4/Db4", 277.18],[62, "D4", 293.66],[63, "D#4/Eb4", 311.13],[64, "E4", 329.63],[65, "F4", 349.23],[66, "F#4/Gb4", 369.99],[67, "G4", 392.00],[68, "G#4/Ab4", 415.30],[69, "A4", 440.00],[70, "A#4/Bb4", 466.16],[71, "B4", 493.88],[72, "C5", 523.25],[73, "C#5/Db5", 554.37],[74, "D5", 587.33],[75, "D#5/Eb5", 622.25],[76, "E5", 659.26],[77, "F5", 698.46],[78, "F#5/Gb5", 739.99],[79, "G5", 783.99],[80, "G#5/Ab5", 830.61],[81, "A5", 880.00],[82, "A#5/Bb5", 932.33],[83, "B5", 987.77],[84, "C6", 1046.50],[85, "C#6/Db6", 1108.73],[86, "D6", 1174.66],[87, "D#6/Eb6", 1244.51],[88, "E6", 1318.51],[89, "F6", 1396.91],[90, "F#6/Gb6", 1479.98],[91, "G6", 1567.98],[92, "G#6/Ab6", 1661.22],[93, "A6", 1760.00],[94, "A#6/Bb6", 1864.66],[95, "B6", 1975.53],[96, "C7", 2093.00],[97, "C#7/Db7", 2217.46],[98, "D7", 2349.32],[99, "D#7/Eb7", 2489.02],[100, "E7", 2637.02],[101, "F7", 2793.83],[102, "F#7/Gb7", 2959.96],[103, "G7", 3135.96],[104, "G#7/Ab7", 3322.44],[105, "A7", 3520.00],[106, "A#7/Bb7", 3729.31],[107, "B7", 3951.07],[108, "C8", 4186.01],[109, "C#8/Db8", 4434.92],[110, "D8", 4698.64],[111, "D#8/Eb8", 4978.03],[112, "E8", 5274.04],[113, "F8", 5587.65],[114, "F#8/Gb8", 5919.91],[115, "G8", 6271.93],[116, "G#8/Ab8", 6644.88],[117, "A8", 7040.00],[118, "A#8/Bb8", 7458.62],[119, "B8", 7902.13],[120, "C9", 8372.02],[121, "C#9/Db9", 8869.84],[122, "D9", 9397.27],[123, "D#9/Eb9", 9956.06],[124, "E9", 10548.08],[125, "F9", 11175.30],[126, "F#9/Gb9", 11839.82],[127, "G9", 12543.85],[128, "G#9/Ab9", 13289.75]],"chords": [{"intervals": [0, 4, 8], "name": "Augmented"}, {"intervals": [0, 4, 7, 10, 2, 6], "name": "Augmented 11th"}, {"intervals": [0, 4, 8, 11], "name": "Augmented major 7th"}, {"intervals": [0, 4, 8, 10], "name": "Augmented 7th"}, {"intervals": [0, 6, 8], "name": "Augmented 6th"}, {"intervals": [0, 3, 6], "name": "Diminished"}, {"intervals": [0, 3, 6, 11], "name": "Diminished major 7th"}, {"intervals": [0, 3, 6, 9], "name": "Diminished 7th"}, {"intervals": [0, 4, 7], "name": "Dominant"}, {"intervals": [0, 4, 7, 10, 2, 5], "name": "Dominant 11th"}, {"intervals": [0, 4, 7, 10, 1], "name": "Dominant minor 9th"}, {"intervals": [0, 4, 7, 10, 2], "name": "Dominant 9th"}, {"intervals": [0, 3, 7], "name": "Dominant parallel"}, {"intervals": [0, 4, 7, 10], "name": "Dominant 7th"}, {"intervals": [0, 4, 6, 10], "name": "Dominant 7th b5"}, {"intervals": [0, 4, 7, 10, 2, 5, 9], "name": "Dominant 13th"}, {"intervals": [0, 5, 6, 7], "name": "Dream"}, {"intervals": [0, 7, 9, 1, 4], "name": "Elektra"}, {"intervals": [0, 8, 11, 4, 9], "name": "Farben"}, {"intervals": [0, 4, 7, 10], "name": "Harmonic 7th"}, {"intervals": [0, 4, 7, 10, 3], "name": "Augmented 9th"}, {"intervals": [0, 3, 6], "name": "Leading-tone"}, {"intervals": [0, 4, 7, 11, 6], "name": "Lydian"}, {"intervals": [0, 4, 7], "name": "Major"}, {"intervals": [0, 4, 7, 11, 2, 5], "name": "Major 11th"}, {"intervals": [0, 4, 7, 11], "name": "Major 7th"}, {"intervals": [0, 4, 7, 11, 6], "name": "Major 7th #11th"}, {"intervals": [0, 4, 7, 9], "name": "Major 6th"}, {"intervals": [0, 4, 7, 11, 2], "name": "Major 9th"}, {"intervals": [0, 4, 7, 11, 2, 6, 9], "name": "Major 13th"}, {"intervals": [0, 3, 7], "name": "Mediant"}, {"intervals": [0, 3, 7], "name": "Minor"}, {"intervals": [0, 3, 7, 10, 2, 5], "name": "Minor 11th"}, {"intervals": [0, 3, 7, 11], "name": "Minor major 7th"}, {"intervals": [0, 3, 7, 10, 2], "name": "Minor 9th"}, {"intervals": [0, 3, 7, 10], "name": "Minor 7th"}, {"intervals": [0, 3, 6, 10], "name": "Half-diminished 7th"}, {"intervals": [0, 3, 7, 9], "name": "Minor 6th"}, {"intervals": [0, 3, 7, 10, 2, 5, 9], "name": "Minor 13th"}, {"intervals": [0, 2, 4, 7], "name": "Mu"}, {"intervals": [0, 6, 10, 4, 9, 2], "name": "Mystic"}, {"intervals": [1, 5, 8], "name": "Neapolitan"}, {"intervals": [0, 4, 8, 10, 2], "name": "Ninth augmented 5th"}, {"intervals": [0, 4, 6, 10, 2], "name": "Ninth b5th"}, {"intervals": [1, 2, 8, 0, 3, 6, 7, 10, 11, 4, 7], "name": "Northern Lights"}, {"intervals": [0, 1, 4, 5, 8, 9], "name": "Napoleon hexachord"}, {"intervals": [0, 1, 4, 6, 7, 10], "name": "Petrushka"}, {"intervals": [0, 7], "name": "Power"}, {"intervals": [0, 3, 7], "name": "Psalms"}, {"intervals": [0, 4, 7], "name": "Secondary dominant"}, {"intervals": [0, 3, 6], "name": "Secondary leading-tone"}, {"intervals": [0, 3, 7], "name": "Secondary supertonic"}, {"intervals": [0, 4, 7, 9, 10], "name": "Seven six"}, {"intervals": [0, 4, 7, 10, 1], "name": "7th b9"}, {"intervals": [0, 5, 7, 10], "name": "7th suspension 4"}, {"intervals": [0, 4, 7, 9, 2], "name": "Sixth 9th"}, {"intervals": [0, 5, 7], "name": "Suspended"}, {"intervals": [0, 4, 7], "name": "Subdominant"}, {"intervals": [0, 3, 7], "name": "Subdominant parallel"}, {"intervals": [0, 3, 7], "name": "Submediant"}, {"intervals": [0, 4, 7], "name": "Subtonic"}, {"intervals": [0, 3, 7], "name": "Supertonic"}, {"intervals": [0, 5, 10, 3, 7], "name": "So What"}, {"intervals": [0, 4, 7, 10, 1, 9], "name": "Thirteenth b9th"}, {"intervals": [0, 4, 6, 10, 1, 9], "name": "Thirteenth b9th b5th"}, {"intervals": [0, 3, 7], "name": "Tonic counter parallel"}, {"intervals": [0, 4, 7], "name": "Tonic"}, {"intervals": [0, 3, 7], "name": "Tonic parallel"}, {"intervals": [0, 3, 6, 10], "name": "Tristan"}, {"intervals": [0, 1, 6], "name": "Viennese trichord 1"}, {"intervals": [0, 6, 7], "name": "Viennese trichord 2"}]}
\ No newline at end of file diff --git a/site/app/twirl/stdui.js b/site/app/twirl/stdui.js new file mode 100644 index 0000000..8141912 --- /dev/null +++ b/site/app/twirl/stdui.js @@ -0,0 +1,494 @@ +twirl.stdui = {
+ PlayButton: function(options) {
+ var self = this;
+ var txtPlay = "\u25b6";
+ var txtStop = "\u23f9";
+
+ this.state = false;
+
+ this.element = $("<p />").text(txtPlay).css("cursor", "pointer");
+
+ if (options.hasOwnProperty("fontsize")) {
+ this.element.css("font-size", options.fontsize);
+ }
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.element.click(function() {
+ if (!self.state) {
+ self.element.text(txtStop);
+ self.state = true;
+ } else {
+ self.element.text(txtPlay);
+ self.state = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(self.state, self);
+ }
+ if (options.hasOwnProperty("change")) {
+ options.change(self.state, self);
+ }
+ });
+
+ this.setValue = function(v, runChange) {
+ if (v) {
+ self.element.text(txtStop);
+ self.state = true;
+ } else {
+ self.element.text(txtPlay);
+ self.state = false;
+ }
+
+ if (runChange && options.hasOwnProperty("change")) {
+ options.change(self.state, self);
+ }
+ };
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(this.element);
+ }
+ },
+ StandardButton: function(options) {
+ var self = this;
+ this.element = $("<button />").addClass("smbut").text(options.label);
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.element.click(function(e) {
+ options.change(e);
+ });
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(this.element);
+ }
+ },
+ StandardToggle: function(options) {
+ var self = this;
+ var doChange = true;
+ this.element = $("<button />").addClass("smbut").attr(
+ "value",
+ options.hasOwnProperty("value") && options.value == 1 ? 1 : 0
+ ).text(options.label);
+
+ function setAppearance() {
+ var col;
+ if (self.element.attr("value") == 0) {
+ col = "#b5b01d";
+ } else {
+ col = "#f2e30c";
+ }
+ self.element.css("background-color", col);
+ };
+
+ setAppearance();
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.element.click(function() {
+ var val = (self.element.attr("value") == 0) ? 1 : 0;
+ self.element.attr("value", val);
+ setAppearance();
+ if (options.stateAlter) {
+ options.stateAlter(val, self);
+ }
+ if (doChange && options.hasOwnProperty("change")) {
+ options.change(val, self);
+ }
+ });
+
+ this.setValue = function(v, runChange) {
+ if (!runChange) {
+ doChange = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(v, self);
+ }
+ self.element.attr("value", v);
+ setAppearance();
+ if (runChange && options.hasOwnProperty("change")) {
+ options.change(v, self);
+ }
+ doChange = true;
+ };
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(this.element);
+ }
+ },
+ ComboBox: function(options) {
+ var self = this;
+ var doChange = true;
+ var tr = $("<tr />");
+ this.element = $("<select />");
+
+ for (var v in options.options) {
+ var val = (options.asValue) ? options.options[v] : v;
+ $("<option />").attr("value", val).text(options.options[v]).appendTo(self.element);
+ }
+
+ this.element.change(function() {
+ var val;
+ val = (options.asValue) ? self.element.find(":selected").text() : self.element.val();
+ if (options.stateAlter) {
+ options.stateAlter(val, self);
+ }
+ if (doChange && options.hasOwnProperty("change")) {
+ options.change(val, self);
+ }
+ });
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ tr.show();
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ tr.hide();
+ };
+
+ this.setValue = function(v, runChange) {
+ if (!runChange) {
+ doChange = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(v, self);
+ }
+ self.element.val(v);
+ doChange = true;
+ };
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ if (options.asRow) {
+ tr.appendTo($("#" + options.target));
+ var tdl = $("<td />").appendTo(tr);
+ if (options.label) tdl.addClass("transparentinput").text(options.label);
+ $("<td />").append(self.element).appendTo(tr);
+ $("<td />").appendTo(tr);
+ } else {
+ $("#" + options.target).append(self.element);
+ }
+ }
+ },
+ TextArea: function(options) {
+ var self = this;
+ this.element = $("<textarea />").css({
+ "background-color": "var(--codeBgColor)",
+ "color": "var(--codeFgColor)",
+ "font-size": "var(--codeFontSize)",
+ "font-family": "var(--codeFontFace)"
+ });
+
+ if (options.width) {
+ self.element.css("width", options.width);
+ }
+ if (options.height) {
+ self.element.css("height", options.height);
+ }
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.setValue = function(v) {
+ self.element.val(v);
+ };
+ if (options.target) {
+ $("#" + options.target).append(self.element);
+ }
+ },
+ TextInput: function(options) {
+ var self = this;
+ var doChange = true;
+ this.element = $("<input />").css({
+ "background-color": "var(--bgColor1)",
+ "color": "var(--fgColor1)"
+ });
+
+ if (options.css) {
+ self.element.css(options.css);
+ }
+
+ this.element.change(function() {
+ var val = self.element.val();
+ if (options.stateAlter) {
+ options.stateAlter(val, self);
+ }
+ if (doChange && options.hasOwnProperty("change")) {
+ options.change(val, self);
+ }
+ });
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.setValue = function(v, runChange) {
+ if (!runChange) {
+ doChange = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(v, self);
+ }
+ self.element.val(v);
+ if (runChange && options.hasOwnProperty("change")) {
+ options.change(v, self);
+ }
+ doChange = true;
+ };
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(this.element);
+ }
+ },
+ ColourInput: function(options) {
+ var self = this;
+ var doChange = true;
+ this.element = $("<input />").attr("type", "color");
+
+ if (options.css) {
+ self.element.css(options.css);
+ }
+
+ this.element.change(function() {
+ var val = self.element.val();
+ if (options.stateAlter) {
+ options.stateAlter(val, self);
+ }
+ if (doChange && options.hasOwnProperty("change")) {
+ options.change(val, self);
+ }
+ });
+
+ this.show = function() {
+ self.element.css("visibility", "visible");
+ };
+
+ this.hide = function() {
+ self.element.css("visibility", "hidden");
+ };
+
+ this.setValue = function(v, runChange) {
+ if (!runChange) {
+ doChange = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(v, self);
+ }
+ self.element.val(v);
+ if (runChange && options.hasOwnProperty("change")) {
+ options.change(v, self);
+ }
+ doChange = true;
+ };
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(this.element);
+ }
+ },
+ Slider: function(options) {
+ var self = this;
+ var doChange = true;
+ var label;
+ var tr = $("<tr />");
+
+ if (!options.hasOwnProperty("min")) {
+ options.min = 0;
+ }
+
+ if (!options.hasOwnProperty("max")) {
+ options.max = 1;
+ }
+
+ if (!options.hasOwnProperty("step")) {
+ options.step = 0.000001;
+ }
+
+ if (!options.hasOwnProperty("value")) {
+ options.value = 0;
+ }
+
+ if (!options.hasOwnProperty("size")) {
+ options.size = 64;
+ }
+
+ this.element = $("<input />")
+ .attr("type", "range")
+ .attr("min", options.min)
+ .attr("max", options.max)
+ .attr("step", options.step)
+ .attr("value", options.value)
+ .addClass("slider")
+ .addClass("transparentinput");
+
+ this.valueLabel = null;
+
+ this.show = function() {
+ tr.show();
+ };
+
+ this.hide = function() {
+ tr.hide();
+ };
+
+ var valueLabelUpdate = true;
+ if (options.hasOwnProperty("valueLabel") && options.valueLabel) {
+ self.valueLabel = $("<input />")
+ .attr("type", "number")
+ .attr("min", options.min)
+ .attr("max", options.max)
+ .attr("step", options.step)
+ .attr("value", options.value)
+ .addClass("transparentinput")
+ .val(options.value).change(function(){
+ valueLabelUpdate = false;
+ self.setValue($(this).val());
+ valueLabelUpdate = true;
+ });
+ }
+
+ function applyChange() {
+ var val = self.element.val();
+ if (options.stateAlter) {
+ options.stateAlter(val, self);
+ }
+ if (doChange && options.hasOwnProperty("change")) {
+ options.change(val, self);
+ }
+ if (self.valueLabel) {
+ self.valueLabel.val(val);
+ }
+ }
+
+ this.element.change(function() {
+ applyChange();
+ });
+
+ this.element.on("input", function() {
+ if (options.changeOnInput) {
+ return applyChange();
+ }
+ if (options.input) {
+ options.input(self.element.val(), self);
+ }
+ if (self.valueLabel) {
+ self.valueLabel.val(self.element.val());
+ }
+ });
+
+ this.setValue = function(v, runChange) {
+ if (!runChange) {
+ doChange = false;
+ }
+ if (options.stateAlter) {
+ options.stateAlter(v, self);
+ }
+ self.element.val(v);
+ if (runChange && options.hasOwnProperty("change")) {
+ options.change(v, self);
+ }
+ if (self.valueLabel && valueLabelUpdate) {
+ self.valueLabel.val(v);
+ };
+ doChange = true;
+ };
+
+
+ if (options.hasOwnProperty("label")) {
+ label = $("<p />").addClass("knoblabel").text(options.label);
+ }
+
+ var tdl = $("<td />").appendTo(tr);
+ if (label) tdl.append(label);
+
+ self.element.appendTo($("<td />").appendTo(tr));
+
+ var tdv = $("<td />").appendTo(tr);
+ if (self.valueLabel) tdv.append(self.valueLabel);
+
+ if (options.tooltip) {
+ this.element.on("mouseover", function(e){
+ twirl.tooltip.show(e, options.tooltip);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ if (options.target) {
+ $("#" + options.target).append(tr);
+ }
+ }
+}
\ No newline at end of file diff --git a/site/app/twirl/theme.css b/site/app/twirl/theme.css new file mode 100644 index 0000000..6f36a90 --- /dev/null +++ b/site/app/twirl/theme.css @@ -0,0 +1,284 @@ +@font-face {
+ font-family: "Chicago";
+ src: url("font/Chicago.woff") format("woff");
+ font-weight: 500;
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "Nouveau IBM";
+ src: url("font/Nouveau_IBM.woff") format("woff");
+ font-style: normal;
+ font-display: swap;
+ font-size: 12pt;
+}
+
+@font-face {
+ font-family: "National Park";
+ src: url("font/NationalPark-Regular.woff") format("woff");
+ font-style: normal;
+ font-display: swap;
+}
+
+@font-face {
+ font-family: "Josefin Sans";
+ src: url("font/JosefinSans.ttf") format("truetype");
+ font-style: normal;
+ font-display: swap;
+}
+
+html {
+ --fontFace: Chicago, Arial, sans-serif;
+ --fontSizeSmall: 11px;
+ --fontSizeDefault: 12px;
+ --fontSizeMedium: 14px;
+ --fontSizeLarge: 16px;
+ --bgColor1: #706b3b;
+ --bgColor2: #614d2c;
+ --bgColor3: #61594e;
+ --bgColor4: #806b4b;
+ --fgColor1: #f0b041;
+ --fgColor2: #e0a031;
+ --fgColor3: #db931f;
+ --menuBarBottomBorder: 1px solid #565656;
+ --tabSelectedBgColor: #453c2e;
+ --tabUnselectedBgColor: #292621;
+ --tabSelectedFgColor: #db931f;
+ --tabUnselectedFgColor: #a67b37;
+ --rowOddBgColor: #383137;
+ --rowEvenBgColor: #525049;
+ --buttonBorder: 1px solid #dba418;
+ --codeBgColor: #524320;
+ --codeFgColor: #f7b314;
+ --codeFontSize: 12pt;
+ --codeFontFace: "Nouveau IBM", courier, monospace;
+ --promptBgColor: #615c53;
+ --promptFontSize: 16px;
+ --promptShadow: 3px 3px rgba(0,0,0,0.2);
+ --promptBorder: 1px solid black;
+ --waveformOverlayColor: #4c464e;
+ --scrollbarColor: #e8bb54 #57451b;
+ --waveformPlayheadColor: #FF2222;
+ --waveformCoverColor: #232323;
+ --waveformCoverOpacity: 0.5;
+ --waveformMarkerColor: #edea2b;
+ --waveformMarkerRunnerColor: #919171;
+ --waveformCrossfadeWidth: 1px;
+ --waveformCrossfadeLineColor: #bfbfbf;
+ --waveformSelectOpacity: 0.5;
+ --waveformSelectColor: #772222;
+ --waveformLocationColor: #e0c496;
+ --waveformBgColor: #332b1f;
+ --waveformFgColor: #d18502;
+ --waveformGridColor: rgb(227, 206, 154, 0.2);
+ --waveformGridTextColor: rgb(240, 190, 65, 0.5);
+ --waveformChannelLineColor: rgb(87, 87, 87, 0.7);
+ --waveformTimeBarBgColor: #806b4b;
+ --waveformTimeBarFgColor: #f0b041;
+ --iconFilter: brightness(0) saturate(100%) invert(78%) sepia(77%) saturate(923%) hue-rotate(334deg) brightness(89%) contrast(88%);
+}
+
+html.themeBasic {
+ --fontFace: "Josefin Sans", Arial, sans-serif;
+ --fontSizeSmall: 10pt;
+ --fontSizeDefault: 11pt;
+ --fontSizeMedium: 14pt;
+ --fontSizeLarge: 16pt;
+ --bgColor1: #a1a1cf;
+ --bgColor2: #9898a8;
+ --bgColor3: #8989b1;
+ --bgColor4: #bdbdff;
+ --fgColor1: #000000;
+ --fgColor2: #555555;
+ --fgColor3: #343445;
+ --menuBarBottomBorder: 1px solid #bdbdbd;
+ --tabSelectedBgColor: #7878bd;
+ --tabUnselectedBgColor: #5656aa;
+ --tabSelectedFgColor: #000000;
+ --tabUnselectedFgColor: #777777;
+ --rowOddBgColor: #a9a9c9;
+ --rowEvenBgColor: #9999a9;
+ --buttonBorder: 1px solid #343434;
+ --codeBgColor: #9999ff;
+ --codeFgColor: #121212;
+ --codeFontSize: 12pt;
+ --codeFontFace: courier, monospace;
+ --promptBgColor: #8585ff;
+ --promptFontSize: 12pt;
+ --promptShadow: 3px 3px rgba(0,0,50,0.3);
+ --promptBorder: 1px solid #5555aa;
+ --waveformOverlayColor: #4c464e;
+ --scrollbarColor: #ffffff #444499;
+ --waveformPlayheadColor: #FF2222;
+ --waveformCoverColor: #232323;
+ --waveformCoverOpacity: 0.5;
+ --waveformMarkerColor: #edea2b;
+ --waveformMarkerRunnerColor: #919171;
+ --waveformCrossfadeWidth: 1px;
+ --waveformCrossfadeLineColor: #3434ff;
+ --waveformSelectOpacity: 0.5;
+ --waveformSelectColor: #772222;
+ --waveformLocationColor: #000000;
+ --waveformBgColor: #fcf6de;
+ --waveformFgColor: #222266;
+ --waveformGridColor: rgb(0, 0, 0, 0.2);
+ --waveformGridTextColor: rgb(0, 0, 0, 0.5);
+ --waveformChannelLineColor: rgb(0, 0, 0, 0.7);
+ --waveformTimeBarBgColor: #ffffff;
+ --waveformTimeBarFgColor: #000000;
+ --iconFilter: invert(17%) sepia(31%) saturate(2452%) hue-rotate(208deg) brightness(96%) contrast(88%);
+}
+
+html.themeHacker {
+ --fontFace: "Nouveau IBM", monospace, Courier, sans-serif;
+ --fontSizeSmall: 10pt;
+ --fontSizeDefault: 12pt;
+ --fontSizeMedium: 14pt;
+ --fontSizeLarge: 16pt;
+ --bgColor1: #323232;
+ --bgColor2: #434343;
+ --bgColor3: #010101;
+ --bgColor4: #344534;
+ --fgColor1: #44ee44;
+ --fgColor2: #66cc66;
+ --fgColor3: #009900;
+ --menuBarBottomBorder: 1px solid #bbbbbb;
+ --tabSelectedBgColor: #454545;
+ --tabUnselectedBgColor: #232323;
+ --tabSelectedFgColor: #44bb44;
+ --tabUnselectedFgColor: #229922;
+ --rowOddBgColor: #232323;
+ --rowEvenBgColor: #343434;
+ --buttonBorder: none;
+ --codeBgColor: #000000;
+ --codeFgColor: #0000ab;
+ --codeFontSize: 12pt;
+ --codeFontFace: "Nouveau IBM", courier, monospace;
+ --promptBgColor: #000000;
+ --promptFontSize: 14pt;
+ --promptShadow: 5px 5px rgba(0,50,0,0.2);
+ --promptBorder: 1px solid white;
+ --waveformOverlayColor: #4c464e;
+ --scrollbarColor: #000000 #005500;
+ --waveformPlayheadColor: #FF2222;
+ --waveformCoverColor: #232323;
+ --waveformCoverOpacity: 0.5;
+ --waveformMarkerColor: #ed2bed;
+ --waveformMarkerRunnerColor: #545454;
+ --waveformCrossfadeWidth: 1px;
+ --waveformCrossfadeLineColor: #989898;
+ --waveformSelectOpacity: 0.5;
+ --waveformSelectColor: #227722;
+ --waveformLocationColor: #000000;
+ --waveformBgColor: #121212;
+ --waveformFgColor: #00aa00;
+ --waveformGridColor: rgb(90, 90, 90, 0.2);
+ --waveformGridTextColor: rgb(120, 170, 120, 0.5);
+ --waveformChannelLineColor: rgb(120, 120, 120, 0.7);
+ --waveformTimeBarBgColor: #446644;
+ --waveformTimeBarFgColor: #000000;
+ --iconFilter: invert(41%) sepia(18%) saturate(1917%) hue-rotate(62deg) brightness(104%) contrast(90%);
+}
+
+html.themeMonoclassic {
+ --fontFace: Chicago, Arial, sans-serif;
+ --fontSizeSmall: 11px;
+ --fontSizeDefault: 12px;
+ --fontSizeMedium: 14px;
+ --fontSizeLarge: 16px;
+ --bgColor1: #ffffff;
+ --bgColor2: #eeeeee;
+ --bgColor3: #dddddd;
+ --bgColor4: #cccccc;
+ --fgColor1: #000000;
+ --fgColor2: #111111;
+ --fgColor3: #222222;
+ --menuBarBottomBorder: 1px solid #000000;
+ --tabSelectedBgColor: #ffffff;
+ --tabUnselectedBgColor: #cccccc;
+ --tabSelectedFgColor: #000000;
+ --tabUnselectedFgColor: #555555;
+ --rowOddBgColor: #ffffff;
+ --rowEvenBgColor: #eeeeee;
+ --buttonBorder: 1px solid #000000;
+ --codeBgColor: #ffffff;
+ --codeFgColor: #000000;
+ --codeFontSize: 12pt;
+ --codeFontFace: "Nouveau IBM", courier, monospace;
+ --promptBgColor: #ffffff;
+ --promptFontSize: 16px;
+ --promptShadow: 3px 3px rgba(0,0,0,0.2);
+ --promptBorder: 1px solid black;
+ --waveformOverlayColor: #bbbbbb;
+ --scrollbarColor: #000000 #ffffff;
+ --waveformPlayheadColor: #000000;
+ --waveformCoverColor: #dddddd;
+ --waveformCoverOpacity: 0.5;
+ --waveformMarkerColor: #444444;
+ --waveformMarkerRunnerColor: #dddddd;
+ --waveformCrossfadeWidth: 1px;
+ --waveformCrossfadeLineColor: #333333;
+ --waveformSelectOpacity: 0.5;
+ --waveformSelectColor: #666666;
+ --waveformLocationColor: #111111;
+ --waveformBgColor: #ffffff;
+ --waveformFgColor: #000000;
+ --waveformGridColor: rgb(20, 20, 20, 0.2);
+ --waveformGridTextColor: rgb(20, 10, 20, 0.5);
+ --waveformChannelLineColor: rgb(10, 10, 10, 0.7);
+ --waveformTimeBarBgColor: #dddddd;
+ --waveformTimeBarFgColor: #444444;
+ --iconFilter: none;
+}
+
+html.themeDoze {
+ --fontFace: "Trebuchet MS", Arial, sans-serif;
+ --fontSizeSmall: 8pt;
+ --fontSizeDefault: 10pt;
+ --fontSizeMedium: 14pt;
+ --fontSizeLarge: 16pt;
+ --bgColor1: #8f8f8f;
+ --bgColor2: #7f7f7f;
+ --bgColor3: #6f6f6f;
+ --bgColor4: #5f5f5f;
+ --fgColor1: #000000;
+ --fgColor2: #171717;
+ --fgColor3: #212121;
+ --menuBarBottomBorder: 1px solid #000000;
+ --tabSelectedBgColor: #acacac;
+ --tabUnselectedBgColor: #6a6a6a;
+ --tabSelectedFgColor: #000000;
+ --tabUnselectedFgColor: #555555;
+ --rowOddBgColor: #acacac;
+ --rowEvenBgColor: #919191;
+ --buttonBorder: 1px solid #767676;
+ --codeBgColor: #000000;
+ --codeFgColor: #f5d151;
+ --codeFontSize: 12pt;
+ --codeFontFace: "Nouveau IBM", courier, monospace;
+ --promptBgColor: #8f8f8f;
+ --promptFontSize: 16pt;
+ --promptShadow: 6px 6px rgba(0,0,0,0.2);
+ --promptBorder: 1px solid #707070;
+ --waveformOverlayColor: #bbbbbb;
+ --scrollbarColor: #949494 #c2c2c2;
+ --waveformPlayheadColor: #bb0000;
+ --waveformCoverColor: #dddddd;
+ --waveformCoverOpacity: 0.5;
+ --waveformMarkerColor: #f0c93e;
+ --waveformMarkerRunnerColor: #9e8e55;
+ --waveformCrossfadeWidth: 1px;
+ --waveformCrossfadeLineColor: #79a1b0;
+ --waveformSelectOpacity: 0.5;
+ --waveformSelectColor: #eff77c;
+ --waveformLocationColor: #bb0000;
+ --waveformBgColor: #2c304d;
+ --waveformFgColor: #485ce0;
+ --waveformGridColor: rgb(20, 20, 20, 0.2);
+ --waveformGridTextColor: rgb(20, 10, 20, 0.5);
+ --waveformChannelLineColor: rgb(10, 10, 10, 0.7);
+ --waveformTimeBarBgColor: #949494;
+ --waveformTimeBarFgColor: #c2c2c2;
+ --iconFilter: none;
+}
\ No newline at end of file diff --git a/site/app/twirl/transform.js b/site/app/twirl/transform.js new file mode 100644 index 0000000..1feff51 --- /dev/null +++ b/site/app/twirl/transform.js @@ -0,0 +1,1212 @@ +twirl.transform = {};
+twirl.transform.Parameter = function(options) {
+ var self = this;
+ var instr = options.instrument;
+ var tDefinition = options.definition;
+ var parent = options.parent;
+ var transform = options.transform;
+ var host = options.host;
+ var onChange;
+ var refreshable = false;
+ var changeFunc;
+ var initval = true;
+ var definition = {};
+ var randomiseAllowed = true;
+ var visible = true;
+ var uniqueTransformID = (options.transform) ? options.transform.uniqueID : "";
+ if (parent) {
+ Object.assign(definition, tDefinition);
+ } else {
+ definition = tDefinition;
+ }
+
+ if (options.onChange || definition.onChange) {
+ onChange = function(val) {
+ if (options.onChange) options.onChange(val);
+ if (definition.onChange) definition.onChange(val);
+ }
+ }
+
+ if (definition.hasOwnProperty("preset")) {
+ var save = {};
+ for (var s of ["dfault", "name", "channel", "automatable", "description"]) {
+ if (definition.hasOwnProperty(s)) {
+ save[s] = definition[s];
+ }
+ }
+
+ if (definition.preset == "amp") {
+ Object.assign(definition, {name: "Amplitude", channel: "amp", description: "Amplitude", dfault: 1, min: 0, max: 1});
+ } else if (definition.preset == "pvslock") {
+ Object.assign(definition, {name: "Peak lock", channel: "pvslock", description: "Lock frequencies around peaks", min: 0, max: 1, step: 1, dfault: 0});
+ } else if (definition.preset == "fftsize") {
+ Object.assign(definition, {name: "FFT size", channel: "fftsize", description: "FFT size", options: [256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65535], dfault: 2, asvalue: true, automatable: false, lagHint: -1});
+ } else if (definition.preset == "wave") {
+ Object.assign(definition, {name: "Wave", description: "Wave shape to use", options: ["Sine", "Square", "Saw", "Pulse", "Triangle"], dfault: 0, channel: "wave"});
+ } else if (definition.preset == "wintype") {
+ Object.assign(definition, {name: "Window type", channel: "wintype", description: "Window shape", options: ["Hanning", "Hamming", "Half sine"], dfault: 0, automatable: false});
+
+ } else if (definition.preset == "instanceloop") {
+ Object.assign(definition, {name: "Cross instance loop type", channel: "otlooptype", description: "Loop type of other instance", options: ["None", "Forward", "Backward", "Ping-pong"], dfault: 0});
+
+ } else if (definition.preset == "note") {
+ var notes = {};
+ for (var i = 21; i < 128; i++) {
+ var v = twirl.noteData.data.notes[i];
+ notes[v[0]] = v[1];
+ }
+ Object.assign(definition, {name: "Note", channel: "note", description: "Note to use", options: notes, dfault: 69, automatable: true});
+ } else if (definition.preset == "instance") {
+ var c = (!definition.channel) ? "ot" : definition.channel;
+ initval = false;
+ if (transform) transform.refreshable = true;
+ refreshable = true;
+ Object.assign(definition, {
+ name: "Instance", description: "Other wave to use", channel: "instance",
+ options: options.otherInstanceNamesFunc(),
+ automatable: false
+ });
+ changeFunc = function(index) {
+ var oif = options.instancesFunc();
+ if (!oif[index]) return;
+ var s = oif[index].selected;
+ app.setControlChannel(instr + "_" + "inststart" + uniqueTransformID, s[0]);
+ app.setControlChannel(instr + "_" + "instend" + uniqueTransformID, s[1]);
+ app.setControlChannel(instr + "_" + "instchan" + uniqueTransformID, s[2]);
+ };
+ }
+ if (save) {
+ Object.assign(definition, save);
+ }
+ } // if preset
+
+ if (definition.channel == "applymode" || definition.noRandomisation) {
+ randomiseAllowed = false;
+ }
+
+ var type;
+
+ if (definition.hasOwnProperty("conditions") && !parent) {
+ refreshable = true;
+ if (transform) transform.refreshable = refreshable;
+ }
+
+ var channel = "";
+ if (!definition.hasOwnProperty("absolutechannel")) {
+ channel = (parent) ? parent.sendChannel : instr + "_";
+ }
+
+ if (definition.hasOwnProperty("channel")) {
+ channel += definition.channel;
+ } else {
+ channel += definition.name.toLowerCase();
+ }
+
+ this.sendChannel = channel;
+ if (!parent) {
+ this.sendChannel += uniqueTransformID;
+ }
+ var elContainer = $("<div />");
+ var elValueLabel = $("<div />");
+ var elValueInput;
+ var elModulations;
+ var elInput;
+ var elRow;
+ var elModSelect;
+ var automation = [];
+
+ this.definition = definition;
+ this.modulation = null;
+ this.automation = null;
+ this.channel = channel;
+ this.modulationParameters = null;
+
+ this.setPlaying = async function(state) {
+ if (definition.automatable || definition.hidden) return;
+
+ if (definition.disableOnPlay) {
+ if (elValueInput) {
+ elValueInput.prop("disabled", state);
+ elValueInput.css("opacity", (state) ? 0.8 : 1);
+ }
+
+ if (elInput) {
+ elInput.prop("disabled", state);
+ elInput.css("opacity", (state) ? 0.8 : 1);
+ }
+ } else {
+ if (state) {
+ var text = "Changes will be applied upon next run";
+ elContainer.on("mouseover", function(event){
+ twirl.tooltip.show(event, text);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ } else {
+ elContainer.off("mouseover").off("mouseout");
+ }
+ }
+ };
+
+
+ if (!definition.hasOwnProperty("hidden")) {
+ definition.hidden = false;
+ }
+
+ if (!definition.step) {
+ definition.step = 0.0000001;
+ }
+
+ if (definition.min == null) {
+ definition.min = 0;
+ }
+
+ if (definition.max == null) {
+ definition.max = 1;
+ }
+
+ if (!definition.hasOwnProperty("fireChanges")) {
+ definition.fireChanges = true;
+ }
+
+ if (definition.dfault == null) {
+ definition.dfault = 1;
+ }
+
+ if (parent) {
+ if (definition.hostrange) {
+ var items = ["step", "min", "max", "options", "conditions", "hostrange"];
+ if (definition.dfault == "hostrangemin") {
+ definition.dfault = parent.definition.min;
+ } else if (definition.dfault == "hostrangemax") {
+ definition.dfault = parent.definition.max;
+ } else {
+ items.push("dfault");
+ }
+ for (let o of items) {
+ if (parent.definition.hasOwnProperty(o)) {
+ definition[o] = parent.definition[o];
+ }
+ }
+ } else if (definition.preset == "hostrangemin") {
+ definition.min = definition.max = definition.dfault = parent.definition.min;
+ } else if (definition.preset == "hostrangemax") {
+ definition.min = definition.max = definition.dfault = parent.definition.max;
+ }
+ }
+
+ if (definition.options) {
+ type = "select";
+ definition.min = 0;
+ definition.max = definition.options.length - 1;
+ definition.step = 1;
+ } else if (definition.hasOwnProperty("type")) {
+ type = definition.type;
+ } else if (definition.min == 0 && definition.max == 1 && definition.step == 1) {
+ type = "checkbox";
+ } else {
+ type = "range";
+ }
+
+ if (!definition.hasOwnProperty("automatable")) {
+ definition.automatable = ((type == "range" || type == "checkbox") && !parent);
+ }
+
+ this.getLagHint = function() {
+ if (!definition.lagHint || !visible) return;
+ var lagHint;
+ if (typeof(definition.lagHint) == "object") {
+ lagHint = "setting <i>" + definition.name + "</i> to <i>"
+ + definition.options[definition.lagHint.option] + "</i>";
+ } else {
+ lagHint = ((definition.lagHint < 0) ? "reducing" : "increasing")
+ + " <i>" + definition.name + "</i>";
+ }
+ return lagHint;
+ };
+
+ this.setRawValue = function(val) {
+ if (type == "checkbox") {
+ elInput[0].checked = (val == 0) ? false : true;
+ } else {
+ elInput.val(val);
+ }
+ elInput.trigger("change");
+ }
+
+ this.getRawValue = function() {
+ return elInput.val();
+ }
+
+ this.getValue = function() {
+ var val;
+ if (type == "range" || type == "string") {
+ val = elInput.val();
+ } else if (type == "select") {
+ val = (definition.asvalue) ? elInput.find("option:selected").text() : elInput.val();
+ } else if (type == "checkbox") {
+ val = (elInput[0].checked) ? 1 : 0;
+ }
+ return val;
+ };
+
+ this.reset = function() {
+ self.setRawValue(definition.dfault);
+ if (!options.unmanagedAutomation) {
+ if (automationActive) disableAutomation();
+ if (self.automation) {
+ delete self.automation;
+ self.automation = null;
+ }
+ if (elSpline) {
+ elSpline.remove();
+ delete elSpline;
+ }
+ }
+ if (modulationShown && !options.unmanagedModulation) {
+ hideModulations();
+ }
+ };
+
+ this.randomise = function() {
+ if (!randomiseAllowed) return;
+ var val;
+ if (!options.unmanagedModulation && definition.automatable) {
+ if (Math.random() >= 0.5) {
+ modButton.el.click();
+ }
+ }
+
+ if (type == "select") {
+ val = Math.round(Math.random() * (definition.options.length - 1));
+ } else if (type == "range") {
+ val = (Math.random() * (definition.max - definition.min)) + definition.min;
+ if (definition.step == 1) {
+ val = Math.round(val);
+ } else {
+ val = Math.ceil((val - definition.min) / definition.step) * definition.step + definition.min;
+ }
+ } else if (type = "checkbox") {
+ val = (Math.round(Math.random()));
+ }
+ self.setRawValue(val);
+
+ if (self.modulationParameters && !options.unmanagedModulation) {
+ // 4 = just the non-crossadaptive ones
+ elModSelect.val(Math.round(Math.random() * 4)).trigger("change");
+ for (let mp in self.modulationParameters) {
+ self.modulationParameters[mp].randomise();
+ }
+ }
+ };
+
+
+ this.refresh = function() {
+ if (!refreshable || !transform) {
+ return;
+ }
+ if (definition.preset == "instance") {
+ createSelectOptions(elInput, options.otherInstanceNamesFunc(), true);
+ }
+ for (var k in definition.conditions) {
+ var c = definition.conditions[k];
+ var chan = (c.absolutechannel) ? c.channel : transform.instr + "_" + c.channel;
+ var val = transform.parameters[chan].getValue();
+ if (
+ (c.operator == "eq" && val != c.value) ||
+ (c.operator == "neq" && val == c.value) ||
+ (c.operator == "lt" && val >= c.value) ||
+ (c.operator == "gt" && val <= c.value) ||
+ (c.operator == "le" && val > c.value) ||
+ (c.operator == "ge" && val < c.value)
+ ) {
+ visible = false;
+ app.setControlChannel(self.sendChannel, definition.dfault);
+ return elRow.hide();
+ }
+ }
+ // app.setControlChannel(self.sendChannel, self.getValue());
+ visible = true;
+ elRow.show();
+ };
+
+ function createSelectOptions(elSelect, options, sendValue) {
+ var selected = elInput.val();
+ elSelect.empty();
+ var applied;
+ var firstOption;
+ for (var x in options) {
+ if (!firstOption) firstOption = x;
+ var opt = $("<option />").text(options[x]).val(x).appendTo(elSelect);
+ if (x == selected) {
+ opt.attr("selected", "1");
+ if (changeFunc) changeFunc(x);
+ applied = true;
+ }
+ }
+ if (!applied) {
+ elInput.val(firstOption);
+ if (changeFunc) changeFunc(firstOption);
+ }
+ if (sendValue) {
+ app.setControlChannel(self.sendChannel, self.getValue());
+ }
+ definition.min = 0;
+ definition.max = (Array.isArray(options)) ? options.length - 1 : Object.keys(options).length - 1;
+ }
+
+ function updateLabel() {
+ if (elValueInput) {
+ var val = self.getValue();
+ updateinput = false;
+ rounding = 10000;
+ val = Math.round(val * rounding) / rounding;
+ elValueInput.val(val);
+ updateinput = true;
+ }
+ }
+
+ if (type == "select") {
+ elInput = $("<select />");
+ elInput.change(function(){
+ var val = self.getValue();
+ if (transform) transform.refresh();
+ if (definition.fireChanges) {
+ if (changeFunc) changeFunc(val);
+ if (!host.offline) app.setControlChannel(self.sendChannel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+
+ var selectOptions = (definition.hostrange && parent) ? parent.definitions.options : definition.options;
+ createSelectOptions(elInput, selectOptions);
+
+ } else if (type == "string") {
+ elInput = $("<input />").change(function() {
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges) {
+ app.setStringChannel(self.sendChannel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+
+ } else if (type == "checkbox") {
+ elInput = $("<input />").addClass("twirl_checkbox").attr("type", "checkbox").on("change", function() {
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges) {
+ app.setControlChannel(self.sendChannel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+ } else if (type == "range") {
+ var updateinput = true;
+ var max = definition.max;
+ var min = definition.min;
+ var step = definition.step;
+ var dfault = definition.dfault;
+
+ elInput = $("<input />").addClass("twirl_slider").attr("type", "range").on("input", function() {
+ updateLabel();
+ if (definition.fireChanges) {
+ app.setControlChannel(self.sendChannel, self.getValue());
+ }
+ }).change(function() {
+ updateLabel();
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges && !host.offline) {
+ app.setControlChannel(self.sendChannel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ }).attr("min", min).attr("max", max).attr("step", step).val(dfault);
+
+ elValueInput = $("<input />").attr("type", "number").attr("min", min).attr("max", max).attr("step", step).addClass("twirl_transparentinput").appendTo(elValueLabel).change(function() {
+ if (updateinput) {
+ elInput.val($(this).val()).trigger("change").trigger("input");
+ }
+ });
+ }
+ /*
+ elInput.on("contextmenu", function(e){
+ var items = [{name: "Reset", click: function(){
+ self.reset();
+ }}];
+ if (definition.automatable) {
+ items.push({
+ name: "Automate",
+ click: function(){
+ if (!options.unmanagedAutomation) {
+ transform.showAutomation(definition.name, elSpline);
+ }
+ }
+ });
+ }
+
+ items.push({
+ name: "Randomise",
+ click: function(){
+ self.randomise();
+ }
+ });
+
+ items.push({
+ name: ((randomiseAllowed) ? "Exclude from" : "Include in") + " randomisation",
+ click: randomiseButton.click
+ });
+
+ twirl.contextMenu.show(e, items);
+ });*/
+
+ elContainer.append(elInput);
+ if (initval) {
+ self.setRawValue(definition.dfault);
+ if (definition.fireChanges) {
+ elInput.trigger("change");
+ }
+ }
+
+
+ this.setDefault = function() {
+ elInput.val(definition.dfault).trigger("change");
+ //app.setControlChannel(sendChannel, definition.dfault);
+ };
+
+ this.remove = function() {
+ disableAutomation();
+ elRow.remove();
+ if (elSpline) {
+ elSpline.remove();
+ }
+ if (self.modulation) {
+ self.modulation = null;
+ }
+
+ if (self.automation) {
+ self.automation = null;
+ }
+ };
+
+ this.getAutomationData = function(start, end) {
+ if (self.modulation) {
+ var m = twirl.appdata.modulations[self.modulation];
+ return {type: "modulation", data: [m.instr, self.sendChannel]};
+ } else if (automationActive && self.automation) {
+ return {type: "automation", channel: self.sendChannel, data: self.automation.getLinsegData(start, end, options.getRegionFunc())};
+ }
+ };
+
+ var resetButton = twirl.createIcon({
+ label: "Reset parameter",
+ icon: "reset",
+ click: function() {
+ self.reset();
+ }
+ });
+
+ var randomiseButton = twirl.createIcon({
+ label: "Include in randomisation",
+ icon: "randomise",
+ click: function(obj) {
+ randomiseAllowed = !randomiseAllowed;
+ var opacity = (randomiseAllowed) ? 1 : 0.4;
+ obj.el.css("opacity", opacity);
+ }
+ });
+ if (!randomiseAllowed) {
+ randomiseButton.el.css("opacity", 0.4);
+ }
+
+ var elSpline;
+ var editAutomationButton = twirl.createIcon({
+ label: "Select automation",
+ icon: "show",
+ click: function() {
+ if (!transform) return;
+ if (elSpline) {
+ automationShown = true;
+ transform.showAutomation(definition.name, elSpline);
+ }
+ }
+ });
+ editAutomationButton.el.hide();
+
+ var automationButton = twirl.createIcon({
+ label: "Automate",
+ label2: "Close automation",
+ icon: "automate",
+ icon2: "close",
+ click: function() {
+ if (elSpline && automationActive) {
+ disableAutomation();
+ if (options.onAutomationClick) options.onAutomationClick(false);
+ } else {
+ showAutomation();
+ if (options.onAutomationClick) options.onAutomationClick(true);
+ }
+ }
+ });
+
+ var automationActive = false;
+ var automationShown = false;
+
+ this.hideAutomation = function() {
+ if (!transform) return;
+ automationShown = false;
+ if (elSpline) {
+ transform.hideAutomation(definition.name);
+ }
+ }
+
+ function disableAutomation() {
+ if (!transform) return;
+ automationActive = false;
+ automationShown = false;
+ if (!host.offline) app.setControlChannel(self.sendChannel, self.getValue());
+ elValueLabel.show();
+ elInput.show();
+ modButton.el.show();
+ automationButton.setState(true);
+ editAutomationButton.el.hide();
+ self.hideAutomation();
+ }
+
+ this.redraw = function(region) {
+ if (self.automation && !options.unmanagedAutomation) {
+ if (region && region[0] != null && region[1] != null) {
+ self.automation.setRange(region[0], region[1]);
+ } else {
+ self.automation.redraw();
+ }
+ }
+ };
+
+ this.createAutomationSpline = function(elTarget, colour) {
+ if (!colour) colour = twirl.random.rgbColour();
+ if (!self.automation) {
+ self.automation = new SplineEdit(
+ elTarget, colour,
+ options.getDurationFunc,
+ [definition.min, definition.max, self.getValue(), definition.step],
+ definition.name
+ );
+ }
+ };
+
+ function showAutomation() {
+ if (!transform) return;
+ var colour = twirl.random.rgbColour();
+ automationShown = true;
+ automationActive = true;
+
+ if (!elSpline) {
+ elSpline = $("<div />").attr("id", "spl_" + channel).css({
+ position: "absolute", width: "100%", height: "100%", overflow: "hidden"
+ });
+ }
+
+ transform.showAutomation(definition.name, elSpline);
+ self.createAutomationSpline(elSpline, colour);
+
+
+ elValueLabel.hide();
+ elInput.hide();
+ modButton.el.hide();
+ elSpline.show();
+ editAutomationButton.el.show(); //.css("background-color", colour);
+ automationButton.setState(false);
+ }
+
+
+ elModulations = $("<div />").addClass("twirl_tf_container").hide().appendTo(elContainer);
+ var modulationShown = false;
+
+
+ var modButton = twirl.createIcon({
+ label: "Modulate",
+ label2: "Close modulation",
+ icon: "modulate",
+ icon2: "close",
+ click: function() {
+ if (elModulations && modulationShown) {
+ hideModulations();
+ } else {
+ showModulations();
+ }
+ }
+ });
+
+ function hideModulations() {
+ app.setControlChannel(self.sendChannel, self.getValue());
+ modulationShown = false;
+ elValueLabel.show();
+ elInput.show();
+ automationButton.el.show();
+ self.modulation = null;
+ modButton.setState(true);
+ if (elModulations) {
+ elModulations.hide();
+ }
+ }
+
+ function showModulations() {
+ if (!transform) return;
+ modulationShown = true;
+ elValueLabel.hide();
+ elInput.hide();
+ automationButton.el.hide();
+ elModulations.show();
+ modButton.setState(false);
+ if (elModulations.children().length != 0) {
+ elModSelect.val(0).trigger("change");
+ return;
+ }
+ var tb = $("<tbody />");
+ function buildModulation(i) {
+ tb.empty();
+ self.modulationParameters = {};
+ self.modulation = i;
+ let m = twirl.appdata.modulations[i];
+ for (let x of m.parameters) {
+ var tp = new twirl.transform.Parameter({
+ instrument: m.instr,
+ definition: x,
+ transform: transform,
+ parent: self,
+ onAutomationClick: options.onAutomationClick,
+ getDurationFunc: options.getDurationFunc,
+ getRegionFunc: options.getRegionFunc,
+ otherInstanceNamesFunc: options.otherInstanceNamesFunc,
+ instancesFunc: options.instancesFunc,
+ host: options.host
+ });
+ self.modulationParameters[tp.channel] = tp;
+ tb.append(tp.getElementRow(true)); // hmm modulate the modulation with false
+ }
+ }
+ var selecttb = $("<tbody />").appendTo($("<table />)").appendTo(elModulations));
+ var row = $("<tr />").append($("<td />").addClass("twirl_tf_cell_text").text("Modulation type")).appendTo(selecttb);
+ var elConditionalOptions = [];
+
+ if (host.onInstanceChangeds) {
+ host.onInstanceChangeds.push(function(){
+
+ for (let o of elConditionalOptions) {
+ if (options.instancesFunc().length == 1) {
+ o.prop("disabled", true);
+ } else {
+ o.prop("disabled", false);
+ }
+ }
+ });
+ }
+
+ elModSelect = $("<select />").change(function() {
+ self.modulation = $(this).val();
+ buildModulation(self.modulation);
+ }).appendTo($("<td />").appendTo(row));
+ $("<table />").append(tb).appendTo(elModulations);
+
+ for (let i in twirl.appdata.modulations) {
+ var m = twirl.appdata.modulations[i];
+ var o = $("<option />").text(m.name).val(i).appendTo(elModSelect);
+ if (m.inputs > 1) {
+ elConditionalOptions.push(o);
+ if (!options.instancesFunc || options.instancesFunc().length == 1) {
+ o.prop("disabled", true);
+ }
+ }
+ }
+ elModSelect.val(0).trigger("change");
+ }
+
+ this.getElementRow = function(nocontrols) {
+ if (definition.hidden) {
+ return null;
+ };
+ if (elRow) {
+ return elRow;
+ }
+ elRow = $("<tr />");
+ var name = $("<td />").addClass("twirl_tf_cell_text").text(definition.name).appendTo(elRow);
+ if (definition.description) {
+ name.on("mouseover", function(event){
+ twirl.tooltip.show(event, definition.description);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ $("<td />").addClass("twirl_tf_cell").append(elContainer).appendTo(elRow);
+ $("<td />").addClass("twirl_tf_cellfixed").append(elValueLabel).appendTo(elRow);
+ if (!nocontrols) {
+ for (let b of [resetButton, randomiseButton]) $("<td />").addClass("twirl_tf_cell_plainbg").append(b.el).appendTo(elRow);
+
+ if (definition.automatable) {
+ var items = [];
+ if (!options.unmanagedAutomation) {
+ items.push(automationButton);
+ items.push(editAutomationButton);
+ }
+ if (!options.unmanagedModulation) {
+ items.push(modButton);
+ }
+ for (let b of items) $("<td />").addClass("twirl_tf_cell_plainbg").append(b.el).appendTo(elRow);
+ }
+
+ }
+ return elRow;
+ };
+};
+
+
+
+twirl.transform.Transform = function(options) {
+ var self = this;
+ var elTarget = options.element;
+ var def = options.definition;
+ var host = options.host;
+ var elTb;
+ var pAddOdd = true;
+ this.path = (options.path) ? options.path : def.name;
+ this.instr = def.instr;
+ this.name = def.name;
+ this.refreshable = false;
+ var elSplineOverlay;
+ var hideAutomationButton;
+ this.parameters = {};
+ this.uniqueID = 0;
+
+ if (options.uniqueID) {
+ this.uniqueID = options.uniqueID;
+ }
+
+ var automationEls = {};
+ this.showAutomation = function(name, el) {
+ if (!elSplineOverlay) {
+ elSplineOverlay = $("<div />").addClass("twirl_spline_overlay").appendTo(options.splineElement);
+ }
+ for (var e in automationEls) {
+ automationEls[e].css({"z-index": 23, opacity: 0.4});
+ }
+ if (!el) {
+ el = automationEls[name];
+ } else {
+ automationEls[name] = el;
+ }
+ el.css({"z-index": 24, opacity: 1}).show();
+ hideAutomationButton.el.show();
+ elSplineOverlay.show();
+ if (el.parents(elSplineOverlay).length == 0) {
+ elSplineOverlay.append(el);
+ }
+ options.splineElement.show();
+ if (options.onShowAutomation) {
+ options.onShowAutomation();
+ }
+ };
+
+ this.getLagHints = function() {
+ var lagHints = [];
+ for (let i in self.parameters) {
+ var p = self.parameters[i];
+ var lagHint = p.getLagHint();
+ if (lagHint) lagHints.push(lagHint);
+ }
+ var lagHintHtml;
+ if (lagHints.length != 0) {
+ lagHintHtml = "Try ";
+ for (var i in lagHints) {
+ lagHintHtml += lagHints[i];
+ if (i != lagHints.length - 1) {
+ lagHintHtml += ((i == lagHints.length - 2) ? " or " : ", ");
+ }
+ }
+ }
+ return lagHintHtml;
+ };
+
+ this.hideAutomation = function(name) {
+ if (automationEls[name]) {
+ automationEls[name].hide();
+ delete automationEls[name];
+ if (Object.keys(automationEls).length == 0) {
+ elSplineOverlay.hide();
+ hideAutomationButton.el.hide();
+ options.splineElement.hide();
+ if (options.onHideAllAutomation) {
+ options.onHideAllAutomation();
+ }
+ }
+ }
+ }
+
+ this.hideAllAutomation = function(name) {
+ for (let p in self.parameters) {
+ self.parameters[p].hideAutomation();
+ }
+ };
+
+ this.redraw = function(region) {
+ for (let p in self.parameters) {
+ self.parameters[p].redraw(region);
+ }
+ };
+
+ this.refresh = function() {
+ if (!self.refreshable) {
+ return;
+ }
+ for (var k in self.parameters) {
+ self.parameters[k].refresh();
+ }
+ };
+
+ this.getAutomationData = function(start, end) {
+ var automations = [];
+ for (var k in self.parameters) {
+ var data = self.parameters[k].getAutomationData(start, end);
+ if (data) {
+ automations.push(data);
+ }
+ }
+ return automations;
+ };
+
+ this.getState = async function() {
+ var data = {instr: def.instr, name: self.path, channels: {}};
+ var value;
+ for (let chan in self.parameters) {
+ value = await app.getControlChannel(self.parameters[chan].sendChannel);
+ data.channels[chan] = value;
+ if (self.parameters[chan].modulationParameters) {
+ for (let modchan in self.parameters[chan].modulationParameters) {
+ value = await app.getControlChannel(self.parameters[chan].modulationParameters[modchan].sendChannel);
+ data.channels[modchan] = value;
+ }
+ }
+ }
+ return data;
+ };
+
+
+ this.reset = function() {
+ for (let p in self.parameters) {
+ self.parameters[p].reset();
+ }
+ };
+
+ this.randomise = function() {
+ for (let p in self.parameters) {
+ self.parameters[p].randomise();
+ if (!options.unmanagedModulation && self.parameters[p].modulationParameters) {
+ for (let mp in self.parameters[p].modulationParameters) {
+ self.parameters[p].modulationParameters[mp].randomise();
+ }
+ }
+ }
+ };
+
+ this.saveState = function() {
+ if (!options.useStorage || !host.storage) return;
+ var state = {};
+ for (let p in self.parameters) {
+ state[p] = self.parameters[p].getRawValue();
+ }
+ if (!host.storage.transforms) {
+ host.storage.transforms = {};
+ }
+ host.storage.transforms[def.instr] = state;
+ host.saveStorage();
+ };
+
+ this.remove = function() {
+ self.saveState();
+ for (let p in self.parameters) {
+ self.parameters[p].remove();
+ }
+ if (elSplineOverlay) {
+ elSplineOverlay.remove();
+ }
+ }
+
+ this.removeParameter = function(channel) {
+ if (self.parameters.hasOwnProperty(channel)) {
+ self.parameters[channel].remove();
+ delete self.parameters[channel]
+ }
+ };
+
+ function addParameter(pdef) {
+ var tp = new twirl.transform.Parameter({
+ instrument: def.instr,
+ definition: pdef,
+ transform: self,
+ getDurationFunc: options.getDurationFunc,
+ getRegionFunc: options.getRegionFunc,
+ otherInstanceNamesFunc: options.otherInstanceNamesFunc,
+ instancesFunc: options.instancesFunc,
+ unmanagedAutomation: options.unmanagedAutomation,
+ unmanagedModulation: options.unmanagedModulation,
+ host: host
+ });
+ self.parameters[tp.channel] = tp;
+ var er = tp.getElementRow();
+ if (er) {
+ elTb.append(er.addClass("twirl_tf_row_" + ((pAddOdd) ? "odd" : "even")));
+ pAddOdd = !pAddOdd;
+ };
+ };
+
+ this.setPlaying = function(state) {
+ for (let i in self.parameters) {
+ self.parameters[i].setPlaying(state);
+ }
+ };
+
+ function namePrepend(name, pdef) {
+ if (!pdef.hasOwnProperty("nameprepend")) return name;
+ name = pdef.nameprepend + " " + name;
+ return name[0] + name.substr(1).toLowerCase()
+ }
+
+ this.addParameter = function(pdef) {
+ if (!pdef.hasOwnProperty("presetgroup")) {
+ return addParameter(pdef);
+ }
+ var name;
+ var conditions;
+ var groupParameters = [];
+ var channelPrepend = (pdef.hasOwnProperty("channelprepend")) ? pdef.channelprepend : "";
+
+ if (pdef.presetgroup == "pvsynth") {
+ var dfaultMode = (pdef.hasOwnProperty("dfault")) ? pdef.dfault : 0;
+ conditions = [
+ {channel: channelPrepend + "pvresmode", operator: "eq", value: 1}
+ ];
+ groupParameters = [
+ {name: namePrepend("Resynth mode", pdef), channel: channelPrepend + "pvresmode", description: "Type of FFT resynthesis used", dfault: dfaultMode, options: ["Overlap-add", "Additive"], automatable: false},
+ {name: namePrepend("Oscillator spread", pdef), channel: channelPrepend + "pvaoscnum", description: "Number of oscillators used", automatable: false, conditions: conditions, lagHint: -1},
+ {name: namePrepend("Frequency modulation", pdef), channel: channelPrepend + "pvafreqmod", description: "Frequency modulation", dfault: 1, min: 0.01, max: 2, conditions: conditions},
+ {name: namePrepend("Oscillator offset", pdef), channel: channelPrepend + "pvabinoffset", description: "Oscillator bin offset", automatable: false, conditions: conditions, dfault: 0, lagHint: 1},
+ {name: namePrepend("Oscillator increment", pdef), channel: channelPrepend + "pvabinincr", description: "Oscillator bin increment", min: 1, max: 8, dfault: 1, step: 1, automatable: false, conditions: conditions, lagHint: -1}
+ ];
+
+ } else if (pdef.presetgroup == "applymode") {
+ var conditionsMix = [{channel: "applymode", operator: "eq", value: 1, absolutechannel: true}];
+ var conditionsFilter = [{channel: "applymode", operator: "eq", value: 4, absolutechannel: true}];
+ if (pdef.conditions) {
+ for (let c of pdef.conditions) {
+ conditionsMix.push(c);
+ conditionsFilter.push(c);
+ }
+ }
+ groupParameters = [
+ {name: "Apply mode", channel: "applymode", absolutechannel: true, description: "Apply mode", automatable: true, options: ["Replace", "Mix", "Modulate", "Demodulate", "Filter"], dfault: 0, conditions: pdef.conditions},
+ {name: "Dry mix", description: "Original signal amplitude", channel: "applymodedry", absolutechannel: true, conditions: conditionsMix, min: 0, max: 1, dfault: 1},
+ {name: "Wet mix", description: "Transformed signal amplitude", channel: "applymodewet", absolutechannel: true, conditions: conditionsMix, min: 0, max: 1, dfault: 1},
+ {name: "Minimum frequency", description: "Minimum frequency to transform", channel: "applymodedry", absolutechannel: true, conditions: conditionsFilter, min: 20, max: 44100, dfault: 500},
+ {name: "Maximum frequency", description: "Maximum frequency to transform", channel: "applymodedry", absolutechannel: true, conditions: conditionsFilter, min: 20, max: 44100, dfault: 2000}
+ ];
+
+ } else if (pdef.presetgroup == "pvanal") {
+ /* LPC unstable with WASM
+ groupParameters = [
+ {name: "Analysis type", channel: "pvstype", options: ["Overlap-add", "Linear prediction"], dfault: 0, automatable: false},
+ {preset: "fftsize"},
+ {name: "Overlap decimation", options: [2, 4, 8, 16], asvalue: true, dfault: 1, channel: "pvsdecimation", automatable: false, lagHint: -1},
+ {preset: "pvslock"},
+ {name: "Window size multiplier", min: 1, max: 4, dfault: 1, step :1, channel: "pvswinsizem", automatable: false, lagHint: -1, conditions: [{channel: "pvstype", operator: "eq", value: 0}]},
+ {name: "Order multiplier", description: "Linear predictor order (FFT size multiplier)", min: 0.001, max: 1, dfault: 0.25, channel: "pvsorderm", automatable: false, lagHint: -1, conditions: [{channel: "pvstype", operator: "eq", value: 1}]},
+ {name: "Window type", channel: "pvswintype", options: ["Hamming", "Von Hann", "Kaiser"], dfault: 1, automatable: false, conditions: [{channel: "pvstype", operator: "eq", value: 0}]},
+ {name: "Window type", channel: "pvswintypelpc", options: ["Hanning", "Hamming", "Half sine"], dfault: 0, automatable: false, conditions: [{channel: "pvstype", operator: "eq", value: 1}]}
+ ];
+ */
+ groupParameters = [
+ {preset: "fftsize"},
+ {name: "Overlap decimation", options: [2, 4, 8, 16], asvalue: true, dfault: 1, channel: "pvsdecimation", automatable: false, lagHint: -1},
+ {preset: "pvslock"},
+ {name: "Window size multiplier", min: 1, max: 4, dfault: 1, step :1, channel: "pvswinsizem", automatable: false, lagHint: -1},
+ {name: "Window type", channel: "pvswintype", options: ["Hamming", "Von Hann", "Kaiser"], dfault: 1, automatable: false}
+ ];
+ } else if (pdef.presetgroup == "pitchscale") {
+ groupParameters = [
+ {name: namePrepend("Pitch scale mode", pdef), channel: channelPrepend + "pitchscalemode", options: ["Ratio", "Semitone"], dfault: 0},
+ {name: namePrepend("Pitch scale", pdef), channel: channelPrepend + "pitchscale", description: "Pitch scaling", dfault: 1, min: 0.01, max: 10, conditions: [{channel: channelPrepend + "pitchscalemode", operator: "eq", value: 0}]},
+ {name: namePrepend("Semitones", pdef), channel: channelPrepend + "pitchsemitones", min: -24, max: 24, step: 1, dfault: 0, conditions: [{channel: channelPrepend + "pitchscalemode", operator: "eq", value: 1}]}
+ ];
+
+ } else if (pdef.presetgroup == "notefreq") {
+ var base = {name: namePrepend("Frequency mode", pdef), channel: channelPrepend + "freqmode", description: "Frequency mode", options: ["Frequency", "Note"], dfault: 0};
+ if (pdef.hasOwnProperty("conditions")) {
+ base["conditions"] = pdef.conditions;
+ }
+ groupParameters.push(base);
+
+ conditions = [{channel: channelPrepend + "freqmode", operator: "eq", value: 0}];
+ if (pdef.hasOwnProperty("conditions")) {
+ Array.prototype.push.apply(conditions, pdef.conditions);
+ }
+
+ var dfaultFreq = (pdef.hasOwnProperty("dfault")) ? pdef.dfault : 440;
+
+ var freq = {name: namePrepend("Frequency", pdef), channel: channelPrepend + "freq", description: "Frequency", dfault: dfaultFreq, min: 20, max: 22000, conditions: conditions}
+ if (pdef.hasOwnProperty("lagHint")) {
+ freq.lagHint = pdef.lagHint;
+ }
+ groupParameters.push(freq);
+
+ conditions = [{channel: channelPrepend + "freqmode", operator: "eq", value: 1}];
+ if (pdef.hasOwnProperty("conditions")) {
+ Array.prototype.push.apply(conditions, pdef.conditions);
+ }
+ var note = {preset: "note", name: namePrepend("Note", pdef), conditions: conditions, channel: channelPrepend + "note"};
+ if (pdef.hasOwnProperty("lagHint")) {
+ note.lagHint = pdef.lagHint;
+ }
+ groupParameters.push(note);
+
+ }
+ for (let gp of groupParameters) {
+ if (pdef.hasOwnProperty("automatable")) {
+ gp.automatable = pdef.automatable;
+ }
+ addParameter(gp);
+ }
+ }
+
+ function build() {
+ elTarget.empty();
+ var elContainer = $("<div />").addClass("twirl_tf_container").appendTo(elTarget);
+ hideAutomationButton = twirl.createIcon({label: "Hide automation", icon: "hide", click: function() {
+ self.hideAllAutomation();
+ }});
+ hideAutomationButton.el.hide();
+
+ if (!host.offline) {
+ app.setControlChannel("applymode" + self.uniqueID, 0); // not all transforms will set this
+ }
+
+ var header = $("<div />").addClass("twirl_tf_header");
+ if (def.unstable) {
+ $("<div />").css({
+ "background-color": "#aa0000",
+ color: "#ffffff",
+ "font-size": "var(--fontSizeSmall)"
+ }).text("Instabilities have been reported with this transform. It is recommended you save your work before using it.").appendTo(header);
+ }
+ $("<div />").text(def.name).appendTo(header);
+ if (options.onClose) {
+ header.append(twirl.createIcon({
+ label: "Close",
+ icon: "close",
+ click: function() { options.onClose()},
+ size: 20
+ }).el.css("float", "right"));
+ }
+ var el = $("<div />").addClass("twirl_tf_container").append(header).appendTo(elContainer);
+
+ if (def.description) {
+ header.on("mouseover", function(event){
+ twirl.tooltip.show(event, def.description);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ $("<div />").css({"float": "right"}).append(
+ hideAutomationButton.el
+ ).append(
+ twirl.createIcon({
+ label: "Randomise parameters",
+ icon: "randomise",
+ click: function() {
+ self.randomise();
+ }
+ }).el
+ ).append(
+ twirl.createIcon({
+ label: "Reset parameters",
+ icon: "reset",
+ click: function() {
+ self.reset();
+ }
+ }).el
+ ).appendTo(el);
+
+
+
+ var tbl = $("<table />").appendTo(elContainer);
+ elTb = $("<tbody />").appendTo(tbl);
+ for (let p of def.parameters) {
+ self.addParameter(p);
+ }
+
+ if (options.useStorage && host.storage && host.storage.transforms && host.storage.transforms[def.instr]) {
+ var state = host.storage.transforms[def.instr];
+ for (var p in state) {
+ self.parameters[p].setRawValue(state[p]);
+ }
+ }
+ self.refresh();
+ }
+ build();
+};
+
+twirl.transform.TreeView = function(options) {
+ var self = this;
+
+ function recurse(items, descended, path) {
+ if (!path) path = "";
+ items = (items) ? items : options.items;
+ var ul = $("<ul />").addClass("twirl_treeview_treelist").addClass((descended) ? "twirl_treeview_nested" : "ttwirl_treeview_reelist");
+
+ for (let k in items) {
+ let name = items[k].name;
+ let thisPath = path + "> " + items[k].name;
+ var li = $("<li />");
+ if (items[k].description) {
+ li.on("mouseover", function(event){
+ twirl.tooltip.show(event, items[k].description);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+ if (items[k].hasOwnProperty("contents")) {
+ $("<span />").addClass("twirl_treeview_caret").text(name).click(function() {
+ $(this).parent().children(".twirl_treeview_nested").toggleClass("twirl_treeview_active");
+ $(this).toggleClass("twirl_treeview_caret-down");
+ }).appendTo(li);
+ var subitems = recurse(items[k].contents, true, thisPath);
+ li.append(subitems);
+
+ } else {
+ var content = name;
+ if (items[k].hasOwnProperty("added")) {
+ var dp = items[k].added.split("-");
+ var added = new Date(dp[0], dp[1] - 1, dp[2]);
+ if (Math.round((new Date() - added) / (1000 * 60 * 60 * 24)) <= 14) {
+ x.html(name + " <p style=\"display:inline;color:#ff2222;\"> [new]</p>");
+ }
+ }
+ li.html(content).css("cursor", "pointer").click(function() {
+ options.click(items[k], thisPath);
+ });
+ }
+ ul.append(li);
+ }
+ options.element.append(ul);
+ return ul;
+ }
+
+ options.element.append(recurse());
+};
\ No newline at end of file diff --git a/site/app/twirl/twirl.css b/site/app/twirl/twirl.css new file mode 100644 index 0000000..f4163fa --- /dev/null +++ b/site/app/twirl/twirl.css @@ -0,0 +1,310 @@ +select {
+ background-color: var(--bgColor3);
+ color: var(--fgColor2);
+}
+
+input {
+ background-color: var(--bgColor3);
+ color: var(--fgColor2);
+}
+
+.twirl_contextmenu {
+ position: absolute;
+ background-color: var(--bgColor3);
+ border: var(--menuBarBottomBorder);
+ color: var(--fgColor1);
+ cursor: arrow;
+ display: none;
+ user-select: none;
+ z-index: 30;
+ opacity: 0.9;
+ padding: 2px;
+}
+
+.twirl_contextmenu_item {
+ font-size: var(--fontSizeDefault);
+}
+
+.twirl_contextmenu_item:hover {
+ color: var(--bgColor1);
+ background-color: var(--fgColor2);
+}
+
+.twirl_slider {
+ appearance: none;
+ outline: none;
+ background-color: var(--bgColor3);
+ background: var(--bgColor3);
+ accent-color: var(--fgColor2);
+}
+
+.twirl_transparentinput {
+ font-size: var(--fontSizeDefault);
+ background-color: var(--bgColor2);
+ color: var(--fgColor3);
+ border: none;
+}
+
+.twirl_tf_container {
+ font-size: var(--fontSizeSmall);
+ font-family: var(--fontFace);
+}
+
+.twirl_tf_row_odd {
+ background-color: var(--rowOddBgColor);
+}
+
+.twirl_tf_row_even {
+ background-color: var(--rowEvenBgColor);
+}
+
+.twirl_tf_cell_plainbg {
+ background-color: var(--bgColor4);
+}
+
+.twirl_tf_cell {
+ font-size: var(--fontSizeDefault);
+}
+
+.twirl_tf_cell_text {
+ font-size: var(--fontSizeDefault);
+ text-align: right;
+}
+
+.twirl_tf_cellfixed {
+ overflow: hidden;
+ width: 40px;
+}
+
+.twirl_tf_header {
+ background-color: var(--bgColor4);
+ font-size: var(--fontSizeDefault);
+ font-weight: bold;
+}
+
+.twirl_spline_overlay {
+ position: absolute;
+ width: 100%;
+ top: 0px;
+ bottom: 0px;
+ left: 0px;
+}
+
+.twirl_tooltip {
+ position: absolute;
+ text-align: center;
+ border-radius: 5px;
+ pointer-events: none;
+ padding: 2px;
+ color: #000000;
+ opacity: 0;
+ font-family: var(--fontFace);
+ font-size: var(--fontSizeSmall);
+ text-shadow: 1px 1px #ffffff;
+ z-index: 210;
+}
+
+#twirl_prompt {
+ z-index: 201;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ display: none;
+}
+
+#twirl_prompt_background {
+ z-index: 202;
+ background-color: #ffffff;
+ opacity: 0.3;
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+#twirl_prompt_inner {
+ z-index: 204;
+ margin: 0px;
+ padding: 10px;
+ position: absolute;
+ font-size: var(--promptFontSize);
+ background-color: var(--promptBgColor);
+ border: var(--promptBorder);
+ box-shadow: var(--promptShadow);
+ width: 40%;
+ min-height: 30%;
+ left: 30%;
+ top: 35%;
+ text-align: center;
+ overflow: auto;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+#twirl_prompt_button_text {
+ font-size: var(--fontSizeMedium);
+ padding: 5px;
+}
+
+#twirl_loading {
+ position: fixed;
+ display: none;
+ z-index: 161;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+#twirl_loading_background {
+ position: absolute;
+ z-index: 162;
+ background-color: #ffffff;
+ opacity: 0.2;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+#twirl_loading_inner {
+ z-index: 163;
+ position: absolute;
+ font-size: var(--promptFontSize);
+ background-color: var(--promptBgColor);
+ border: var(--promptBorder);
+ box-shadow: var(--promptShadow);
+ text-align: center;
+ width: 50%;
+ height: 20%;
+ left: 25%;
+ top: 40%;
+}
+
+#twirl_loading_percent {
+ z-index: 163;
+ position: absolute;
+ top: 80%;
+ left: 10%;
+ width: 80%;
+ height: 10%;
+ background-color: #9e8c6d;
+}
+
+#twirl_loading_percent_inner {
+ z-index: 163;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ height: 100%;
+ width: 1%;
+ background-color: #e0c494;
+}
+
+.twirl_icon {
+ cursor: pointer;
+ filter: var(--iconFilter);
+}
+
+.topmenu {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ background-color: var(--bgColor1);
+ border-bottom: var(--menuBarBottomBorder);
+ color: var(--fgColor2);
+ cursor: arrow;
+ user-select: none;
+ z-index: 40;
+}
+
+.topmenu_item {
+ float: left;
+ font-size: var(--fontSizeDefault);
+ text-align: center;
+ padding: 2px 5px;
+ z-index: 40;
+}
+
+.topmenu_item:hover {
+ color: var(--bgColor1);
+ background-color: var(--fgColor2);
+}
+
+.topmenu_dropdown {
+ display: none;
+ border: 1px solid black;
+ position: fixed;
+ margin: 2px -5px;
+ background-color: var(--bgColor1);
+ color: var(--fgColor2);
+ min-width: 160px;
+ padding-top: 0px;
+ padding-left: 2px;
+ padding-right: 2px;
+ padding-bottom: 2px;
+ box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+ z-index: 40;
+}
+
+.topmenu_dropdown_item {
+ text-align: left;
+ z-index: 40;
+}
+
+.topmenu_dropdown_item_disabled {
+ text-align: left;
+ color: #666666;
+ font-style: italic;
+ z-index: 40;
+}
+
+.topmenu_dropdown .topmenu_dropdown_item:hover {
+ background-color: #000000;
+}
+
+.topmenu_dropdown_itemright {
+ float: right;
+}
+
+ul, .twirl_treeview_treelist {
+ list-style-type: none;
+ font-size: var(--fontSizeSmall);
+ border-bottom: 1px solid #878787;
+}
+
+.twirl_treeview_treelist {
+ margin: 0;
+ padding: 0;
+}
+
+.twirl_treeview_caret {
+ cursor: pointer;
+ font-size: var(--fontSizeDefault);
+ user-select: none;
+}
+
+.twirl_treeview_caret::before {
+ content: "\25B6";
+ color: black;
+ display: inline-block;
+ margin-right: 6px;
+}
+
+.twirl_treeview_caret-down::before {
+ transform: rotate(90deg);
+}
+
+.twirl_treeview_nested {
+ margin-left: 20px;
+ display: none;
+}
+.twirl_treeview_active {
+ display: block;
+}
diff --git a/site/app/twirl/twirl.js b/site/app/twirl/twirl.js new file mode 100644 index 0000000..5f201f6 --- /dev/null +++ b/site/app/twirl/twirl.js @@ -0,0 +1,479 @@ +window.twirl = {
+ debug: false, //window.location.href.startsWith("file://"),
+ themes: ["Default", "Basic", "Hacker", "Monoclassic", "Doze"],
+ audioTypes: ["audio/mpeg", "audio/mp4", "audio/ogg", "audio/vorbis", "audio/x-flac","audio/aiff","audio/x-aiff", "audio/vnd.wav", "audio/wave", "audio/x-wav", "audio/wav", "audio/flac"],
+ maxFileSize: 1e+8, // 100MB
+ latencyCorrection: 40,
+ storage: {},
+ errorState: null,
+ audioContext: null,
+ _booted: false,
+ _initialised: false,
+ _remote: {sessionID: null, sending: false},
+ _els: {
+ base: null,
+ toolTip: null,
+ prompt: {},
+ loading: {},
+ contextMenu: null
+ }
+};
+
+twirl.boot = function() {
+ if (twirl._booted) return;
+ twirl.audioContext = new AudioContext();
+ twirl._booted = true;
+};
+
+twirl.init = function() {
+ if (twirl._initialised) return;
+
+ var NoteData = function() {
+ var self = this;
+ this.data = null;
+ fetch("https://apps.csound.1bpm.net/app/twirl/notedata.json").then(function(r) {
+ r.json().then(function(j) {
+ self.data = j;
+ });
+ });
+ };
+ twirl.noteData = new NoteData();
+
+ // storage
+ twirl.storage.data = localStorage.getItem("twirl");
+ if (twirl.storage.data) {
+ twirl.storage.data = JSON.parse(twirl.storage.data);
+ } else {
+ twirl.storage.data = {};
+ }
+
+ // base
+ twirl._els.base = $("<div />").attr("id", "twirl").appendTo($("body"));
+
+ // tooltip
+ twirl._els.toolTip = $("<div />").addClass("twirl_tooltip").appendTo(twirl._els.base);
+
+ // context menu
+ twirl._els.contextMenu = $("<div />").addClass("twirl_contextmenu").appendTo(twirl._els.base);
+
+ // prompt
+ var p = twirl._els.prompt;
+ p.base = $("<div />").attr("id", "twirl_prompt").appendTo(twirl._els.base);
+ $("<div />").attr("id", "twirl_prompt_background").appendTo(p.base);
+ var promptInner = $("<div />").attr("id", "twirl_prompt_inner").appendTo(p.base);
+ p.text = $("<div />").attr("id", "twirl_prompt_text").appendTo(promptInner);
+ p.button = $("<button />").attr("id", "twirl_prompt_button_text").text("OK");
+ p.buttonContainer = $("<div />").attr("id", "twirl_prompt_button").append($("<hr />")).append(p.button).appendTo(promptInner);
+
+ // loading
+ var l = twirl._els.loading;
+ l.base = $("<div />").attr("id", "twirl_loading").appendTo(twirl._els.base);
+ $("<div />").attr("id", "twirl_loading_background").appendTo(l.base);
+ var loadingInner = $("<div />").attr("id", "twirl_loading_inner").appendTo(l.base);
+ l.text = $("<p />").attr("id", "twirl_loading_text").text("Processing").appendTo(loadingInner);
+ l.percentContainer = $("<div />").attr("id", "twirl_loading_percent").appendTo(loadingInner);
+ l.percent = $("<div />").attr("id", "twirl_loading_percent_inner").appendTo(l.percentContainer);
+
+ // theme
+ if (twirl.storage.data.theme) {
+ twirl.setTheme(twirl.storage.data.theme, true);
+ }
+ twirl._initialised = true;
+};
+
+twirl.storage.save = function() {
+ localStorage.setItem("twirl", JSON.stringify(twirl.storage.data));
+};
+
+twirl.random = {
+ rgbColour: function() {
+ return "rgb(" + (Math.round(Math.random() * 50) + 205) + ","
+ + (Math.round(Math.random() * 50) + 205) + ","
+ + (Math.round(Math.random() * 50) + 205) + ")";
+ }
+};
+
+twirl.createIcon = function(definition) {
+ var state = true;
+ var active = true;
+ function formatPath(i) {
+ return "../twirl/icon/" + i + ".svg";
+ }
+ var el = $("<img />");
+
+ if (definition.size) {
+ el.css("width", definition.size + "px");
+ }
+
+ var obj = {
+ el: el,
+ setState: function(tstate) {
+ if (!definition.icon2) return;
+ state = tstate;
+ if (state) {
+ el.attr("src", formatPath(definition.icon));
+ } else {
+ el.attr("src", formatPath(definition.icon2));
+ }
+
+ },
+ setActive: function(state) {
+ if (state) {
+ el.css("opacity", 1);
+ active = true;
+ } else {
+ el.css("opacity", 0.4);
+ active = false;
+ }
+ },
+ definition: definition
+ };
+
+ obj.click = function() {
+ definition.click(obj);
+ };
+
+ el.addClass("twirl_icon").css("opacity", 1).attr("src", formatPath(definition.icon)).on("mouseover", function(event){
+ var label = (!state && definition.label2) ? definition.label2 : definition.label;
+ twirl.tooltip.show(event, label);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ }).click(function(el) {
+ if (active || definition.clickOnInactive) definition.click(obj);
+ });
+ return obj;
+};
+
+twirl.setTheme = function(name, noSave) {
+ var html = $("html");
+ if (html.attr("class")) {
+ for (let c of html.attr("class").split(/\s+/)) {
+ if (c.startsWith("theme")) {
+ html.removeClass(c);
+ }
+ }
+ }
+ html.addClass("theme" + name[0].toUpperCase() + name.substr(1).toLowerCase());
+ if (!noSave) {
+ twirl.storage.data.theme = name;
+ twirl.storage.save();
+ }
+};
+
+twirl.prompt = {
+ hide: function() {
+ twirl._els.prompt.base.hide();
+ },
+ show: function(text, onComplete, noButton) {
+ var p = twirl._els.prompt;
+ twirl.loading.hide();
+ p.text.empty();
+ if (typeof(text) == "string") {
+ p.text.text(text);
+ } else {
+ p.text.append(text);
+ }
+ if (!noButton) {
+ p.buttonContainer.show();
+ p.button.unbind().click(function(){
+ twirl.prompt.hide();
+ if (onComplete) onComplete();
+ });
+ } else {
+ p.buttonContainer.hide();
+ }
+ p.base.show();
+ }
+};
+
+twirl.loading = {
+ hide: function() {
+ $("body").css("cursor", "default");
+ twirl._els.loading.base.hide();
+ },
+ show: function(text, showPercent) {
+ var l = twirl._els.loading;
+ $("body").css("cursor", "wait");
+ l.text.text((text) ? text : "Processing");
+ if (showPercent) {
+ l.percentContainer.show();
+ } else {
+ l.percentContainer.hide();
+ }
+ l.base.show();
+ },
+ setPercent: function(percent) {
+ twirl._els.loading.percent.width(percent + "%");
+ }
+};
+
+twirl._setContextPosition = function(event, el, augmentations) {
+ var margin = 100;
+ if (!augmentations) augmentations = [0, 0];
+ if (event.clientX >= window.innerWidth - margin) {
+ el.css({right: margin + "px", left: "auto"});
+ } else {
+ el.css({right: "auto", left: (event.clientX + augmentations[0]) + "px"});
+ }
+
+ if (event.clientY >= window.innerHeight - margin) {
+ el.css({bottom: margin + "px", top: "auto"});
+ } else {
+ el.css({bottom: "auto", top: (event.clientY + augmentations[1]) + "px"});
+ }
+};
+
+twirl.contextMenu = {
+ show: function(event, data) {
+ event.preventDefault();
+ twirl._els.contextMenu.empty().unbind().on("mouseout", function(){
+ twirl._els.contextMenu.hide().off("mouseout");
+ });
+ for (let i in data) {
+ let d = data[i];
+ $("<div />").addClass("twirl_contextmenu_item").text(d.name).click(function(){
+ twirl._els.contextMenu.hide().off("mouseout");
+ d.click();
+ }).appendTo(twirl._els.contextMenu).on("mouseout", function(e){
+ e.stopPropagation();
+ });
+ }
+ twirl._setContextPosition(event, twirl._els.contextMenu, [-10, -10]);
+ twirl._els.contextMenu.show();
+ return false;
+ }
+};
+
+twirl.tooltip = {
+ show: function(event, text, colour) {
+ if (!colour) colour = "#bbbbbb";
+ var el = twirl._els.toolTip;
+ el.html(text).css({opacity: 0.8, "background-color": colour});
+ twirl._setContextPosition(event, el, [20, -15]);
+
+ },
+ hide: function() {
+ twirl._els.toolTip.css("opacity", 0);
+ }
+};
+
+twirl.sendErrorState = async function(errorObj) {
+ if (twirl._remote.sending) return;
+ twirl._remote.sending = true;
+ if (typeof(errorObj) == "function") {
+ errorObj = errorObj();
+ }
+ errorObj.application = $("title").text();
+ var data = {
+ request_type: "LogError",
+ error: errorObj
+ };
+
+ if (twirl._remote.sessionID) {
+ data.session_id = twirl._remote.sessionID;
+ }
+ var resp = await fetch("https:///service/", {
+ method: "POST",
+ headers: {
+ "Content-type": "application/json"
+ },
+ body: JSON.stringify(data)
+ });
+ var json = await resp.json();
+ if (json.session_id && !twirl._remote.sessionID) {
+ twirl._remote.sessionID = json.session_id;
+ }
+ twirl._remote.sending = false;
+};
+
+twirl.errorHandler = function(text, onComplete, errorObj) {
+ var errorText = (!text) ? twirl.errorState : text;
+ if (!errorObj) errorObj = {};
+ errorObj.text = errorText;
+ //twirl.sendErrorState(errorObj);
+ twirl.prompt.show(errorText, onComplete);
+ twirl.errorState = null;
+};
+
+twirl.showSettings = function(host, settings, onThemeChange) {
+ var el = $("<div />").css("font-size", "var(--fontSizeDefault)").append($("<h3 />").text("Settings"));
+ var tb = $("<tbody />");
+ $("<table />").append(tb).appendTo(el);
+
+ var currentThemeIndex;
+ if (twirl.storage.data.theme) currentThemeIndex = twirl.themes.indexOf(twirl.storage.data.theme);
+ if (!currentThemeIndex) currentThemeIndex = 0;
+
+ var tpTheme = new twirl.transform.Parameter({
+ definition: {name: "Theme", options: twirl.themes, dfault: currentThemeIndex, fireChanges: false, automatable: false},
+ host: host,
+ onChange: function(val) {
+ twirl.setTheme(twirl.themes[val]);
+ if (onThemeChange) onThemeChange();
+ }
+ });
+ tb.append(tpTheme.getElementRow(true))
+
+ for (let s of settings) {
+ var value;
+ if (s.options && s.storageKey) {
+ if (host.storage[s.storageKey]) value = host.storage[s.storageKey];
+ if (value < 0) value = s.dfault;
+ } else if (s.storageKey) {
+ value = (host.storage[s.storageKey]) ? host.storage[s.storageKey] : s.dfault;
+ if (s.bool) {
+ s.min = 0;
+ s.max = 1;
+ s.step = 1;
+ }
+ } else {
+ value = s.dfault;
+ }
+
+ let param = new twirl.transform.Parameter({
+ definition: {
+ name: s.name,
+ description: s.description,
+ fireChanges: false, automatable: false,
+ min: s.min, max: s.max, step: s.step, dfault: value,
+ options: s.options, asvalue: s.asvalue
+
+ }, host: host, onChange: function(val) {
+ if (s.storageKey) {
+ host.storage[s.storageKey] = val;
+ host.saveStorage();
+ }
+ if (s.onChange) s.onChange(val);
+ }
+ });
+ tb.append(param.getElementRow(true));
+ }
+ twirl.prompt.show(el);
+};
+
+twirl.TopMenu = function(host, menuData, elTarget) {
+ var self = this;
+ var opened = false;
+ var keyHandlers = [];
+
+ function keyHandler(e) {
+ if (!host.visible) return;
+ var nodeType = e.target.nodeName.toLowerCase();
+ if (nodeType == "input" || nodeType == "textarea") return;
+ e.preventDefault();
+ for (let h of keyHandlers) {
+ if (
+ (h.key == e.key.toLowerCase()) &&
+ ((!h.hasOwnProperty("ctrlKey") && !e.ctrlKey) || (h.ctrlKey && e.ctrlKey)) &&
+ ((!h.hasOwnProperty("shiftKey") && !e.shiftKey) || (h.shiftKey && e.shiftKey)) &&
+ ((!h.hasOwnProperty("altKey") && !e.altKey) || (h.altKey && e.altKey))
+ ) {
+ if (h.hasOwnProperty("condition") && !h.condition(host)) {
+ return;
+ }
+ if (h.hasOwnProperty("keyCondition") && !h.keyCondition(host)) {
+ return;
+ }
+ return h.func(host);
+ }
+ }
+ }
+
+ function construct(data) {
+ if (!data) data = menuData;
+ let onPlayDisables = [];
+ elTarget.empty();
+ var elMenuBar = $("<div />").addClass("topmenu").appendTo(elTarget);
+ for (let d of data) {
+ let elTopItem = $("<div />").addClass("topmenu_item").text(d.name).appendTo(elMenuBar);
+ let elMenu = $("<div />").addClass("topmenu_dropdown").appendTo(elTopItem);
+ let showConditions = [];
+ let onShows = [];
+ for (let c of d.contents) {
+ let elItem;
+ if (c.preset) {
+ if (c.preset == "divider") {
+ elItem = $("<hr />").appendTo(elMenu);
+ }
+ } else {
+ elItem = $("<div />").addClass("topmenu_dropdown_item").appendTo(elMenu);
+ if (typeof(c.name) == "function") {
+ onShows.push(function(){
+ elItem.text(c.name(host));
+ });
+ } else {
+ elItem.text(c.name);
+ }
+ if (c.click) elItem.click(function(){
+ if (c.condition && !c.condition(host)) return;
+ elMenu.hide();
+ opened = false;
+ c.click(host);
+ });
+ if (c.shortcut) {
+ $("<div />").addClass("topmenu_dropdown_itemright").text(c.shortcut.name).appendTo(elItem);
+ var obj = {func: c.click};
+ Object.assign(obj, c.shortcut);
+ if (c.condition) obj.condition = c.condition;
+ if (c.keyCondition) obj.keyCondition = c.keyCondition;
+ delete obj.name;
+ keyHandlers.push(obj);
+ }
+ if (c.disableOnPlay) {
+ onPlayDisables.push(elItem);
+ }
+ }
+ if (c.condition) {
+ showConditions.push({el: elItem, func: c.condition});
+ }
+ }
+
+ function showMenu() {
+ for (let c of showConditions) {
+ if (c.func(host)) {
+ c.el.removeClass("topmenu_dropdown_item_disabled");
+ } else {
+ c.el.addClass("topmenu_dropdown_item_disabled");
+ }
+ }
+ for (let o of onShows) {
+ o(host);
+ }
+ elMenu.show();
+ }
+
+
+ elTopItem.on("mouseover", function(){
+ if (opened) {
+ setTimeout(function(){
+ opened = true;
+ }, 10);
+ showMenu();
+ }
+ }).on("click", function() {
+ opened = true;
+ showMenu();
+ }).on("mouseleave", function() {
+ elMenu.hide();
+ setTimeout(function(){
+ opened = false;
+ }, 5);
+ });
+
+ }
+ if (host.onPlays) {
+ host.onPlays.push(async function(playing){
+ for (let o of onPlayDisables) {
+ if (playing) {
+ o.addClass("topmenu_dropdown_item_disabled");
+ } else {
+ o.removeClass("topmenu_dropdown_item_disabled");
+ }
+ }
+ });
+ }
+ $("body").off("keydown", keyHandler).on("keydown", keyHandler);
+ }
+ construct();
+};
+
diff --git a/site/app/twirl/twirl_compiler.py b/site/app/twirl/twirl_compiler.py new file mode 100644 index 0000000..cc2ba3e --- /dev/null +++ b/site/app/twirl/twirl_compiler.py @@ -0,0 +1,92 @@ +import lxml.html as lh
+import lxml.etree as et
+import os
+import shutil
+
+base_path = "/mnt/hd/web/1bpm.net"
+top_path = os.path.join(base_path, "apps.csound")
+apps_top_path = os.path.join(top_path, "app")
+twirl_path = os.path.join(apps_top_path, "twirl")
+
+apps = ["twist", "twigs", "twine"]
+
+
+def compile_apps():
+ for app in apps:
+ compile(app)
+
+def compile(app):
+ print "Compiling {}".format(app)
+ app_path = os.path.join(apps_top_path, app)
+ target_dir = "{}/{}".format(base_path, app)
+
+ doc = lh.parse(os.path.join(app_path, "index.html"))
+ root = doc.getroot()
+ head = root.xpath("//head")[0]
+
+ script_data = ""
+ css_data = ""
+ post_scripts = []
+
+ for script in root.xpath("//script"):
+ src = script.attrib.get("src")
+ if src:
+ src = src.replace("https://apps.csound.1bpm.net/", "../../")
+ path = os.path.join(app_path, src)
+ with open(path, "r") as f:
+ script_data += f.read() + "\n"
+ else:
+ post_scripts.append(script)
+ script.getparent().remove(script)
+
+ new_script = et.fromstring("<script type=\"text/javascript\" src=\"{}.js\"></script>".format(app))
+ head.append(new_script)
+ for ps in post_scripts:
+ head.append(ps)
+
+ for css in root.xpath("//link"):
+ href = css.attrib.get("href")
+ if href:
+ href = href.replace("https://apps.csound.1bpm.net/", "../../")
+ path = os.path.join(app_path, href)
+ with open(path, "r") as f:
+ css_data += f.read() + "\n"
+ css.getparent().remove(css)
+
+ new_css = et.fromstring("<link rel=\"stylesheet\" href=\"{}.css\" />".format(app))
+ head.append(new_css)
+
+ doc.write(os.path.join(target_dir, "index.html"), method="html", encoding="UTF-8")
+
+ with open(os.path.join(target_dir, "{}.js".format(app)), "w") as f:
+ f.write(script_data)
+
+ with open(os.path.join(target_dir, "{}.css".format(app)), "w") as f:
+ f.write(css_data)
+
+ links = [
+ [twirl_path, "twirl"],
+ [os.path.join(twirl_path, "font"), "font"],
+ [os.path.join(top_path, "udo"), "udo"],
+ [os.path.join(top_path, "code"), "code"],
+ [os.path.join(app_path, "{}.csd".format(app)), "{}.csd".format(app)]
+ ]
+
+ for l in links:
+ target = os.path.join(target_dir, l[1])
+ if os.path.islink(target):
+ os.unlink(target)
+ os.symlink(l[0], target)
+
+ copies = ["documentation.html", "developer_documentation.html"]
+ for c in copies:
+ item = os.path.join(app_path, c)
+ if os.path.exists(item):
+ target = os.path.join(target_dir, c)
+ if os.path.exists(target):
+ os.unlink(target)
+ shutil.copy(item, target)
+
+if __name__ == "__main__":
+ compile_apps()
+
diff --git a/site/app/twist/_unlive/apid.js b/site/app/twist/_unlive/apid.js new file mode 100644 index 0000000..28a00f2 --- /dev/null +++ b/site/app/twist/_unlive/apid.js @@ -0,0 +1,978 @@ +var twst = {};
+
+
+
+
+twst.Parameter = function(instr, definition, parent, transform, twist) {
+ var self = this;
+ var refreshable = false;
+ var changeFunc;
+ var value;
+ var initval = true;
+ var type;
+ var applicable;
+ var channel = (parent) ? parent.channel : instr + "_";
+ if (definition.hasOwnProperty("channel")) {
+ channel += definition.channel;
+ } else {
+ channel += definition.name.toLowerCase();
+ }
+
+ Object.defineProperty(this, "channel", {
+ get: function() { return channel; },
+ set: function(x) {}
+ });
+
+
+ if (definition.hasOwnProperty("options")) {
+ if (!definition.hasOwnProperty("automatable")) {
+ definition.automatable = false;
+ }
+ }
+
+ if (definition.hasOwnProperty("preset")) {
+ var save = {};
+ if (definition.hasOwnProperty("dfault")) {
+ save.dfault = definition.dfault;
+ }
+
+ if (definition.hasOwnProperty("name")) {
+ save.name = definition.name;
+ }
+
+ if (definition.preset == "fftsize") {
+ Object.assign(definition, {name: "FFT size", channel: "fftsize", description: "FFT size", options: [256, 512, 1024, 2048, 4096], dfault: 1, asvalue: true, automatable: false});
+ } else if (definition.preset == "wave") {
+ Object.assign(definition, {name: "Wave", description: "Wave shape to use", options: ["Sine", "Square", "Saw", "Pulse", "Triangle"], dfault: 0});
+ } else if (definition.preset == "instance") {
+ initval = false;
+ transform.refreshable = true;
+ refreshable = true;
+ Object.assign(definition, {
+ name: "Instance", description: "Other wave to use", channel: "instanceindex",
+ options: twist.otherInstanceNames,
+ automatable: false
+ });
+ changeFunc = function(index) {
+ var s = twist.waveforms[index].selected;
+ app.setControlChannel(instr + "_" + "otinststart", s[0]);
+ app.setControlChannel(instr + "_" + "otinstend", s[1]);
+ app.setControlChannel(instr + "_" + "otiinstchan", s[2]);
+ }
+ }
+ if (save) {
+ Object.assign(definition, save);
+ }
+ } // if preset
+
+
+
+ if (definition.hasOwnProperty("options") || (definition.hostrange && parent.definition.hasOwnProperty("options"))) {
+ type = "select";
+ } else {
+ type = "range";
+ }
+
+
+ if (definition.hasOwnProperty("conditions") && !parent) {
+ transform.refreshable = refreshable = true;
+ }
+
+ Object.defineProperty(this, "applicable", {
+ get: function() { return applicable; },
+ set: function(v) { }
+ });
+
+ Object.defineProperty(this, "value", {
+ get: function() { return value; },
+ set: function(v) {
+ if (type == "select") {
+ if (v < 0) {
+ v = 0;
+ } else if (v >= definition.options.length) {
+ v = defintion.options.length - 1;
+ }
+ if (definition.asvalue) {
+ value = definition.options[v];
+ } else {
+ value = v;
+ }
+ } else if (type == "range") {
+ if (v > definition.max) {
+ v = definition.max;
+ } else if (v < definition.min) {
+ v = definition.min;
+ } else if (v % definition.step != 0) {
+ if (definition.step == 1) {
+ v = Math.round(v);
+ } else {
+ v = Math.ceil((v - definition.min) / definition.step) * definition.step + definition.min;
+ }
+ }
+ value = v;
+ }
+ twist.csapp.setControlChannel(channel, value);
+ }
+ });
+
+
+
+
+ var automation = [];
+
+ this.definition = definition;
+ this.modulation = null;
+ this.channel = channel;
+ var modulationParameters = null;
+
+
+ if (!definition.hasOwnProperty("step")) {
+ definition.step = 0.0000001;
+ }
+
+ if (!definition.hasOwnProperty("min")) {
+ definition.min = 0;
+ }
+
+ if (!definition.hasOwnProperty("max")) {
+ definition.max = 1;
+ }
+
+ if (!definition.hasOwnProperty("automatable")) {
+ definition.automatable = true;
+ }
+
+ if (!definition.hasOwnProperty("dfault")) {
+ definition.dfault = 1;
+ }
+
+
+ if (parent && definition.hostrange) {
+ for (var o of ["step", "min", "max", "dfault", "options", "condition", "hostrange"]) {
+ if (parent.definition.hasOwnProperty(o)) {
+ definition[o] = parent.definition[o];
+ }
+ }
+ }
+
+ this.refresh = function() {
+ if (!refreshable) {
+ return;
+ }
+ for (var k in definition.conditions) {
+ var c = definition.conditions[k];
+ var val = transform.parameters[transform.instr + "_" + c.channel].getValue();
+ if (
+ (c.operator == "eq" && val != c.value) ||
+ (c.operator == "lt" && val >= c.value) ||
+ (c.operator == "gt" && val <= c.value) ||
+ (c.operator == "le" && val > c.value) ||
+ (c.operator == "ge" && val < c.value)
+ ) {
+ applicable = false;
+ }
+ }
+ applicable = true;
+ };
+
+ this.setDefault = function() {
+ value = definition.dfault;
+ };
+
+ if (initval) {
+ self.setDefault();
+ }
+
+ this.getAutomationData = function() {
+ if (!self.modulation) return;
+ var m = twist.appdata.modulations[self.modulation];
+ return [m.instr, self.channel];
+ };
+
+ function showModulations() {
+ modulationShown = true;
+ elValueLabel.hide();
+ elInput.hide();
+ elModulations.show();
+ elModButton.text("Close");
+ if (elModulations.children().length != 0) {
+ elModSelect.val(0).trigger("change");
+ return;
+ }
+ var tb = $("<tbody />");
+ function buildModulation(i) {
+ tb.empty();
+ modulationParameters = [];
+ self.modulation = i;
+ let m = twist.appdata.modulations[i];
+ for (let x of m.parameters) {
+ var tp = new twst.Parameter(m.instr, x, self, transform, twist);
+ modulationParameters.push(tp);
+ tb.append(tp.getElementRow(true)); // hmm modulate the modulation with false
+ }
+ }
+ var selecttb = $("<tbody />").appendTo($("<table />)").appendTo(elModulations));
+ var row = $("<tr />").append($("<td />").text("Modulation type")).appendTo(selecttb);
+
+ elModSelect = $("<select />").change(function() {
+ self.modulation = $(this).val();
+ buildModulation(self.modulation);
+ automation.push(self);
+ }).appendTo($("<td />").appendTo(row));
+ $("<table />").append(tb).appendTo(elModulations);
+
+ for (let i in twist.appdata.modulations) {
+ var m = twist.appdata.modulations[i];
+ $("<option />").text(m.name).val(i).appendTo(elModSelect);
+ }
+ elModSelect.val(0).trigger("change");
+ }
+
+};
+
+function getTransformContainer(name) {
+ return $("<div />").addClass("tfv_container").append(
+ $("<div />").addClass("tfv_header").text(name)
+ );
+}
+
+twst.ParameterGroup = function(def, instance, twist) {
+ var self = this;
+ this.instr = def.instr;
+ this.refreshable = false;
+ var presetParameters;
+ this.parameters = {};
+
+ if (def.hasOwnProperty("preset") && def.preset == "pvsynth") {
+ var conditions = [
+ {channel: "pvresmode", operator: "eq", value: 1}
+ ];
+ presetParameters = [
+ {name: "Resynth mode", channel: "pvresmode", description: "Type of FFT resynthesis used", dfault: 0, options: ["Overlap-add", "Additive"], automatable: false},
+ {name: "Oscillator spread", channel: "pvaoscnum", description: "Number of oscillators used", automatable: false, conditions: conditions},
+ {name: "Frequency modulation", channel: "pvafreqmod", description: "Frequency modulation", dfault: 1, min: 0.01, max: 2, conditions: conditions},
+ {name: "Oscillator offset", channel: "pvabinoffset", description: "Oscillator bin offset", automatable: false, conditions: conditions},
+ {name: "Oscillator increment", channel: "pvabinoffset", description: "Oscillator bin increment", min: 1, max: 32, dfault: 1, step: 1, automatable: false, conditions: conditions}
+ ];
+ }
+
+ this.refresh = function() {
+ if (!self.refreshable) {
+ return;
+ }
+ for (var k in self.parameters) {
+ self.parameters[k].refresh();
+ }
+ };
+
+ this.getAutomationData = function() {
+ var automations = [];
+ for (var k in self.parameters) {
+ var data = self.parameters[k].getAutomationData();
+ if (data) {
+ automations.push(data);
+ }
+ }
+ return automations;
+ };
+
+ this.removeParameter = function(channel) {
+ if (self.parameters.hasOwnProperty(channel)) {
+ self.parameters[channel].remove();
+ delete self.parameters[channel]
+ }
+ };
+
+ this.addParameter = function(pdef) {
+ var tp = new twst.Parameter(def.instr, pdef, null, self, twist);
+ self.parameters[tp.channel] = tp;
+ return tp;
+ };
+
+ function build() {
+ getTransformContainer(def.name).appendTo(elContainer);
+
+ var tbl = $("<table />").appendTo(elContainer);
+ elTb = $("<tbody />").appendTo(tbl);
+
+ for (let p of def.parameters) {
+ self.addParameter(p);
+ }
+
+ if (presetParameters) {
+ for (let p of presetParameters) {
+ self.addParameter(p);
+ }
+ }
+ self.refresh();
+ }
+ build();
+};
+
+
+var Transform = function(definition, instance, twist) {
+ var parameterGroup = new ParameterGroup(definition, instance, twist);
+
+ Object.defineProperty(this, "parameterGroup", {
+ get: function() { return parameterGroup; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "parameters", {
+ get: function() { return parameterGroup.parameters; },
+ set: function(x) {}
+ });
+
+
+ function handleAutomation(onready) {
+ if (transform) {
+ var automations = transform.getAutomationData();
+ if (automations && automations.length > 0) {
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ onready(1);
+ } else {
+ return twist.errorHandler("Cannot parse automation data");
+ }
+ });
+ var call = [0, 1, cbid];
+ for (let i in automations) {
+ call.push(automations[i][0] + " \\\"" + automations[i][1] + "\\\"");
+ }
+ twist.csapp.insertScore("twst_automationprepare", call);
+ } else {
+ onready(0);
+ }
+ }
+ }
+
+ this.audition = function(start, end, timeUnit) {
+ if (twist.isProcessing || twist.inUse) return twist.errorHandler("Already in use");
+ errorState = "Playback error";
+
+ if (!start) {
+ start = instance.selection.ratio[0];
+ end = instance.selection.ratio[1];
+ } else {
+ if (!timeUnit) timeUnit = "seconds");
+ start = timeConvert(start, timeUnit);
+ end = timeConvert(end, timeUnit);
+ }
+
+ handleAutomation(function(automating){
+var cbid = playPositionHandler();
+ operation({
+ instr: "twst_audition",
+ score: [start, end, instance.selectedChannel, definition.instr, automating]
+ });
+
+
+
+ });
+
+ };
+
+ this.commit = function(start, end, timeUnitPos, crossfadeIn, crossfadeOut, timeUnitCrossfade) {
+ if (twist.isProcessing || twist.inUse) return twist.errorHandler("Already in use");
+ handleAutomation(function(automating){
+ if (!start) {
+ start = instance.selection.start.ratio;
+ end = instance.selection.end.ratio;
+ } else {
+ if (!timeUnitPos) timeUnitPos = "seconds");
+ start = timeConvert(start, timeUnitPos);
+ end = timeConvert(end, timeUnitPos);
+ }
+
+ if (!crossfadeIn) {
+ crossfadeIn = instance.selection.ratio[0];
+ crossfadeOut = instance.selection.ratio[1];
+ } else {
+ if (!timeUnitPos) timeUnitPos = "seconds");
+ crossfadeIn = timeConvert(start, timeUnitPos);
+ crossfadeOut = timeConvert(end, timeUnitPos);
+ }
+
+ errorState = "Transform commit error";
+ operation({
+ instr: "twst_commit",
+ refresh: true,
+ score: [start, end, instance.selectedChannel, definition.instr, automating, instance.crossFade.start.ratio, instance.crossFade.end.ratio]
+ });
+
+ });
+ };
+};
+
+
+
+
+
+var TwistInstance = function(instanceIndex, twist, options) {
+ var self = this;
+ if (!options) options = {};
+ var transform;
+ var channels;
+ var durationSamples;
+ var selectedChannel = -1;
+ var filename;
+ var sr;
+ var csTables = [];
+
+ var Time = function(dfault, onValidate, onChange) {
+ var tself = this;
+ var value = dfault;
+
+ Object.defineProperty(this, "samples", {
+ get: function() { return value; },
+ set: function(v) {
+ if (value == v) return;
+ value = v;
+ if (onValidate) {
+ var res = onValidate(value);
+ if (res) {
+ value = res;
+ }
+ }
+ if (onChange) onChange(tself);
+ }
+ });
+
+ Object.defineProperty(this, "seconds", {
+ get: function() { return value / sr; },
+ set: function(v) {
+ tself.samples = Math.round(v * sr);
+ }
+ });
+
+ Object.defineProperty(this, "ratio", {
+ get: function() { return value / durationSamples; },
+ set: function(v) {
+ tself.samples = Math.round(v * durationSamples);
+ }
+ });
+ };
+
+ var playPosition = new Time(0);
+ var selection = new Time({start: 0, end: 0}, function(v) {
+ if (typeof(v) != "object") {
+ v = {start: v, end: v};
+ return v;
+ }
+ if (v.start > v.end) {
+ v.start = v.end
+ }
+ if (v.end > durationSamples) {
+ v.end = durationSamples);
+ }
+ }, options.onSelectionChange);
+
+ var crossFade = new Time({start: 0, end: 0}, function(v) {
+ iif (typeof(v) != "object") {
+ v = {start: v, end: v};
+ return v;
+ }
+ var half = Math.round(durationSamples * 0.5);
+ if (v.start > half) {
+ v.start = half;
+ }
+ if (v.end > half) {
+ v.end = half;
+ }
+ }, options.onCrossFadeChange);
+
+
+ Object.defineProperty(this, "selectedChannel", {
+ get: function() { return selectedChannel; },
+ set: function(v) {
+ if (channels == 1) return;
+ if (v >= channels) {
+ selectedChannel = channels - 1;
+ } else if (v < 0) {
+ selectedChannel = 0;
+ } else {
+ selectedChannel = v;
+ }
+ }
+ });
+
+ Object.defineProperty(this, "playPosition", {
+ get: function() { return playPosition; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "selection", {
+ get: function() { return selection; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "crossFade", {
+ get: function() { return crossFade; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "instanceIndex", {
+ get: function() { return instanceIndex; },
+ set: function(v) {}
+ });
+
+ var durationObj;
+ Object.defineProperty(durationObj, "samples", {
+ get: function() { return durationSamples; },
+ set: function(v) {}
+ });
+ Object.defineProperty(durationObj, "seconds", {
+ get: function() { return durationSamples / sr; },
+ set: function(v) {}
+ });
+ Object.defineProperty(this, "duration", {
+ get: function() { return durationObj; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "filename", {
+ get: function() { return filename; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "sr", {
+ get: function() { return sr; },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "csTables", {
+ get: function() { return csTables; },
+ set: function(v) {}
+ });
+
+
+ function refresh(data) {
+ twist.errorState = "Overview refresh error";
+ csTables = [data.waveL];
+ if (data.hasOwnProperty("waveR")) {
+ csTables.push(data.waveR);
+ }
+ sr = data.sr;
+ durationSamples = Math.round(data.sr * data.duration);
+ if (options.onRefresh) options.onRefresh(self);
+ }
+
+
+
+ function getTransform(path) {
+ if (!twist.transforms.hasOwnProperty(path)) {
+ return;
+ }
+ return new ParameterGroup(transforms[path], self, twist);
+ }
+
+
+ function operation(data) {
+ if (!data.setUsage) data.setUsage = true;
+ if (!data.setProcessing) data.setProcessing = true;
+ if (twist.inUse || twist.isProcessing) {
+ return twist.errorHandler("Already processing");
+ }
+
+ var score = [0, -1];
+ if (!data.noCallback) {
+ cbid = twist.csapp.createCallback(function(ndata){
+ if (data.refresh) refresh();
+ if (data.onComplete) data.onComplete(ndata);
+ if (data.setUsage) twist.inUse = false;
+ if (data.setProcessing) twist.isProcessing = false;
+ });
+ score.push(cbid);
+ if (data.setUsage) twist.inUse = true;
+ if (data.setProcessing) twist.isProcessing = true;
+ }
+ if (data.onRun) options.onRun();
+ if (data.score) {
+ for (s of data.score) {
+ score.push(s);
+ }
+ }
+
+ twist.csapp.insertScore(data.instr, score);
+ } // operation
+
+ function loadFile(name) {
+ var cbid = twist.csapp.createCallback(async function(ndata){
+ await app.getCsound().fs.unlink(name);
+ if (ndata.status == 0) {
+ return twist.errorHandler("File not valid");
+ } else {
+ refresh(ndata);
+ }
+ twist.inUse = false;
+ twist.isProcessing = false;
+ });
+ twist.inUse = true;
+ twist.isProcessing = true;
+ app.insertScore("twst_loadfile", [0, -1, cbid, item.name]);
+ }
+
+ this.loadUrl = function(url, onLoad) {
+ twist.csapp.loadFile(url, loadFile);
+ };
+
+ this.loadBuffer = function(arrayBuffer, onLoad) {
+ twist.csapp.loadBuffer(url, loadFile);
+ };
+
+ this.saveFile = function(name, onSave) {
+ if (!onSave) {
+ onSave = options.onSave;
+ }
+
+ if (!onSave) {
+ return twist.errorHandler("Instance or saveFile onSave option has not been provided");
+ }
+
+ twist.inUse = true;
+ twist.isProcessing = true;
+
+ if (!name) {
+ name = filename;
+ }
+ if (!name) {
+ name = "export.wav";
+ }
+
+ if (!name.toLowerCase().endsWith(".wav")) {
+ name += ".wav";
+ }
+ var cbid = twist.csapp.createCallback(async function(ndata){
+ var content = await twist.csapp.getCsound().fs.readFile(name);
+ var blob = new Blob(content, {type: "audio/wav"});
+ var url = window.URL.createObjectURL(blob);
+ onSave(url);
+ twist.inUse = false;
+ twist.isProcessing = false;
+ });
+ twist.csapp.insertScore("twst_savefile", [0, -1, cbid, name]);
+ };
+
+ function timeConvert(val, mode) { // returns ratio right now
+ if (mode == "ratio") {
+ return val;
+ } else if (mode == "samples") {
+ return val / durationSamples;
+ } else if (mode == "seconds") {
+ return val / (durationSamples / sr);
+ }
+ }
+
+ this.cut = function(start, end, timeUnit) {
+ if (!start) {
+ start = self.selection.ratio[0];
+ end = self.selection.ratio[1];
+ } else {
+ if (!timeUnit) timeUnit = "seconds");
+ start = timeConvert(start, timeUnit);
+ end = timeConvert(end, timeUnit);
+ }
+ operation({
+ instr: "twst_cut",
+ score: [start, end, selectedChannel],
+ refresh: true,
+ });
+ };
+
+ this.copy = function(start, end, timeUnit) {
+ if (!start) {
+ start = self.selection.ratio[0];
+ end = self.selection.ratio[1];
+ } else {
+ if (!timeUnit) timeUnit = "seconds");
+ start = timeConvert(start, timeUnit);
+ end = timeConvert(end, timeUnit);
+ }
+ operation({
+ instr: "twst_copy",
+ score: [start, end, selectedChannel],
+ });
+ };
+
+ this.paste = function(start, end, timeUnit) {
+ if (!start) {
+ start = self.selection.ratio[0];
+ end = self.selection.ratio[1];
+ } else {
+ if (!timeUnit) timeUnit = "seconds");
+ start = timeConvert(start, timeUnit);
+ end = timeConvert(end, timeUnit);
+ }
+ operation({
+ instr: "twst_paste",
+ score: [start, end, selectedChannel],
+ });
+ };
+
+ this.pasteSpecial = function(start, end, timeUnit) {
+ pasteSpecial: {instr: "twst_pastespecial", refresh: true, parameters: [
+ {name: "Repetitions", channel: "repetitions", min: 1, max: 40, step: 1, dfault: 1, automatable: false},
+ {name: "Repetition random time variance ratio", channel: "timevar", min: 0, max: 1, step: 0.000001, dfault: 0, automatable: false},
+ {name: "Mix paste", channel: "mixpaste", step: 1, dfault: 0, automatable: false},
+ {name: "Mix crossfade", channel: "mixfade", automatable: false, conditions: [{channel: "mixpaste", operator: "eq", value: 1}]}
+ ]},
+ };
+
+ this.play = function(start, end, timeUnit) {
+ errorState = "Playback error";
+ if (!start) {
+ start = self.selection.ratio[0];
+ end = self.selection.ratio[1];
+ } else {
+ if (!timeUnit) timeUnit = "seconds");
+ start = timeConvert(start, timeUnit);
+ end = timeConvert(end, timeUnit);
+ }
+ operation({
+ instr: "twst_play",
+ score: [start, end, selectedChannel],
+ });
+ };
+
+ this.stop = function() {
+ operation({
+ instr: "twst_stop"
+ });
+ };
+
+
+
+
+
+
+
+
+
+};
+
+
+var Twist = function(options) {
+ var twist = this;
+ var inUse = false;
+ var isProcessing = false;
+ var instanceIndex = 0;
+ var instances = [];
+ var transforms;
+ var modulations;
+ var onRunFunc;
+ this.errorState = null;
+
+ if (!options) options = {};
+
+ if (!options.appdata) {
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", "appdata.json", false);
+ xhr.send();
+ if (xhr.status == 200) {
+ options.appdata = JSON.parse(xhr.responseText);
+ } else {
+ throw "No appdata available";
+ }
+ }
+
+ function errorHandlerInner(error, func) {
+ if (!error && twist.errorState) {
+ error = twist.errorState;
+ twist.errorState = null;
+ } elseif (!error && !twist.errorState) {
+ error = "Unhandled error";
+ }
+ func(error);
+ }
+
+ this.errorHandler = function(error) {
+ if (!error && twist.errorState) {
+ error = twist.errorState;
+ twist.errorState = null;
+ } elseif (!error && !twist.errorState) {
+ error = "Unhandled error";
+ }
+ if (options.errorHandler) {
+ options.errorHandler(error);
+ } else {
+ throw error;
+ }
+ };
+
+ this.setPercent = function(percent) {
+ if (options.onPercentChange) {
+ options.onPercentChange(percent);
+ }
+ };
+
+ if (!csapp) {
+ csapp = new CSApplication({
+ csdUrl: "twist.csd",
+ csOptions: ["--omacro:TWST_FAILONLAG=1"],
+ onPlay: function () {
+ if (onRunFunc) onRunFunc();
+ },
+ errorHandler: options.errorHandler,
+ ioReceivers: {percent: twist.setPercent}
+ });
+ }
+
+
+ Object.defineProperty(this, "csapp", {
+ get: function() {
+ return csapp;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "instances", {
+ get: function() {
+ return instances;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "transforms", {
+ get: function() {
+ return transforms;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "modulations", {
+ get: function() {
+ return modulations;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "appdata", {
+ get: function() {
+ return options.appdata;
+ },
+ set: function(v) {}
+ });
+
+ Object.defineProperty(this, "inUse", {
+ get: function() {
+ return inUse;
+ },
+ set: function(v) {
+ if (inUse != v) {
+ inUse = v;
+ if (options.onUsage) options.onUsage(v);
+ }
+ }
+ });
+
+ Object.defineProperty(this, "isProcessing", {
+ get: function() {
+ return isProcessing;
+ },
+ set: function(v) {
+ if (isProcessing != v) {
+ isProcessing = v;
+ if (options.onUsage) options.onUsage(v);
+ }
+ }
+ });
+
+ this.run = function(onRunFunc) {
+ onRunFunc = onRun;
+ csapp.play();
+ };
+
+ this.createInstance = function() {
+ var instance = new TwistInstance(instanceIndex, twist, options.instance);
+ instances[instanceIndex] = instance;
+ instanceIndex ++;
+ return instance;
+ };
+
+ this.removeInstanceByIndex = function(index) {
+ if (i < 0 || i > instances.length - 2) return;
+ delete instances[index];
+ };
+
+ function getProcesses(appdata, type) {
+ var processes = {};
+
+ function recurse(items, prefix) {
+ if (!prefix) {
+ prefix = "/";
+ }
+ for (let item of items) {
+ if (item.hasOwnProperty("contents")) {
+ var subitems = recurse(item.contents, prefix + item.name + "/");
+ } else {
+ processes[prefix + item.name] = item;
+ }
+ }
+ }
+ recurse(appdata[type]);
+ return processes;
+ }
+
+ transforms = getProcesses(options.appdata, "transforms");
+ modulations = getProcesses(options.appdata, "modulations");
+
+};
+
+
+
+
+
+
+
+
+
+
+
+window.t = new Twist({
+ csapp: null,
+ appdata: null,
+ latencyCorrection: 170,
+ onPercentChange,
+ onProcessing: state => {
+
+ },
+ onUsage: state => {
+
+ },
+ instance: {
+
+ onPlayPositionChange: position => {
+
+ },
+ onSelectionChange: selection => {
+
+ },
+ onCrossFadeChange: crossfades => {
+
+ },
+ onRefresh: () => {
+
+ },
+ onPlay: () => {
+
+ },
+ onSave: () => {
+
+ }
+ }
+});
+
+
+
+
+
+
+$("#start_invoke").click(function(){
+ $("#loading").show();
+ t.run(function(){
+ $("#start").hide();
+ $("#loading").hide();
+ });
+});
+
+
diff --git a/site/app/twist/_unlive/index.api.html b/site/app/twist/_unlive/index.api.html new file mode 100644 index 0000000..80c5eb9 --- /dev/null +++ b/site/app/twist/_unlive/index.api.html @@ -0,0 +1,1144 @@ +<html>
+ <head>
+ <title>twist</title>
+ <script type="text/javascript" src="/code/jquery.js"></script>
+ <script type="text/javascript" src="../base/base.js"></script>
+ <script type="text/javascript" src="../base/waveform.js"></script>
+ <script type="text/javascript">
+
+
+ var TransformParameterUI = function(instr, definition, parent, transform, twist) {
+ var self = this;
+ var parameter = twist.Parameter(instr, definition, transform, twist);
+ var initval = true;
+ var elContainer = $("<div />");
+ var elValueLabel = $("<div />");
+ var elValueInput;
+ var elModulations;
+ var elInput;
+ var elRow;
+ var elModSelect;
+
+ this.refresh = function() {
+ if (!refreshable) {
+ return;
+ }
+ parameter.refresh();
+
+ if (definition.preset == "instance") {
+ createSelectOptions(elInput, twist.otherInstanceNames);
+ }
+ if (parameter.applicable) {
+ elRow.show();
+ } else {
+ elRow.hide();
+ }
+ };
+
+ function createSelectOptions(elSelect, options) {
+ elSelect.empty();
+ var selected = elInput.val();
+ for (var x in options) {
+ var opt = $("<option />").text(options[x]).val(x).appendTo(elSelect);
+ if (x == selected) {
+ opt.attr("selected", "1");
+ }
+ }
+ }
+
+ function updateLabel() {
+ if (elValueInput) {
+ var val = self.getValue();
+ updateinput = false;
+ elValueInput.val(val);
+ updateinput = true;
+ //elValueLabel.text(val);
+ }
+ }
+
+ if (type == "select") {
+ elInput = $("<select />").change(function(){
+ transform.refresh();
+ parameter.value = $(this).val();
+ if (changeFunc) changeFunc(parameter.value);
+ });
+ var options = (definition.hostrange) ? parent.definitions.options : definition.options;
+ createSelectOptions(elInput, options);
+ } else {
+ var updateinput = true;
+ var max = definition.max;
+ var min = definition.min;
+ var step = definition.step;
+ var dfault = definition.dfault;
+
+
+
+ elInput = $("<input />").attr("type", "range").on("input", function() {
+ updateLabel();
+ }).change(function() {
+ transform.refresh();
+ parameter.value = $(this).val();
+ }).attr("min", min).attr("max", max).attr("step", step).val(dfault);
+
+ elValueInput = $("<input />").attr("type", "number").attr("min", min).attr("max", max).attr("step", step).addClass("transparentinput").appendTo(elValueLabel).change(function() {
+ if (updateinput) {
+ elInput.val($(this).val()).trigger("change").trigger("input");
+ }
+ });
+ }
+
+ elContainer.append(elInput);
+ if (initval) {
+ elInput.val(definition.dfault).trigger("change");
+ updateLabel();
+ }
+
+
+ this.setDefault = function() {
+ elInput.val(definition.dfault).trigger("change");
+ //app.setControlChannel(channel, definition.dfault);
+ };
+
+ this.remove = function() {
+ elContainer.remove();
+ };
+
+ this.getAutomationData = function() {
+ if (!self.modulation) return;
+ var m = twist.appdata.modulations[self.modulation];
+ return [m.instr, self.channel];
+ };
+
+ var elAutomation = $("<button />").text("Automate").click(function() {
+
+ });
+
+ var modulationShown = false;
+ var elModButton = $("<button />").text("Modulate").click(function() {
+ if (elModulations && modulationShown) {
+ hideModulations();
+ } else {
+ showModulations();
+ }
+ });
+
+ function hideModulations() {
+ app.setControlChannel(channel, self.getValue());
+ modulationShown = false;
+ elValueLabel.show();
+ elInput.show();
+ self.modulation = null;
+ elModButton.text("Modulate");
+ if (elModulations) {
+ elModulations.hide();
+ if (automation.includes(self)) {
+ delete automation[automation.indexOf(self)];
+ }
+ }
+ }
+
+
+ elModulations = $("<div />").addClass("tfv_container").hide().appendTo(elContainer);
+
+ function showModulations() {
+ modulationShown = true;
+ elValueLabel.hide();
+ elInput.hide();
+ elModulations.show();
+ elModButton.text("Close");
+ if (elModulations.children().length != 0) {
+ elModSelect.val(0).trigger("change");
+ return;
+ }
+ var tb = $("<tbody />");
+ function buildModulation(i) {
+ tb.empty();
+ modulationParameters = [];
+ self.modulation = i;
+ let m = twist.appdata.modulations[i];
+ for (let x of m.parameters) {
+ var tp = new TransformParameter(m.instr, x, self, transform, twist);
+ modulationParameters.push(tp);
+ tb.append(tp.getElementRow(true)); // hmm modulate the modulation with false
+ }
+ }
+ var selecttb = $("<tbody />").appendTo($("<table />)").appendTo(elModulations));
+ var row = $("<tr />").append($("<td />").text("Modulation type")).appendTo(selecttb);
+
+ elModSelect = $("<select />").change(function() {
+ self.modulation = $(this).val();
+ buildModulation(self.modulation);
+ automation.push(self);
+ }).appendTo($("<td />").appendTo(row));
+ $("<table />").append(tb).appendTo(elModulations);
+
+ for (let i in twist.appdata.modulations) {
+ var m = twist.appdata.modulations[i];
+ $("<option />").text(m.name).val(i).appendTo(elModSelect);
+ }
+ elModSelect.val(0).trigger("change");
+ }
+
+ this.getElementRow = function(nocontrols) {
+ if (elRow) {
+ return elRow;
+ }
+ elRow = $("<tr />");
+ $("<td />").addClass("tfv_cell").text(definition.name).appendTo(elRow);
+ $("<td />").addClass("tfv_cell").append(elContainer).appendTo(elRow);
+ $("<td />").addClass("tfv_cellfixed").append(elValueLabel).appendTo(elRow);
+ if (!nocontrols) {
+ if (definition.automatable) {
+ $("<td />").addClass("tfv_cell").append(elAutomation).appendTo(elRow);
+ $("<td />").addClass("tfv_cell").append(elModButton).appendTo(elRow);
+ }
+ }
+ return elRow;
+ };
+
+
+ this.automate = function(start, end) {
+ app.insertScore("twst_createautomation", []);
+ };
+ };
+
+ function getTransformContainer(name) {
+ return $("<div />").addClass("tfv_container").append(
+ $("<div />").addClass("tfv_header").text(name)
+ );
+ }
+
+ var TransformUI = function(target, def, twist) {
+ var self = this;
+ var transform = new Transform(target, def, twist);
+ var elContainer = $("<div />").addClass("tfv_container").appendTo(target);
+ var elTb;
+ var pAddOdd = true;
+ this.uiparameters = [];
+ this.instr = def.instr;
+ this.refreshable = false;
+
+
+ this.refresh = function() {
+ if (!self.refreshable) {
+ return;
+ }
+ for (var k in self.uiparameters) {
+ self.uiparameters[k].refresh();
+ }
+ };
+
+ this.getAutomationData = function() {
+ return transform.getAutomationData();;
+ };
+
+ this.removeParameter = function(channel) {
+ if (self.uiparameters.hasOwnProperty(channel)) {
+ self.uiparameters[channel].remove();
+ delete self.uiparameters[channel]
+ }
+ transform.parameterGroup.removeParameter(channel);
+ };
+
+ this.addParameter = function(definition) {
+ self.addParameterUI(transform.parameterGroup.addParameter(definition));
+ };
+
+ this.addParameterUI = function(parameter) {
+ var tp = new TransformParameterUI(def.instr, parameter, null, self, twist);
+ self.uiparameters[tp.channel] = tp;
+ elTb.append(tp.getElementRow().addClass("tfv_row_" + ((pAddOdd) ? "odd" : "even")));
+ pAddOdd = !pAddOdd;
+ };
+
+ function build() {
+ getTransformContainer(def.name).appendTo(elContainer);
+
+ var tbl = $("<table />").appendTo(elContainer);
+ elTb = $("<tbody />").appendTo(tbl);
+
+ for (let p of transform.parameters) {
+ self.addParameter(p);
+ }
+ self.refresh();
+ }
+ build();
+ };
+
+ var TransformsTreeView = function(options, twist) {
+ var self = this;
+ var elTarget = $("#" + options.target);
+
+
+ function recurse(items, descended) {
+ items = (items) ? items : options.items;
+ var ul = $("<ul />").css({"border-bottom": "1px solid #878787", "padding-inline-start": 10}).addClass((descended) ? "nested" : "treelist");
+
+ for (let k in items) {
+ var li = $("<li />");
+ if (items[k].hasOwnProperty("contents")) {
+ $("<span />").addClass("caret").text(items[k].name).click(function() {
+ $(this).parent().children(".nested").toggleClass("active");
+ $(this).toggleClass("caret-down");
+ }).appendTo(li);
+ var subitems = recurse(items[k].contents, true);
+ li.append(subitems);
+
+ } else {
+ li.text(items[k].name).css("cursor", "pointer").click(function(){
+ var el = $("#controls").empty();
+ if (items[k].hasOwnProperty("display")) {
+ var container = getTransformContainer(items[k].name).appendTo(el);
+ twist.currentTransform = items[k].display(container);
+ } else {
+ twist.currentTransform = new Transform(el, items[k], twist);
+ }
+ });
+ }
+ ul.append(li);
+ }
+ elTarget.append(ul);
+ return ul;
+ }
+
+ elTarget.append(recurse());
+ };
+
+
+
+
+ var TwistUI = function(options) {
+ var self = this;
+ var toptions = {
+ errorHandler: function(text) {
+ self.showPrompt(text);
+ },
+ onProcessing: function(state) {
+
+ },
+ onUsage: function(state) {
+ self.waveform.cover(state);
+ }
+ };
+ var twist = new Twist(options);
+ var audioTypes = ["audio/mpeg", "audio/mp4", "audio/ogg", "audio/vorbis", "audio/x-flac","audio/aiff","audio/x-aiff", "audio/vnd.wav", "audio/wave", "audio/x-wav", "audio/wav"];
+ var maxsize = 1e+8; // 100 MB
+
+ var instanceIndex = 0;
+ this.stoptoggle = null;
+ this.waveforms = [];
+ var waveformTabs = [];
+ var keyModifier = {shift: false, alt: false, ctrl: false};
+ var playheadInterval;
+ var playing = false;
+ var elCrossfades = [];
+ var elPasteSpecial;
+
+ if (!options) options = {};
+ if (!options.latencyCorrection) options.latencyCorrection = 0;
+
+ function newInstance() {
+ var instance = twist.createInstance();
+ var element = $("<div />").addClass("waveform").appendTo("#waveforms");
+ let index = self.waveforms.length;
+ if (index < 0) index = 0;
+ waveformTabs.push(
+ $("<td />").text("New file").click(function() {
+ self.waveform = index;
+ }).addClass("wtab_selected").appendTo("#waveform_tabs")
+ );
+
+ self.waveforms.push(
+ new Waveform({target: element, latencyCorrection: options.latencyCorrection, showcrossfades: true})
+ );
+
+ self.waveform = index;
+ }
+
+ function removeInstance(i) {
+ if (i < 0 || i > this.waveforms.length - 2) {
+ return;
+ }
+ self.waveform.destroy();
+ twist.removeInstanceByIndex(i);
+ if (instanceIndex == i) {
+ instanceIndex = i + ((i == 0) ? 1 : -1);
+ self.waveform.show();
+ }
+ }
+
+ this.setPercent = function(percent) {
+ $("#loading_percent_inner").width(percent + "%");
+ };
+
+
+ function setLoadingStatus(state, showpercent) {
+ var el = $("#loading");
+ if (state) {
+ el.show();
+ if (showpercent) {
+ $("#loading_percent").show();
+ } else {
+ $("#loading_percent").hide();
+ }
+ } else {
+ el.hide();
+ }
+ }
+
+ this.setLoadingStatus = setLoadingStatus;
+
+ this.showPrompt = function(text, oncomplete) {
+ setLoadingStatus(false);
+ $("#prompt").show();
+ $("#prompt_text").text(text);
+ $("#prompt_button").unbind().click(function(){
+ if (oncomplete) {
+ oncomplete();
+ }
+ $("#prompt").hide();
+ });
+ };
+
+
+ function playPositionHandler(noPlayhead) {
+ function callback(ndata) {
+ if (ndata.status == 1) {
+ playing = true;
+ if (!noPlayhead) {
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ playheadInterval = setInterval(async function(){
+ var val = await app.getControlChannel("playposratio");
+ if (val < 0 || val >= 1) {
+ clearInterval(playheadInterval);
+ }
+ self.waveform.movePlayhead(val);
+ }, 50);
+ }
+ } else {
+ playing = false;
+ if (ndata.status == -1) {
+ self.errorHandler("Not enough processing power to transform in realtime");
+ }
+ if (self.stoptoggle) {
+ setTimeout(self.stoptoggle, latencyCorrection);
+ }
+ app.removeCallback(ndata.cbid);
+ if (!noPlayhead) {
+ self.waveform.movePlayhead(0);
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ }
+ self.waveform.cover(false);
+ }
+ }
+ return app.createCallback(callback, true);
+ }
+
+
+
+ async function refreshOverviews(ndata) {
+ errorState = "Overview refresh error";
+ var wavedata = [];
+ var duration = ndata.duration;
+
+ wavedata.push(async function(v) {
+ if (v < 0) {
+ return await app.getCsound().tableLength(ndata.waveL);
+ } else {
+ return await app.getCsound().tableGet(ndata.waveL, v);
+ }
+ });
+
+ if (ndata.hasOwnProperty("waveR")) {
+ wavedata.push(async function(v) {
+ return await app.getCsound().tableGet(ndata.waveR, v);
+ });
+ }
+ self.waveform.setData(wavedata, ndata.duration);
+
+ self.waveform.cover(false);
+ }
+
+ this.cut = function() {
+ self.instance.cut();
+ };
+
+ this.copy = function() {
+ self.instance.copy();
+ };
+
+ this.paste = function() {
+ self.instance.paste();
+ };
+
+ this.moveToStart = function() {
+ self.waveform.setSelection(0);
+ };
+
+ this.moveToEnd = function() {
+ self.waveform.setSelection(1);
+ };
+
+
+ this.pasteSpecial = function() {
+ if (!elPasteSpecial) {
+ elPasteSpecial = $("<div />").addClass("waveform_overlay").appendTo($("#waveforms"));
+ elPasteSpecial.append($("<h2 />").text("Paste special"));
+ var def = {
+ instr: "twst_pastespecial",
+ parameters: [
+ {name: "Repetitions", channel: "repetitions", min: 1, max: 40, step: 1, dfault: 1, automatable: false},
+ {name: "Repetition random time variance ratio", channel: "timevar", min: 0, max: 1, step: 0.000001, dfault: 0, automatable: false},
+ {name: "Mix paste", channel: "mixpaste", step: 1, dfault: 0, automatable: false},
+ {name: "Mix crossfade", channel: "mixfade", automatable: false, conditions: [{channel: "mixpaste", operator: "eq", value: 1}]}
+ ]
+ };
+ var tf = new Transform(elPasteSpecial, def, self);
+
+ $("<button />").text("Paste").click(function(){
+ elPasteSpecial.hide();
+ self.waveform.cover(true);
+ operation("twst_pastespecial", refreshOverviews, true);
+ }).appendTo(elPasteSpecial);
+
+ } else {
+ elPasteSpecial.show();
+ }
+ };
+
+
+ this.play = function() {
+ self.instance.play();
+ };
+
+ this.stop = function() {
+ self.instance.stop();
+ };
+
+ this.saveFile = function(name) {
+ self.instance.saveFile(name, function(url) {
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a.click();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ app.getCsound().fs.unlink(name);
+ }, 2000);
+ });
+ };
+
+ this.audition = function() {
+ self.instance.audition();
+
+ };
+
+ this.commit = function() {
+ self.instance.commit();
+ }
+
+ function buildWavecontrols() {
+ var el = $("#wavecontrols_inner");
+ var items = [
+ {label: "Zoom sel", click: function() {self.waveform.zoomSelection();}},
+ {label: "Zoom in", click: function() {self.waveform.zoomIn();}},
+ {label: "Zoom out", click: function() {self.waveform.zoomOut();}},
+ {label: "Show all", click: function() {self.waveform.zoomLevel = 1;}},
+
+ {label: "Cut", click: self.cut, css: {"background-color": "#a5ab30"}},
+ {label: "Copy", click: self.copy, css: {"background-color": "#d5db60"}},
+ {label: "Paste", click: self.paste, css: {"background-color": "#e5df90"}},
+ {label: "Paste special", click: self.pasteSpecial, css: {"background-color": "#e9dfa5"}},
+
+ {label: "Play", click: function(b) {
+ self.stoptoggle = function() {
+ b.text("Play");
+ };
+ if (b.text() == "Play") {
+ b.text("Stop");
+ self.play();
+ } else {
+ b.text("Play");
+ self.stop();
+ }
+ }, css: {"background-color": "#cc9999"}},
+ {label: "Audition", click: function(b) {
+ self.stoptoggle = function() {
+ b.text("Audition");
+ };
+ if (b.text() == "Audition") {
+ b.text("Stop");
+ self.audition();
+ } else {
+ b.text("Audition");
+ self.stop();
+ }
+ }, css: {"background-color": "#aa6666"}},
+ {label: "Commit", click: self.commit, css: {"background-color": "#ff4444"}},
+ ];
+
+ for (let i of items) {
+ let button = $("<button />").text(i.label)
+ button.click(function() {
+ i.click(button);
+ });
+ if (i.hasOwnProperty("css")) {
+ button.css(i.css);
+ }
+ $("<td />").append(
+ button
+ ).appendTo(el);
+ }
+
+ for (let e of ["in", "out"]) {
+ var elRange = $("<input />").attr("type", "range").attr("min", 0).attr("max", 0.45).attr("step", 0.00001).val(0).on("input", function() {
+ if (e == "in") {
+ self.waveform.crossFadeInRatio = $(this).val();
+ } else {
+ self.waveform.crossFadeOutRatio = $(this).val();
+ }
+ });
+ elCrossfades.push(elRange);
+ $("<td />").append($("<div />").text("Commit crossfade " + e)).append(elRange).appendTo(el);
+ }
+ }
+
+ function createLeftPane() {
+ var el = $("<div />").addClass("treetop").appendTo($("#panetree"));
+ $("<div />").addClass("treetop_header").text("twist").appendTo(el);
+
+ var ttv = new TransformsTreeView({
+ target: "panetree",
+ items: appdata.transforms
+ }, self);
+ }
+
+ async function handleFileDrop(e, obj) {
+ e.preventDefault();
+ if (!e.originalEvent.dataTransfer.files) {
+ return;
+ }
+ twist.isProcessing = true;
+ for (const item of e.originalEvent.dataTransfer.files) {
+ //item.size;
+ //item.type "audio/mpeg";
+ if (!audioTypes.includes(item.type)) {
+ return self.errorHandler("Unsupported file type");
+ }
+ if (item.size > maxsize) {
+ return self.errorHandler("File too big");
+ }
+ twist.errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ self.instance.loadBuffer(content, function(ndata){
+ self.waveformTab.text(item.name);
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ });
+ }
+ }
+
+ this.run = function() {
+ twist.run();
+
+ Object.defineProperty(this, "waveformTab", {
+ get: function() { return waveformTabs[instanceIndex]; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "otherInstanceNames", {
+ get: function() {
+ var data = {};
+ for (var i in waveformTabs) {
+ if (i != instanceIndex) {
+ data[i] = waveformTabs[i].text();
+ }
+ }
+ return data
+ },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "waveform", {
+ get: function() { return self.waveforms[instanceIndex]; },
+ set: function(x) {
+ if (instanceIndex != x) {
+ self.waveformTab.removeClass("wtab_selected").addClass("wtab_unselected");
+ self.waveform.hide();
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ instanceIndex = x;
+ self.waveformTab.removeClass("wtab_unselected").addClass("wtab_selected");
+ self.waveform.show();
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ } else {
+ self.showPrompt("Error changing instance");
+ }
+ });
+ app.insertScore("twst_setinstance", [0, 1, cbid, x]);
+
+ }
+ }
+ });
+
+ $("<td />").text("+").click(function() {
+ newInstance();
+ }).appendTo("#waveform_tabs").addClass("wtab_selected");
+
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ }).on("drop", function(e) {
+ handleFileDrop(e, self);
+ }).on("keydown", function(e){
+ switch (e.which) {
+ case 32: // space
+ if (playing) {
+ self.stop();
+ } else {
+ self.play;
+ }
+ break;
+ case 13: // enter
+ if (keyModifier.alt) self.commit();
+ break;
+ case 67: // c
+ if (keyModifier.ctrl) self.copy();
+ break;
+ case 88: // x
+ if (keyModifier.ctrl) self.cut();
+ break;
+ case 86: // v
+ if (keyModifier.ctrl) {
+ if (keyModifier.shift) {
+ self.pasteSpecial();
+ } else {
+ self.paste();
+ }
+ }
+ break;
+ case 17:
+ keyModifier.ctrl = true;
+ break;
+ case 18:
+ keyModifier.alt = true;
+ break;
+ case 16:
+ keyModifier.shift = true;
+ break;
+ default:
+ return;
+ }
+ e.preventDefault();
+ }).on("keyup", function(e){
+ switch (e.which) {
+ case 17:
+ keyModifier.ctrl = false;
+ break;
+ case 18:
+ keyModifier.alt = false;
+ break;
+ case 16:
+ keyModifier.shift = false;
+ break;
+ default:
+ return;
+ }
+ e.preventDefault();
+ });
+
+ newInstance();
+ buildWavecontrols();
+ createLeftPane();
+ };
+
+ }; // end twist
+
+ $(function() {
+ window.twist = new Twist(appdata);
+ window.app = new CSApplication({
+ csdUrl: "twist.csd",
+ csOptions: ["--omacro:TWST_FAILONLAG=1"],
+ onPlay: function () {
+ twist.setLoadingStatus(false);
+ },
+ errorHandler: twist.errorHandler,
+ ioReceivers: {percent: twist.setPercent}
+ });
+
+ $("#start_invoke").click(function() {
+ $("#start").hide();
+ twist.run();
+ twist.setLoadingStatus(true);
+ app.play();
+ });
+
+ });
+
+
+ </script>
+ <style type="text/css">
+ /* Remove default bullets */
+ ul, .treelist {
+ list-style-type: none;
+ }
+
+ /* Remove margins and padding from the parent ul */
+ .treelist {
+ margin: 0;
+ padding: 0;
+ }
+
+ /* Style the caret/arrow */
+ .caret {
+ cursor: pointer;
+ font-weight: bold;
+ user-select: none; /* Prevent text selection */
+ }
+
+ /* Create the caret/arrow with a unicode, and style it */
+ .caret::before {
+ content: "\25B6";
+ color: black;
+ display: inline-block;
+ margin-right: 6px;
+ }
+
+ /* Rotate the caret/arrow icon when clicked on (using JavaScript) */
+ .caret-down::before {
+ transform: rotate(90deg);
+ }
+
+ /* Hide the nested list */
+ .nested {
+ display: none;
+ }
+
+ /* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */
+ .active {
+ display: block;
+ }
+
+
+ .treetop_header {
+ font-size: 16pt;
+ font-weight: bold;
+ padding-top: 10px;
+ width: 100%;
+ text-align: center;
+ top: 0px;
+ }
+
+ .treetop {
+ width: 100%;
+ height: 50px;
+ border-bottom: 1px solid black;
+ }
+ </style>
+ <style type="text/css">
+ #loading {
+ position: fixed;
+ display: none;
+ z-index: 161;
+ background-color: #7e80f2;
+ text-align: center;
+ font-size: 64pt;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ }
+
+ #loading_percent {
+ position: absolute;
+ top: 20%;
+ left: 30%;
+ width: 40%;
+ height: 10%;
+ background-color: #9a88f7;
+ }
+
+ #loading_percent_inner {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ height: 100%;
+ width: 1%;
+ background-color: #5e50a2;
+ }
+
+ #main {
+ position: absolute;
+ z-index: 5;
+ background-color: "#c5c5f0;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ }
+
+ .waveform {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ }
+
+ #waveforms {
+ position: absolute;
+ left: 15%;
+ top: 0px;
+ height: 60%;
+ width: 85%;
+ }
+
+ .waveform_overlay {
+ position: absolute;
+ padding: 20px;
+ width: 100%;
+ height: 100%;
+ background-color: #fcf6de;
+ opacity: 0.9;
+ left: 0px;
+ top: 0px;
+ z-index: 20;
+ }
+
+ #sidepane {
+ position: absolute;
+ background-color: #a5a5d9;
+ left: 0px;
+ top: 0px;
+ height: 100%;
+ width: 15%;
+ border-right: 1px solid black;
+ }
+
+ #controls {
+ position: absolute;
+ background-color: #9d9ded;
+ left: 15%;
+ top: 65%;
+ height: 40%;
+ width: 85%;
+ border-top: 1px solid black;
+ }
+
+ #wavecontrols {
+ position: absolute;
+ overflow: hidden;
+ background-color: #323265;
+ left: 15%;
+ top: 60%;
+ height: 5%;
+ width: 85%;
+ border-top: 1px solid black;
+ }
+
+ #waveform_tabs {
+ cursor: pointer;
+ }
+
+ #panetree {
+ font-size: 8pt;
+ font-family: Arial, sans-serif;
+ }
+
+ button {
+ border: none;
+ background-color: #8787bd;
+ font-size: 8pt;
+ padding: 1px;
+ font-family: Arial, sans-serif;
+ }
+
+ .tfv_script {
+ background-color: #323265;
+ color: #ffc67a;
+ font-size: 10pt;
+ font-family: monospace, Courier;
+ width: 100%;
+ height: 100%;
+ }
+
+ .tfv_container {
+ background-color: #8181fa;
+ font-size: 10pt;
+ font-family: Arial, sans-serif;
+ }
+
+ .tfv_row_odd {
+ background-color: #8181c9;
+ font-size: 10pt;
+ font-family: Arial, sans-serif;
+ }
+
+ .tfv_row_even {
+ background-color: #7171ba;
+ font-size: 10pt;
+ font-family: Arial, sans-serif;
+ }
+
+ .tfv_cell {
+ font-size: 10pt;
+ font-family: Arial, sans-serif;
+ }
+
+ .tfv_cellfixed {
+ font-size: 8pt;
+ font-family: Arial, sans-serif;
+ overflow: hidden;
+ width: 40px;
+ }
+
+ .tfv_header {
+ background-color: #565698;
+ font-size: 11pt;
+ font-weight: bold;
+ }
+
+ .automate_container {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ z-index: 125;
+ display: none;
+ }
+
+ #prompt {
+ z-index: 201;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #3434d9;
+ display: none;
+ }
+
+ #prompt_centre {
+ z-index: 202;
+ position: relative;
+ height: 200px;
+ }
+
+ #prompt_inner {
+ z-index: 203;
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 24pt;
+ cursor: pointer;
+ text-align: centre;
+ }
+
+ #prompt_button {
+ font-size: 24pt;
+ padding: 20px;
+ }
+
+ #start {
+ z-index: 200;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: #5656d1;
+ }
+
+ #start_centre {
+ z-index: 201;
+ position: relative;
+ height: 200px;
+ }
+
+ .transparentinput {
+ font-size: 8pt;
+ background-color: 9898ff;
+ color: #000000";
+ border: none;
+ }
+
+ .wtab_selected {
+ font-size: 8pt;
+ font-weight: bold;
+ background-color: 9898ff;
+ color: #000000";
+ padding: 3px;
+ border: 1px solid black;
+ border-top: 0;
+ }
+
+ .wtab_unselected {
+ font-size: 8pt;
+ background-color: #8888df;
+ font-weight: normal;
+ color: #000000";
+ padding: 3px;
+ border: 1px solid black;
+ }
+
+ #start_invoke {
+ z-index: 202;
+ text-align: centre;
+ margin: 0;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ font-size: 72pt;
+ cursor: pointer;
+ }
+
+ body {
+ font-family: Arial, sans-serif;
+ }
+
+ </style>
+ </head>
+ <body>
+ <div id="prompt">
+ <div id="prompt_centre">
+ <div id="prompt_inner">
+ <p id="prompt_text"></p>
+ <button id="prompt_button">OK</button>
+ </div>
+ </div>
+ </div>
+ <div id="start">
+ <div id="start_centre">
+ <h1>twist</h1>
+ <p>Web based audio transformer</p>
+ <p id="start_invoke">Press to begin</p>
+ </div>
+ </div>
+ <div id="loading">
+ Processing
+ <div id="loading_percent"><div id="loading_percent_inner"></div></div>
+ </div>
+ <div id="main">
+ <div id="waveforms"></div>
+ <div id= "automate_container"></div>
+ <div id="wavecontrols">
+ <table><tbody><tr id="waveform_tabs"></tr><tbody></table>
+ <table><tbody><tr id="wavecontrols_inner"></tr><tbody></table>
+ </div>
+ <div id="sidepane">
+ <div id="panetree"></div>
+ </div>
+ <div id="controls"></div>
+ </div>
+ </body>
+</html>
\ No newline at end of file diff --git a/site/app/twist/_unlive/splinetest.html b/site/app/twist/_unlive/splinetest.html new file mode 100644 index 0000000..cda0969 --- /dev/null +++ b/site/app/twist/_unlive/splinetest.html @@ -0,0 +1,42 @@ +<!doctype html>
+<html lang="en-GB">
+ <head>
+ <title>twist</title>
+ <script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+ <script src="https://apps.csound.1bpm.net/code/d3.v7.min.js"></script>
+ <script type="text/javascript" src="../base/spline-edit.js"></script>
+ <script type="text/javascript">
+ $(function() {
+ window.spline = new SplineEdit(
+ $("#spline"),
+ "#992222",
+ 30,
+ [-500, 500, 100, 0.0001],
+ "ass"
+ );
+ });
+ </script>
+ <style type="text/css">
+ .tooltip-splineedit {
+ position: absolute;
+ text-align: center;
+ border-radius: 5px;
+ pointer-events: none;
+ padding: 2px;
+ color: #000000;
+ opacity: 0;
+ font-family: Arial, sans-serif;
+ font-size: 8pt;
+ text-shadow: 1px 1px #ffffff;
+ z-index: 42;
+ }
+ #spline {
+ position: absolute;left:0px;top:20%;width: 100%;height: 50%;background-color:#bdbdbd;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="tooltip-splineedit" class="tooltip-splineedit"></div>
+ <div id="spline"></div>
+ </body>
+</html>
\ No newline at end of file diff --git a/site/app/twist/_unlive/transform.js b/site/app/twist/_unlive/transform.js new file mode 100644 index 0000000..3810359 --- /dev/null +++ b/site/app/twist/_unlive/transform.js @@ -0,0 +1,1024 @@ +var TransformParameter = function(instr, tDefinition, parent, transform, twist, onChange) {
+ var self = this;
+ var refreshable = false;
+ var changeFunc;
+ var initval = true;
+ var definition = {};
+ var randomiseAllowed = true;
+ var visible = true;
+
+ if (parent) {
+ Object.assign(definition, tDefinition);
+ } else {
+ definition = tDefinition;
+ }
+
+ if (definition.channel == "applymode") {
+ randomiseAllowed = false;
+ }
+
+ if (definition.hasOwnProperty("preset")) {
+ var save = {};
+ for (var s of ["dfault", "name", "channel", "automatable", "description"]) {
+ if (definition.hasOwnProperty(s)) {
+ save[s] = definition[s];
+ }
+ }
+
+ if (definition.preset == "amp") {
+ Object.assign(definition, {name: "Amplitude", channel: "amp", description: "Amplitude", dfault: 1, min: 0, max: 1});
+ } else if (definition.preset == "pvslock") {
+ Object.assign(definition, {name: "Peak lock", channel: "pvslock", description: "Lock frequencies around peaks", step: 1, dfault: 0});
+ } else if (definition.preset == "fftsize") {
+ Object.assign(definition, {name: "FFT size", channel: "fftsize", description: "FFT size", options: [256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65535], dfault: 2, asvalue: true, automatable: false, lagHint: -1});
+ } else if (definition.preset == "wave") {
+ Object.assign(definition, {name: "Wave", description: "Wave shape to use", options: ["Sine", "Square", "Saw", "Pulse", "Triangle"], dfault: 0, channel: "wave"});
+ } else if (definition.preset == "wintype") {
+ Object.assign(definition, {name: "Window type", channel: "wintype", description: "Window shape", options: ["Hanning", "Hamming", "Half sine"], dfault: 0, automatable: false});
+
+ } else if (definition.preset == "instanceloop") {
+ Object.assign(definition, {name: "Cross instance loop type", channel: "otlooptype", description: "Loop type of other instance", options: ["None", "Forward", "Backward", "Ping-pong"], dfault: 0});
+
+ } else if (definition.preset == "applymode") {
+ Object.assign(definition, {name: "Apply mode", channel: "applymode", absolutechannel: true, description: "Apply mode", automatable: false, options: ["Replace", "Mix", "Modulate", "Demodulate"], dfault: 0});
+ } else if (definition.preset == "note") {
+ var notes = {};
+ for (var i = 21; i < 128; i++) {
+ var v = twist.noteData.data.notes[i];
+ notes[v[0]] = v[1];
+ }
+ Object.assign(definition, {name: "Note", channel: "note", description: "Note to use", options: notes, dfault: 69, automatable: true});
+ } else if (definition.preset == "instance") {
+ var c = (!definition.channel) ? "ot" : definition.channel;
+ initval = false;
+ if (transform) transform.refreshable = true;
+ refreshable = true;
+ Object.assign(definition, {
+ name: "Instance", description: "Other wave to use", channel: instr + "_" + "instance",
+ options: twist.otherInstanceNames,
+ automatable: false
+ });
+ changeFunc = function(index) {
+ var s = twist.waveforms[index].selected;
+ app.setControlChannel(instr + "_" + "inststart", s[0]);
+ app.setControlChannel(instr + "_" + "instend", s[1]);
+ app.setControlChannel(instr + "_" + "instchan", s[2]);
+ };
+ }
+ if (save) {
+ Object.assign(definition, save);
+ }
+ } // if preset
+
+ var type;
+
+ if (definition.hasOwnProperty("conditions") && !parent) {
+ refreshable = true;
+ if (transform) transform.refreshable = refreshable;
+ }
+
+ var channel = "";
+ if (!definition.hasOwnProperty("absolutechannel")) {
+ channel = (parent) ? parent.channel : instr + "_";
+ }
+
+ if (definition.hasOwnProperty("channel")) {
+ channel += definition.channel;
+ } else {
+ channel += definition.name.toLowerCase();
+ }
+
+ var elContainer = $("<div />");
+ var elValueLabel = $("<div />");
+ var elValueInput;
+ var elModulations;
+ var elInput;
+ var elRow;
+ var elModSelect;
+ var automation = [];
+
+ this.definition = definition;
+ this.modulation = null;
+ this.automation = null;
+ this.channel = channel;
+ this.modulationParameters = null;
+
+ this.setPlaying = async function(state) {
+ if (definition.automatable || definition.hidden) return;
+ if (elValueInput) {
+ elValueInput.prop("disabled", state);
+ elValueInput.css("opacity", (state) ? 0.8 : 1);
+ }
+
+ if (elInput) {
+ elInput.prop("disabled", state);
+ elInput.css("opacity", (state) ? 0.8 : 1);
+ }
+ };
+
+
+ if (!definition.hasOwnProperty("hidden")) {
+ definition.hidden = false;
+ }
+
+ if (!definition.hasOwnProperty("step")) {
+ definition.step = 0.0000001;
+ }
+
+ if (!definition.hasOwnProperty("min")) {
+ definition.min = 0;
+ }
+
+ if (!definition.hasOwnProperty("max")) {
+ definition.max = 1;
+ }
+
+ if (!definition.hasOwnProperty("fireChanges")) {
+ definition.fireChanges = true;
+ }
+
+ if (!definition.hasOwnProperty("dfault")) {
+ definition.dfault = 1;
+ }
+
+ if (parent) {
+ if (definition.hostrange) {
+ var items = ["step", "min", "max", "options", "conditions", "hostrange"];
+ if (definition.dfault == "hostrangemin") {
+ definition.dfault = parent.definition.min;
+ } else if (definition.dfault == "hostrangemax") {
+ definition.dfault = parent.definition.max;
+ } else {
+ items.push("dfault");
+ }
+ for (let o of items) {
+ if (parent.definition.hasOwnProperty(o)) {
+ definition[o] = parent.definition[o];
+ }
+ }
+ } else if (definition.preset == "hostrangemin") {
+ definition.min = definition.max = definition.dfault = parent.definition.min;
+ } else if (definition.preset == "hostrangemax") {
+ definition.min = definition.max = definition.dfault = parent.definition.max;
+ }
+ }
+
+ if (definition.hasOwnProperty("options")) {
+ type = "select";
+ } else if (definition.hasOwnProperty("type")) {
+ type = definition.type;
+ } else if (definition.min == 0 && definition.max == 1 && definition.step == 1) {
+ type = "checkbox";
+ } else {
+ type = "range";
+ }
+
+ if (!definition.hasOwnProperty("automatable")) {
+ definition.automatable = ((type == "range" || type == "checkbox") && !parent);
+ }
+
+ this.getLagHint = function() {
+ if (!definition.lagHint || !visible) return;
+ var lagHint;
+ if (typeof(definition.lagHint) == "object") {
+ lagHint = "setting <i>" + definition.name + "</i> to <i>"
+ + definition.options[definition.lagHint.option] + "</i>";
+ } else {
+ lagHint = ((definition.lagHint < 0) ? "reducing" : "increasing")
+ + " <i>" + definition.name + "</i>";
+ }
+ return lagHint;
+ };
+
+ this.setRawValue = function(val) {
+ if (type == "checkbox") {
+ elInput[0].checked = (val == 0) ? false : true;
+ } else {
+ elInput.val(val);
+ }
+ elInput.trigger("change");
+ }
+
+ this.getRawValue = function() {
+ return elInput.val();
+ }
+
+ this.getValue = function() {
+ var val;
+ if (type == "range" || type == "string") {
+ val = elInput.val();
+ } else if (type == "select") {
+ val = (definition.asvalue) ? elInput.find("option:selected").text() : elInput.val();
+ } else if (type == "checkbox") {
+ val = (elInput[0].checked) ? 1 : 0;
+ }
+ return val;
+ };
+
+ this.reset = function() {
+ self.setRawValue(definition.dfault);
+ if (automationActive) disableAutomation();
+ if (self.automation) {
+ delete self.automation;
+ self.automation = null;
+ }
+ if (elSpline) {
+ elSpline.remove();
+ delete elSpline;
+ }
+ if (modulationShown) hideModulations();
+ };
+
+ this.randomise = function() {
+ if (!randomiseAllowed) return;
+ var val;
+ if (definition.automatable) {
+ if (Math.random() >= 0.5) {
+ modButton.el.click();
+ }
+ }
+
+ if (type == "select") {
+ val = Math.round(Math.random() * (definition.options.length - 1));
+ } else if (type == "range") {
+ val = (Math.random() * (definition.max - definition.min)) + definition.min;
+ if (definition.step == 1) {
+ val = Math.round(val);
+ } else {
+ val = Math.ceil((val - definition.min) / definition.step) * definition.step + definition.min;
+ }
+ } else if (type = "checkbox") {
+ val = (Math.round(Math.random()));
+ }
+ self.setRawValue(val);
+
+ if (self.modulationParameters) {
+ // 4 = just the non-crossadaptive ones
+ elModSelect.val(Math.round(Math.random() * 4)).trigger("change");
+ for (let mp in self.modulationParameters) {
+ self.modulationParameters[mp].randomise();
+ }
+ }
+ };
+
+
+ this.refresh = function() {
+ if (!refreshable || !transform) {
+ return;
+ }
+ if (definition.preset == "instance") {
+ createSelectOptions(elInput, twist.otherInstanceNames);
+ }
+ for (var k in definition.conditions) {
+ var c = definition.conditions[k];
+ var val = transform.parameters[transform.instr + "_" + c.channel].getValue();
+ if (
+ (c.operator == "eq" && val != c.value) ||
+ (c.operator == "neq" && val == c.value) ||
+ (c.operator == "lt" && val >= c.value) ||
+ (c.operator == "gt" && val <= c.value) ||
+ (c.operator == "le" && val > c.value) ||
+ (c.operator == "ge" && val < c.value)
+ ) {
+ visible = false;
+ return elRow.hide();
+ }
+ }
+ visible = true;
+ elRow.show();
+ };
+
+ function createSelectOptions(elSelect, options) {
+ var selected = elInput.val();
+ elSelect.empty();
+ for (var x in options) {
+ var opt = $("<option />").text(options[x]).val(x).appendTo(elSelect);
+ if (x == selected) {
+ opt.attr("selected", "1");
+ if (changeFunc) changeFunc(x);
+ }
+ }
+ definition.min = 0;
+ definition.max = (Array.isArray(options)) ? options.length - 1 : Object.keys(options).length - 1;
+ }
+
+ function updateLabel() {
+ if (elValueInput) {
+ var val = self.getValue();
+ updateinput = false;
+ rounding = 10000;
+ val = Math.round(val * rounding) / rounding;
+ elValueInput.val(val);
+ updateinput = true;
+ }
+ }
+
+ if (type == "select") {
+ elInput = $("<select />");
+ elInput.change(function(){
+ var val = self.getValue();
+ if (transform) transform.refresh();
+ if (definition.fireChanges) {
+ if (changeFunc) changeFunc(val);
+ app.setControlChannel(channel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+
+ var options = (definition.hostrange && parent) ? parent.definitions.options : definition.options;
+ createSelectOptions(elInput, options);
+
+ } else if (type == "string") {
+ elInput = $("<input />").change(function() {
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges) {
+ app.setStringChannel(channel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+
+ } else if (type == "checkbox") {
+ elInput = $("<input />").addClass("tp_checkbox").attr("type", "checkbox").on("change", function() {
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges) {
+ app.setControlChannel(channel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ });
+ } else if (type == "range") {
+ var updateinput = true;
+ var max = definition.max;
+ var min = definition.min;
+ var step = definition.step;
+ var dfault = definition.dfault;
+
+ elInput = $("<input />").addClass("tp_slider").attr("type", "range").on("input", function() {
+ updateLabel();
+ if (definition.fireChanges) {
+ app.setControlChannel(channel, self.getValue());
+ }
+ }).change(function() {
+ updateLabel();
+ if (transform) transform.refresh();
+ var val = self.getValue();
+ if (definition.fireChanges) {
+ app.setControlChannel(channel, val);
+ }
+ if (onChange) {
+ onChange(val);
+ }
+ }).attr("min", min).attr("max", max).attr("step", step).val(dfault);
+
+ elValueInput = $("<input />").attr("type", "number").attr("min", min).attr("max", max).attr("step", step).addClass("transparentinput").appendTo(elValueLabel).change(function() {
+ if (updateinput) {
+ elInput.val($(this).val()).trigger("change").trigger("input");
+ }
+ });
+ }
+
+ elContainer.append(elInput);
+ if (initval) {
+ self.setRawValue(definition.dfault);
+ if (definition.fireChanges) {
+ elInput.trigger("change");
+ }
+ }
+
+
+ this.setDefault = function() {
+ elInput.val(definition.dfault).trigger("change");
+ //app.setControlChannel(channel, definition.dfault);
+ };
+
+ this.remove = function() {
+ elRow.remove();
+ if (elSpline) {
+ elSpline.remove();
+ }
+ if (self.modulation) {
+ self.modulation = null;
+ }
+ if (self.automation) {
+ self.automation = null;
+ }
+ };
+
+ this.getAutomationData = function(start, end) {
+ if (self.modulation) {
+ var m = twist.appdata.modulations[self.modulation];
+ return {type: "modulation", data: [m.instr, self.channel]};
+ } else if (automationActive && self.automation) {
+ return {type: "automation", channel: self.channel, data: self.automation.getLinsegData(start, end, twist.waveform.getRegion())};
+ }
+ };
+
+ var resetButton = twirl.createIcon({
+ label: "Reset parameter",
+ icon: "reset",
+ click: function() {
+ self.reset();
+ }
+ });
+
+ var randomiseButton = twirl.createIcon({
+ label: "Include in randomisation",
+ icon: "randomise",
+ click: function(obj) {
+ randomiseAllowed = !randomiseAllowed;
+ var opacity = (randomiseAllowed) ? 1 : 0.4;
+ obj.el.css("opacity", opacity);
+ }
+ });
+ if (!randomiseAllowed) {
+ randomiseButton.el.css("opacity", 0.4);
+ }
+
+ var elSpline;
+ var editAutomationButton = twirl.createIcon({
+ label: "Select",
+ icon: "show",
+ click: function() {
+ if (!transform) return;
+ if (elSpline) {
+ automationShown = true;
+ transform.showAutomation(definition.name, elSpline);
+ }
+ }
+ });
+ editAutomationButton.el.hide();
+
+ var automationButton = twirl.createIcon({
+ label: "Automate",
+ label2: "Close automation",
+ icon: "automate",
+ icon2: "close",
+ click: function() {
+ if (elSpline && automationActive) {
+ disableAutomation();
+ } else {
+ showAutomation();
+ }
+ }
+ });
+
+ var automationActive = false;
+ var automationShown = false;
+
+ this.hideAutomation = function() {
+ if (!transform) return;
+ automationShown = false;
+ if (elSpline) {
+ transform.hideAutomation(definition.name);
+ }
+ }
+
+ function disableAutomation() {
+ if (!transform) return;
+ automationActive = false;
+ automationShown = false;
+ app.setControlChannel(channel, self.getValue());
+ elValueLabel.show();
+ elInput.show();
+ modButton.el.show();
+ automationButton.setState(true);
+ editAutomationButton.el.hide();
+ self.hideAutomation();
+ }
+
+ this.redraw = function(region) {
+ if (self.automation) {
+ if (region && region[0] != null && region[1] != null) {
+ self.automation.setRange(region[0], region[1]);
+ } else {
+ self.automation.redraw();
+ }
+ }
+ };
+
+ function showAutomation() {
+ if (!transform) return;
+ var colour = "rgb(" + (Math.round(Math.random() * 50) + 205) + ","
+ + (Math.round(Math.random() * 50) + 205) + ","
+ + (Math.round(Math.random() * 50) + 205) + ")";
+ automationShown = true;
+ automationActive = true;
+
+ if (!elSpline) {
+ elSpline = $("<div />").attr("id", "spl_" + channel).css({
+ position: "absolute", width: "100%", height: "100%", overflow: "hidden"
+ });
+ }
+
+ transform.showAutomation(definition.name, elSpline);
+
+ if (!self.automation) {
+ self.automation = new SplineEdit(
+ elSpline, colour,
+ twist.waveform.getDuration,
+ [definition.min, definition.max, self.getValue(), definition.step],
+ definition.name
+ );
+ }
+
+ elValueLabel.hide();
+ elInput.hide();
+ modButton.el.hide();
+ elSpline.show();
+ editAutomationButton.el.show(); //.css("background-color", colour);
+ automationButton.setState(false);
+ }
+
+
+ elModulations = $("<div />").addClass("tfv_container").hide().appendTo(elContainer);
+ var modulationShown = false;
+
+
+ var modButton = twirl.createIcon({
+ label: "Modulate",
+ label2: "Close modulation",
+ icon: "modulate",
+ icon2: "close",
+ click: function() {
+ if (elModulations && modulationShown) {
+ hideModulations();
+ } else {
+ showModulations();
+ }
+ }
+ });
+
+ function hideModulations() {
+ app.setControlChannel(channel, self.getValue());
+ modulationShown = false;
+ elValueLabel.show();
+ elInput.show();
+ automationButton.el.show();
+ self.modulation = null;
+ modButton.setState(true);
+ if (elModulations) {
+ elModulations.hide();
+ }
+ }
+
+ function showModulations() {
+ if (!transform) return;
+ modulationShown = true;
+ elValueLabel.hide();
+ elInput.hide();
+ automationButton.el.hide();
+ elModulations.show();
+ modButton.setState(false);
+ if (elModulations.children().length != 0) {
+ elModSelect.val(0).trigger("change");
+ return;
+ }
+ var tb = $("<tbody />");
+ function buildModulation(i) {
+ tb.empty();
+ self.modulationParameters = {};
+ self.modulation = i;
+ let m = twist.appdata.modulations[i];
+ for (let x of m.parameters) {
+ var tp = new TransformParameter(m.instr, x, self, transform, twist);
+ self.modulationParameters[tp.channel] = tp;
+ tb.append(tp.getElementRow(true)); // hmm modulate the modulation with false
+ }
+ }
+ var selecttb = $("<tbody />").appendTo($("<table />)").appendTo(elModulations));
+ var row = $("<tr />").append($("<td />").text("Modulation type")).appendTo(selecttb);
+ var elConditionalOptions = [];
+
+ twist.onInstanceChangeds.push(function(){
+ for (let o of elConditionalOptions) {
+ if (twist.waveforms.length == 1) {
+ o.prop("disabled", true);
+ } else {
+ o.prop("disabled", false);
+ }
+ }
+ });
+
+ elModSelect = $("<select />").change(function() {
+ self.modulation = $(this).val();
+ buildModulation(self.modulation);
+ }).appendTo($("<td />").appendTo(row));
+ $("<table />").append(tb).appendTo(elModulations);
+
+ for (let i in twist.appdata.modulations) {
+ var m = twist.appdata.modulations[i];
+ var o = $("<option />").text(m.name).val(i).appendTo(elModSelect);
+ if (m.inputs > 1) {
+ elConditionalOptions.push(o);
+ if (twist.waveforms.length == 1) {
+ o.prop("disabled", true);
+ }
+ }
+ }
+ elModSelect.val(0).trigger("change");
+ }
+
+ this.getElementRow = function(nocontrols) {
+ if (definition.hidden) {
+ return null;
+ };
+ if (elRow) {
+ return elRow;
+ }
+ elRow = $("<tr />");
+ var name = $("<td />").addClass("tfv_cell_text").text(definition.name).appendTo(elRow);
+ if (definition.description) {
+ name.on("mouseover", function(event){
+ twirl.tooltip.show(event, definition.description);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ $("<td />").addClass("tfv_cell").append(elContainer).appendTo(elRow);
+ $("<td />").addClass("tfv_cellfixed").append(elValueLabel).appendTo(elRow);
+ if (!nocontrols) {
+ for (let b of [resetButton, randomiseButton]) $("<td />").addClass("tfv_cell_plainbg").append(b.el).appendTo(elRow);
+
+ if (definition.automatable) {
+ for (let b of [automationButton, editAutomationButton, modButton]) $("<td />").addClass("tfv_cell_plainbg").append(b.el).appendTo(elRow);
+ }
+
+ }
+ return elRow;
+ };
+};
+
+
+
+function getTransformContainer(nameOrElement) {
+ var el = $("<div />").addClass("tfv_header");
+ if (typeof(nameOrElement) == "string") {
+ el.text(nameOrElement);
+ } else {
+ el.append(nameOrElement);
+ }
+ return $("<div />").addClass("tfv_container").append(el);
+}
+
+var Transform = function(target, def, twist) {
+ var self = this;
+ var elTb;
+ var pAddOdd = true;
+ this.instr = def.instr;
+ this.refreshable = false;
+ var elSplineOverlay;
+ var hideAutomationButton;
+ this.parameters = {};
+
+ var automationEls = {};
+ this.showAutomation = function(name, el) {
+ if (!elSplineOverlay) {
+ elSplineOverlay = $("<div />").addClass("spline_overlay").appendTo($("#twist_splines"));
+ }
+ for (var e in automationEls) {
+ automationEls[e].css({"z-index": 23, opacity: 0.4});
+ }
+ if (!el) {
+ el = automationEls[name];
+ } else {
+ automationEls[name] = el;
+ }
+ el.css({"z-index": 24, opacity: 1}).show();
+ hideAutomationButton.el.show();
+ elSplineOverlay.show();
+ if (el.parents(elSplineOverlay).length == 0) {
+ elSplineOverlay.append(el);
+ }
+ $("#twist_splines").show();
+ };
+
+ this.getLagHints = function() {
+ var lagHints = [];
+ for (let i in self.parameters) {
+ var p = self.parameters[i];
+ var lagHint = p.getLagHint();
+ if (lagHint) lagHints.push(lagHint);
+ }
+ var lagHintHtml;
+ if (lagHints.length != 0) {
+ lagHintHtml = "Try ";
+ for (var i in lagHints) {
+ lagHintHtml += lagHints[i];
+ if (i != lagHints.length - 1) {
+ lagHintHtml += ((i == lagHints.length - 2) ? " or " : ", ");
+ }
+ }
+ }
+ return lagHintHtml;
+ };
+
+ this.hideAutomation = function(name) {
+ if (automationEls[name]) {
+ automationEls[name].hide();
+ delete automationEls[name];
+ if (Object.keys(automationEls).length == 0) {
+ elSplineOverlay.hide();
+ hideAutomationButton.el.hide();
+ $("#twist_splines").hide();
+ }
+ }
+ }
+
+ this.hideAllAutomation = function(name) {
+ for (let p in self.parameters) {
+ self.parameters[p].hideAutomation();
+ }
+ };
+
+ this.redraw = function(region) {
+ for (let p in self.parameters) {
+ self.parameters[p].redraw(region);
+ }
+ };
+
+ this.refresh = function() {
+ if (!self.refreshable) {
+ return;
+ }
+ for (var k in self.parameters) {
+ self.parameters[k].refresh();
+ }
+ };
+
+ this.getAutomationData = function(start, end) {
+ var automations = [];
+ for (var k in self.parameters) {
+ var data = self.parameters[k].getAutomationData(start, end);
+ if (data) {
+ automations.push(data);
+ }
+ }
+ return automations;
+ };
+
+ this.getState = async function() {
+ var data = {instr: def.instr, channels: {}};
+ var value;
+ for (let chan in self.parameters) {
+ value = await app.getControlChannel(chan);
+ data.channels[chan] = value;
+ if (self.parameters[chan].modulationParameters) {
+ for (let modchan in self.parameters[chan].modulationParameters) {
+ value = await app.getControlChannel(modchan);
+ data.channels[modchan] = value;
+ }
+ }
+ }
+ return data;
+ };
+
+
+ this.reset = function() {
+ for (let p in self.parameters) {
+ self.parameters[p].reset();
+ }
+ };
+
+ this.randomise = function() {
+ for (let p in self.parameters) {
+ self.parameters[p].randomise();
+ if (self.parameters[p].modulationParameters) {
+ for (let mp in self.parameters[p].modulationParameters) {
+ self.parameters[p].modulationParameters[mp].randomise();
+ }
+ }
+ }
+ };
+
+ this.saveState = function() {
+ var state = {};
+ for (let p in self.parameters) {
+ state[p] = self.parameters[p].getRawValue();
+ }
+ if (!twist.storage.transforms) {
+ twist.storage.transforms = {};
+ }
+ twist.storage.transforms[def.instr] = state;
+ twist.saveStorage();
+ };
+
+ this.remove = function() {
+ self.saveState();
+ for (let p in self.parameters) {
+ self.parameters[p].remove();
+ }
+ if (elSplineOverlay) {
+ elSplineOverlay.remove();
+ }
+ }
+
+ this.removeParameter = function(channel) {
+ if (self.parameters.hasOwnProperty(channel)) {
+ self.parameters[channel].remove();
+ delete self.parameters[channel]
+ }
+ };
+
+ function addParameter(pdef) {
+ var tp = new TransformParameter(def.instr, pdef, null, self, twist);
+ self.parameters[tp.channel] = tp;
+ var er = tp.getElementRow();
+ if (er) {
+ elTb.append(er.addClass("tfv_row_" + ((pAddOdd) ? "odd" : "even")));
+ pAddOdd = !pAddOdd;
+ };
+ };
+
+ this.setPlaying = function(state) {
+ for (let i in self.parameters) {
+ self.parameters[i].setPlaying(state);
+ }
+ };
+
+ function namePrepend(name, pdef) {
+ if (!pdef.hasOwnProperty("nameprepend")) return name;
+ name = pdef.nameprepend + " " + name;
+ return name[0] + name.substr(1).toLowerCase()
+ }
+
+ this.addParameter = function(pdef) {
+ if (!pdef.hasOwnProperty("presetgroup")) {
+ return addParameter(pdef);
+ }
+ var name;
+ var conditions;
+ var groupParameters = [];
+ var channelPrepend = (pdef.hasOwnProperty("channelprepend")) ? pdef.channelprepend : "";
+
+ if (pdef.presetgroup == "pvsynth") {
+ var dfaultMode = (pdef.hasOwnProperty("dfault")) ? pdef.dfault : 0;
+ conditions = [
+ {channel: channelPrepend + "pvresmode", operator: "eq", value: 1}
+ ];
+ groupParameters = [
+ {name: namePrepend("Resynth mode", pdef), channel: channelPrepend + "pvresmode", description: "Type of FFT resynthesis used", dfault: dfaultMode, options: ["Overlap-add", "Additive"], automatable: false},
+ {name: namePrepend("Oscillator spread", pdef), channel: channelPrepend + "pvaoscnum", description: "Number of oscillators used", automatable: false, conditions: conditions, lagHint: -1},
+ {name: namePrepend("Frequency modulation", pdef), channel: channelPrepend + "pvafreqmod", description: "Frequency modulation", dfault: 1, min: 0.01, max: 2, conditions: conditions},
+ {name: namePrepend("Oscillator offset", pdef), channel: channelPrepend + "pvabinoffset", description: "Oscillator bin offset", automatable: false, conditions: conditions, dfault: 0, lagHint: 1},
+ {name: namePrepend("Oscillator increment", pdef), channel: channelPrepend + "pvabinincr", description: "Oscillator bin increment", min: 1, max: 8, dfault: 1, step: 1, automatable: false, conditions: conditions, lagHint: -1}
+ ];
+ } else if (pdef.presetgroup == "pvanal") {
+ groupParameters = [
+ {preset: "fftsize"},
+ {preset: "pvslock"},
+ {name: "Overlap decimation", min: 4, max: 16, step: 1, dfault: 4, channel: "pvsdecimation", automatable: false, lagHint: -1},
+ {name: "Window size multiplier", min: 1, max: 4, dfaut: 1, step :1, channel: "pvswinsizem", automatable: false, lagHint: -1},
+ {name: "Window type", options: ["Hamming", "Von Hann", "Kaiser"], dfault: 1, automatable: false}
+ ];
+ } else if (pdef.presetgroup == "pitchscale") {
+ groupParameters = [
+ {name: namePrepend("Pitch scale mode", pdef), channel: channelPrepend + "pitchscalemode", options: ["Ratio", "Semitone"], dfault: 0},
+ {name: namePrepend("Pitch scale", pdef), channel: channelPrepend + "pitchscale", description: "Pitch scaling", dfault: 1, min: 0.01, max: 10, conditions: [{channel: channelPrepend + "pitchscalemode", operator: "eq", value: 0}]},
+ {name: namePrepend("Semitones", pdef), channel: channelPrepend + "pitchsemitones", min: -24, max: 24, step: 1, dfault: 0, conditions: [{channel: channelPrepend + "pitchscalemode", operator: "eq", value: 1}]}
+ ];
+
+ } else if (pdef.presetgroup == "notefreq") {
+ var base = {name: namePrepend("Frequency mode", pdef), channel: channelPrepend + "freqmode", description: "Frequency mode", options: ["Frequency", "Note"], dfault: 0};
+ if (pdef.hasOwnProperty("conditions")) {
+ base["conditions"] = pdef.conditions;
+ }
+ groupParameters.push(base);
+
+ conditions = [{channel: channelPrepend + "freqmode", operator: "eq", value: 0}];
+ if (pdef.hasOwnProperty("conditions")) {
+ Array.prototype.push.apply(conditions, pdef.conditions);
+ }
+
+ var dfaultFreq = (pdef.hasOwnProperty("dfault")) ? pdef.dfault : 440;
+
+ var freq = {name: namePrepend("Frequency", pdef), channel: channelPrepend + "freq", description: "Frequency", dfault: dfaultFreq, min: 20, max: 22000, conditions: conditions}
+ if (pdef.hasOwnProperty("lagHint")) {
+ freq.lagHint = pdef.lagHint;
+ }
+ groupParameters.push(freq);
+
+ conditions = [{channel: channelPrepend + "freqmode", operator: "eq", value: 1}];
+ if (pdef.hasOwnProperty("conditions")) {
+ Array.prototype.push.apply(conditions, pdef.conditions);
+ }
+ var note = {preset: "note", name: namePrepend("Note", pdef), conditions: conditions, channel: channelPrepend + "note"};
+ if (pdef.hasOwnProperty("lagHint")) {
+ note.lagHint = pdef.lagHint;
+ }
+ groupParameters.push(note);
+
+ }
+ for (let gp of groupParameters) {
+ if (pdef.hasOwnProperty("automatable")) {
+ gp.automatable = pdef.automatable;
+ }
+ addParameter(gp);
+ }
+ }
+
+ function build() {
+ target.empty();
+ var elContainer = $("<div />").addClass("tfv_container").appendTo(target);
+ hideAutomationButton = twirl.createIcon({label: "Hide automation", icon: "hide", click: function() {
+ self.hideAllAutomation();
+ }});
+ hideAutomationButton.el.hide();
+
+ app.setControlChannel("applymode", 0); // not all transforms will set this
+ var el = $("<div />");
+ var header = $("<div />").text(def.name).appendTo(el);
+
+ if (def.description) {
+ header.on("mouseover", function(event){
+ twirl.tooltip.show(event, def.description);
+ }).on("mouseout", function(){
+ twirl.tooltip.hide();
+ });
+ }
+
+ $("<div />").css({"float": "right"}).append(
+ hideAutomationButton.el
+ ).append(
+ twirl.createIcon({
+ label: "Randomise parameters",
+ icon: "randomise",
+ click: function() {
+ self.randomise();
+ }
+ }).el
+ ).append(
+ twirl.createIcon({
+ label: "Reset parameters",
+ icon: "reset",
+ click: function() {
+ self.reset();
+ }
+ }).el
+ ).appendTo(el);
+
+ $("<div />").addClass("tfv_container").append(
+ $("<div />").addClass("tfv_header").append(el)
+ ).appendTo(elContainer);
+
+ //getTransformContainer(el).appendTo(elContainer);
+ var tbl = $("<table />").appendTo(elContainer);
+ elTb = $("<tbody />").appendTo(tbl);
+
+ for (let p of def.parameters) {
+ self.addParameter(p);
+ }
+
+ if (twist.storage && twist.storage.transforms && twist.storage.transforms[def.instr]) {
+ var state = twist.storage.transforms[def.instr];
+ for (var p in state) {
+ self.parameters[p].setRawValue(state[p]);
+ }
+ }
+ self.refresh();
+ }
+ build();
+};
+
+var TransformsTreeView = function(options, twist) {
+ var self = this;
+ var elTarget = $("#" + options.target);
+
+
+ function recurse(items, descended) {
+ items = (items) ? items : options.items;
+ var ul = $("<ul />").css({"border-bottom": "1px solid #878787", "padding-inline-start": 10}).addClass((descended) ? "nested" : "treelist");
+
+ for (let k in items) {
+ var li = $("<li />");
+ if (items[k].hasOwnProperty("contents")) {
+ $("<span />").addClass("caret").text(items[k].name).click(function() {
+ $(this).parent().children(".nested").toggleClass("active");
+ $(this).toggleClass("caret-down");
+ }).appendTo(li);
+ var subitems = recurse(items[k].contents, true);
+ li.append(subitems);
+
+ } else {
+ li.text(items[k].name).css("cursor", "pointer").click(function(){
+ if (twist.currentTransform) {
+ twist.currentTransform.remove();
+ }
+ twist.currentTransform = new Transform($("#twist_controls"), items[k], twist);
+ });
+ }
+ ul.append(li);
+ }
+ elTarget.append(ul);
+ return ul;
+ }
+
+ elTarget.append(recurse());
+};
\ No newline at end of file diff --git a/site/app/twist/_unlive/twist_fxtester.csd b/site/app/twist/_unlive/twist_fxtester.csd new file mode 100644 index 0000000..9f12cb7 --- /dev/null +++ b/site/app/twist/_unlive/twist_fxtester.csd @@ -0,0 +1,101 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+
+#include "/twist/twist.udo"
+
+gStransform = "twst_tf_fftpitchscale";, "twst_tf_morph"
+SchanSet[] fillarray "timescale", "pitchscale", "winsize", "randwin", "overlap", "wintype", "shift", "amp", "freq", "fftsize", "otinstchan", "instanceindex", "otinststart", "otinstend", "pvresmode", "time", "scale", "formants"
+ichanset[] fillarray 1.5, 1, 4410, 441, 4, 0, 900, 0, 1, 512, -1, 1, 0, 1, 0, 0.4, 2, 0
+index = 0
+while (index < lenarray(ichanset)) do
+ chnset ichanset[index], sprintf("%s_%s", gStransform, SchanSet[index])
+ index += 1
+od
+
+
+gSfile1 = "d:/temp/kord.wav"
+gSfile2 = "d:/temp/drive.wav"
+
+instr load1
+ gitwst_instanceindex = 0
+ schedule("twst_loadfile", 0, 1, 0, gSfile1)
+endin
+
+instr load2
+ gitwst_instanceindex = 1
+ schedule("twst_loadfile", 0, 1, 0, gSfile2)
+endin
+
+instr boot
+ schedule("load1", 0, 1)
+ schedule("load2", 1, 1)
+ schedule("audition", 2, 2)
+endin
+
+instr apply
+ schedule("twst_commit", 0, -1, 0, 0, 1, -1, gStransform, 0, 0, 0)
+ turnoff
+endin
+
+instr playback
+ schedule("twst_audition", 0, p3, 0, 0, 1, -1, "", 0)
+ turnoff
+endin
+
+instr audition
+ gitwst_instanceindex = 0
+ schedule("twst_audition", 0, p3, 0, 0, 1, -1, gStransform, 0)
+ turnoff
+endin
+
+
+/*
+gStransform = "twst_tf_freqshift1"
+gStransform = "twst_tfi_sndwarp"
+
+SchanSet[] fillarray "timescale", "pitchscale", "winsize", "randwin", "overlap", "wintype", "shift"
+ichanset[] fillarray 1.5, 1, 4410, 441, 4, 0, 900
+index = 0
+while (index < lenarray(ichanset)) do
+ chnset ichanset[index], sprintf("%s_%s", gStransform, SchanSet[index])
+ index += 1
+od
+
+
+gSfile = "d:/temp/sinetest.wav"
+
+instr boot
+ schedule("twst_loadfile", 0, 1, 0, gSfile)
+ schedule("audition", 1, 2)
+ schedule("apply", 3, 1)
+ schedule("playback", 4, 2)
+endin
+
+instr apply
+ schedule("twst_commit", 0, -1, 0, 0, 1, -1, gStransform, 0, 0, 0)
+ turnoff
+endin
+
+instr playback
+ schedule("twst_audition", 0, p3, 0, 0, 1, -1, "", 0)
+ turnoff
+endin
+
+instr audition
+ schedule("twst_audition", 0, p3, 0, 0, 1, -1, gStransform, 0)
+ turnoff
+endin
+*/
+</CsInstruments>
+<CsScore>
+i"boot" 0 10
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/twist/_unlive/twist_instance_WIP.js b/site/app/twist/_unlive/twist_instance_WIP.js new file mode 100644 index 0000000..1c56cb6 --- /dev/null +++ b/site/app/twist/_unlive/twist_instance_WIP.js @@ -0,0 +1,350 @@ +var TwistInstance = function(index, twist) {
+ var self = this;
+ this.appdata = appdata;
+ this.waveform = null;
+ var waveformFile;
+ var waveformTab;
+ this.onPlays = [];
+ var sr = 44100;
+ var undoLevel;
+
+ function pushOperationLog(operation) {
+ var max = twist.storage.commitHistoryLevel;
+ if (!max) {
+ twist.storage.commitHistoryLevel = max = 16;
+ }
+ if (operationLog.length + 1 >= max) {
+ operationLog.shift();
+ }
+ operationLog.push(operation);
+ }
+
+ this.redraw = function() {
+ self.waveform.redraw();
+ };
+
+ this.close = function() {
+ self.waveform.destroy();
+ delete self.waveform;
+ };
+
+ this.show = function() {
+ self.waveform.show();
+ };
+
+ this.movePlayhead = function() {
+
+ };
+
+ function removeInstance(i) {
+ if (i < 0 || i > this.waveforms.length - 2) {
+ return;
+ }
+ self.waveform.destroy();
+ if (instanceIndex == i) {
+ instanceIndex = i + ((i == 0) ? 1 : -1);
+ self.waveform.show();
+ }
+ }
+
+
+ this.undo = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_undo", globalCallbackHandler, true, null, true);
+ };
+
+ this.cut = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_cut", globalCallbackHandler, true);
+ };
+
+ this.delete = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_delete", globalCallbackHandler, true);
+ };
+
+ this.copy = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_copy", null, true);
+ };
+
+ this.paste = function() {
+ if (playing) return;
+ self.waveform.cover(true);
+ operation("twst_paste", globalCallbackHandler, true);
+ // keep original play position / offset new
+ };
+
+ this.moveToStart = function() {
+ if (playing) return;
+ self.waveform.setSelection(0);
+ };
+
+ this.moveToEnd = function() {
+ if (playing) return;
+ self.waveform.setSelection(1);
+ };
+
+ this.selectAll = function() {
+ if (playing) return;
+ self.waveform.setSelection(0, 1);
+ };
+
+ this.selectNone = function() {
+ if (playing) return;
+ self.waveform.setSelection(0);
+ };
+
+ this.selectToEnd = function() {
+ if (playing) return;
+ self.waveform.alterSelection(null, 1);
+ }
+
+ this.selectFromStart = function() {
+ if (playing) return;
+ self.waveform.alterSelection(0, null);
+ }
+
+ this.play = function() {
+ if (playing) return;
+ auditioning = false;
+ recording = false;
+ operation("twst_play", playPositionHandler(), false, null, true);
+ };
+
+ this.stop = function() {
+ if (!playing) return;
+ self.waveform.cover(false);
+ app.insertScore("twst_stop");
+ };
+
+ function getAutomationData(start, end) {
+ var calls = [];
+ if (!self.currentTransform) return calls;
+ var automations = self.currentTransform.getAutomationData(start, end);
+ if (automations && automations.length > 0) {
+ for (let i in automations) {
+ if (automations[i].type == "modulation") {
+ calls.push(automations[i].data[0] + " \\\"" + automations[i].data[1] + "\\\"");
+ } else if (automations[i].type == "automation") {
+ calls.push("chnset linseg:k(" + automations[i].data + "), \\\"" + automations[i].channel + "\\\"");
+ }
+ }
+ }
+ return calls;
+ }
+
+ function handleAutomation(onready, calls) {
+ if (calls.length == 0) {
+ return onready(0);
+ }
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ onready(1);
+ } else {
+ self.errorHandler("Cannot parse automation data");
+ }
+ });
+
+ var call = [0, 1, cbid];
+ for (let c of calls) {
+ call.push(c);
+ }
+ app.insertScore("twst_automationprepare", call);
+ }
+
+ function compileVariScript(script, onComplete) {
+ var cbid = app.createCallback(function(ndata){
+ onComplete(ndata.status == 1);
+ // should maybe automatically refresh
+ });
+ }
+
+
+ function fftsizeCheck(selected, duration) {
+ if (self.currentTransform) {
+ for (var p in self.currentTransform.parameters) {
+ if (p.indexOf("fftsize") != -1) {
+ var val = self.currentTransform.parameters[p].getValue();
+ var minTime = (val / sr) * 2;
+ if ((selected[1] - selected[0]) * duration < minTime) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ this.record = async function() {
+ if (playing) return;
+ auditioning = false;
+ recording = true;
+ await app.enableAudioInput();
+ errorState = "Recording error";
+ self.waveform.cover(true);
+ var cbid = playPositionHandler();
+ var s = self.waveform.selected;
+ var items = [0, 1, cbid, s[0], s[1], s[2]];
+ app.insertScore("twst_record", items);
+ };
+
+ this.audition = function() {
+ if (playing) return;
+ if (!self.currentTransform) {
+ return self.play();
+ }
+ self.currentTransform.saveState();
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+
+ auditioning = true;
+ recording = false;
+ errorState = "Playback error";
+ handleAutomation(function(automating){
+ var cbid = playPositionHandler();
+ var items = [
+ 0, 1, cbid, s[0], s[1], s[2],
+ self.currentTransform.instr, automating,
+ elCrossfades[0].val(), elCrossfades[1].val()
+ ];
+ app.insertScore("twst_audition", items);
+ }, getAutomationData(s[0], s[1]));
+
+ };
+
+
+ var scriptStack = [];
+ function applyScript(audition) {
+ if (playing) return;
+ var lastData;
+ var script = scriptStack.shift();
+ if (!script) {
+ setLoadingStatus(false);
+ if (lastData) {
+ console.log("ass", lastData);
+ globalCallbackHandler(lastData);
+ }
+ twist.setPlaying(false);
+ return;
+ }
+
+ if (audition) auditioning = true;
+ twist.setPlaying(true);
+ if (script.type == "operation") {
+ if (audition) {
+ return self.errorHandler("Only transform scripts can be auditioned");
+ }
+ self.waveform.cover(true);
+ onComplete = (script.instr == "twst_copy") ? null : globalCallbackHandler;
+ operation(script.instr, function(ndata){
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ }, true, script.selection);
+ } else if (script.type == "transform") {
+ errorState = ((audition) ? "Audition" : "Transform" ) + " commit error";
+ if (!audition) {
+ setLoadingStatus(true, true);
+ }
+
+ for (let channel in script.channels) {
+ app.setControlChannel(channel, script.channels[channel]);
+ }
+ handleAutomation(function(automating){
+ if (audition) {
+ var cbid = playPositionHandler();
+ } else {
+ var cbid = app.createCallback(function(ndata) {
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ });
+ }
+ var instr = "twst_" + ((audition) ? "audition" : "commit");
+
+ app.insertScore(instr, [
+ 0, -1, cbid, script.selection[0], script.selection[1], script.selection[2], script.instr, automating, script.crossfades[0], script.crossfades[1]
+ ]);
+ }, script.automation);
+ }
+ }
+
+ this.applyScript = async function(script, audition) {
+ if (playing) return;
+ scriptStack = [];
+ if (Array.isArray(script)) {
+ if (audition) {
+ return self.errorHandler("Only single scripts can be auditioned");
+ }
+ scriptStack = script;
+ } else {
+ scriptStack = [script];
+ }
+ if (self.storage.autosave && !audition) {
+ self.saveFile(null, function() {
+ applyScript(audition);
+ });
+ } else {
+ applyScript(audition);
+ }
+ };
+
+ async function innerCommit() {
+ if (playing) return;
+ if (!self.currentTransform) return;
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+ watchdog.start("commit");
+ self.setPlaying(true);
+ setLoadingStatus(true, true);
+ var calls = getAutomationData(s[0], s[1]);
+
+ self.currentTransform.saveState();
+ var state = await self.currentTransform.getState();
+ state.type = "transform";
+ state.automation = calls;
+ state.crossfades = [elCrossfades[0].val(), elCrossfades[1].val()];
+ state.selection = [s[0], s[1], s[2]];
+ state.instanceIndex = instanceIndex;
+ pushOperationLog(state);
+
+ handleAutomation(function(automating){
+ var cbid = app.createCallback(function(ndata) {
+ watchdog.stop();
+ setLoadingStatus(false);
+ self.setPlaying(false);
+ if (ndata.status > 0) {
+ globalCallbackHandler(ndata);
+ } else {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file is too large";
+ }
+ self.errorHandler(text);
+ }
+ });
+ errorState = "Transform commit error";
+ app.insertScore("twst_commit", [0, -1, cbid, s[0], s[1], s[2], self.currentTransform.instr, automating, state.crossfades[0],state.crossfades[1]]);
+ }, calls);
+ }
+
+ this.commit = async function() {
+ if (self.storage.autosave) {
+ self.saveFile(null, function() {
+ innerCommit();
+ });
+ } else {
+ innerCommit();
+ }
+ };
+
+}; // end twist
\ No newline at end of file diff --git a/site/app/twist/_unlive/twist_instance_separation_WIP.js b/site/app/twist/_unlive/twist_instance_separation_WIP.js new file mode 100644 index 0000000..3805807 --- /dev/null +++ b/site/app/twist/_unlive/twist_instance_separation_WIP.js @@ -0,0 +1,1250 @@ +var NoteData = function() {
+ var self = this;
+ this.data = null;
+ fetch("../base/notedata.json").then(function(r) {
+ r.json().then(function(j) {
+ self.data = j;
+ });
+ });
+};
+
+
+
+
+var OperationWatchdog = function(twist) {
+ var self = this;
+ var active = false;
+ var lastValues = [true, false];
+ var firstActive = true;
+ var checkInterval;
+ var timeoutTime = 2000;
+ var alivetimeoutTime = 2000;
+ var context;
+
+ function crash() {
+ self.stop();
+ twist.sendErrorState("Unhandled exception in " + context);
+ var el = $("#twist_crash").show();
+ var elSr = $("#twist_crash_recovery");
+
+ function doomed() {
+ elSr.empty().append($("<h4 />").text("Sorry, unfortunately your work cannot be saved."));
+ }
+
+ var doomedTimeout = setTimeout(doomed, 6000);
+
+ var cbid = app.createCallback(function(ndata) {
+ if (doomedTimeout) clearTimeout(doomedTimeout);
+
+ if (!ndata.left && !ndata.right) {
+ return doomed();
+ }
+ elSr.empty();
+ var text;
+ var linkLeft = $("<a />").attr("href", "#").text("Download").click(function(e){
+ e.preventDefault();
+ twist.downloadFile("/crashL.wav");
+ });
+ if (ndata.left && !ndata.right) {
+ elSr.append($("<h4 />").text("Your work has been recovered:"));
+ elSr.append(linkLeft);
+ } else {
+ elSr.append($("<h4 />").text("Your work has been recovered as separate left/right channels:"));
+ linkLeft.text("Download left channel").appendTo(elSr);
+ elSr.append("<br />");
+ var linkRight = $("<a />").attr("href", "#").text("Download right channel").click(function(e){
+ e.preventDefault();
+ twist.downloadFile("/crashR.wav");
+ }).appendTo(elSr);
+ }
+
+ });
+ app.getCsound().compileOrc("iwrittenL = 0\niwrittenR = 0\nif (gitwst_bufferL[gitwst_instanceindex] > 0) then\niwrittenL ftaudio gitwst_bufferL[gitwst_instanceindex], \"/crashL.wav\", 14\nendif\nif (gitwst_bufferR[gitwst_instanceindex] > 0) then\niwrittenR ftaudio gitwst_bufferR[gitwst_instanceindex], \"/crashR.wav\", 14\nendif\nio_sendstring(\"callback\", sprintf(\"{\\\"cbid\\\":" + cbid + ",\\\"left\\\":%d,\\\"right\\\":%d}\", iwrittenL, iwrittenR))\n");
+ }
+
+ function checkAlive() {
+ var alive = false;
+ var aliveTimeout = setTimeout(crash, alivetimeoutTime);
+ var cbid = app.createCallback(function(){
+ clearTimeout(aliveTimeout);
+ alive = true;
+ });
+ app.insertScore("twst_checkalive", [0, 1, cbid]);
+ }
+
+ this.start = function(startContext) {
+ active = true;
+ context = startContext;
+ firstActive = true;
+ lastValues = [true, false];
+ if (checkInterval) clearInterval(checkInterval);
+ checkInterval = setInterval(function() {
+ if (lastValues[0] === lastValues[1]) {
+ checkAlive();
+ }
+ }, timeoutTime);
+ };
+
+ this.setActive = function(value) {
+ if (!active) return;
+ if (firstActive) {
+ firstActive = false;
+ } else {
+ lastValues[0] = lastValues[1];
+ }
+ lastValues[1] = value;
+ };
+
+ this.stop = function() {
+ active = false;
+ firstActive = true;
+ lastValues = [true, false];
+ if (checkInterval) clearInterval(checkInterval);
+ };
+};
+
+var Twist = function(appdata) {
+ var self = this;
+ var audioTypes = ["audio/mpeg", "audio/mp4", "audio/ogg", "audio/vorbis", "audio/x-flac","audio/aiff","audio/x-aiff", "audio/vnd.wav", "audio/wave", "audio/x-wav", "audio/wav", "audio/flac"];
+ var maxsize = 1e+8; // 100 MB
+ this.currentTransform = null;
+ var errorState;
+ var instanceIndex = 0;
+ this.appdata = appdata;
+ this.instances = [];
+ var playheadInterval;
+ var latencyCorrection = 100;
+ var playing = false;
+ var auditioning = false;
+ var scope;
+ var recording = false;
+ var elCrossfades = [];
+ this.onPlays = [];
+ var elToolTip = $("<div />").addClass("tooltip").appendTo($("body"));
+ this.audioContext = null;
+ var operationLog = [];
+ this.noteData = new NoteData();
+ var topMenu = new TopMenu(self, topMenuData, $("#twist_menubar"));
+ this.storage = localStorage.getItem("twist");
+ this.watchdog = new OperationWatchdog(self);
+
+ if (self.storage) {
+ self.storage = JSON.parse(self.storage);
+ } else {
+ self.storage = {};
+ }
+
+ this.tooltip = {
+ show: function(event, text) {
+ var margin = 100;
+ elToolTip.text(text).css("opacity", 0.9);
+
+ if (event.pageX >= window.innerWidth - margin) {
+ elToolTip.css({left: window.innerWidth - (margin * 2) + "px"});
+ } else {
+ elToolTip.css({left: (event.pageX + 20) + "px"});
+ }
+
+ if (event.pageY >= window.innerHeight - margin) {
+ elToolTip.css({top: window.innerHeight - (margin * 2) + "px"});
+ } else {
+ elToolTip.css({top: (event.pageY - 15) + "px"});
+ }
+
+ },
+ hide: function() {
+ elToolTip.css("opacity", 0);
+ }
+ };
+
+ this.setPlaying = function(state) {
+ if (playing == state) return;
+ playing = state;
+ for (var o of self.onPlays) {
+ o(playing, auditioning, recording);
+ }
+ if (self.currentTransform) {
+ self.currentTransform.setPlaying(state);
+ }
+ if (scope) {
+ scope.setPlaying(state);
+ }
+ };
+
+ this.saveStorage = function() {
+ localStorage.setItem("twist", JSON.stringify(self.storage));
+ };
+
+ function lastOperation() {
+ return operationLog[operationLog.length - 1];
+ }
+
+ function pushOperationLog(operation) {
+ var max = self.storage.commitHistoryLevel;
+ if (!max) {
+ self.storage.commitHistoryLevel = max = 16;
+ }
+ if (operationLog.length + 1 >= max) {
+ operationLog.shift();
+ }
+ operationLog.push(operation);
+ }
+
+
+ function showLoadNewPrompt() {
+ var elNewFile = $("<div />").css({"font-size": "var(--fontSizeDefault)"});
+ elNewFile.append($("<h3 />").text("Drag an audio file here to load")).append($("<p />").text("or"));
+
+ $("<h4 />").text("Create an empty file").css("cursor", "pointer").appendTo(elNewFile).click(function() {
+ elNewFile.show();
+ });
+
+ var tpDuration = new TransformParameter(null, {name: "Duration", min: 0.1, max: 60, dfault: 10, automatable: false, fireChanges: false}, null, null, twist);
+
+ var tpChannels = new TransformParameter(null, {name: "Channels", min: 1, max: 2, dfault: 2, step: 1, automatable: false, fireChanges: false}, null, null, twist);
+
+ var tpName = new TransformParameter(null, {name: "Name", type: "string", dfault: "New file", fireChanges: false}, null, null, twist);
+
+ var tb = $("<tbody />");
+ $("<table />").append(tb).css("margin", "0 auto").appendTo(elNewFile);
+ tb.append(tpDuration.getElementRow(true)).append(tpChannels.getElementRow(true)).append(tpName.getElementRow(true));
+
+ $("<button />").text("Create").appendTo(elNewFile).click(function() {
+ var name = tpName.getValue();
+ if (name.trim() == "") {
+ name = "New file";
+ }
+ var cbid = app.createCallback(async function(ndata) {
+ self.waveformTab.text(name);
+ await globalCallbackHandler(ndata);
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ waveformFiles[instanceIndex] = name;
+ setLoadingStatus(false);
+ });
+ self.hidePrompt();
+ setLoadingStatus(true, false, "Creating");
+ app.insertScore("twst_createempty", [0, 1, cbid, tpDuration.getValue(), tpChannels.getValue()]);
+ });
+
+ self.showPrompt(elNewFile, null, true);
+ }
+
+ this.toggleScope = function(noSaveState) {
+ var height;
+ var top;
+ var state;
+ if (!scope) {
+ state = true;
+ height = "60%";
+ top = "40%";
+ var elScope = $("<div />").addClass("twist_scope").appendTo($("#twist_waveforms"));
+ var type = (self.storage.scopeType) ? self.storage.scopeType : "frequency";
+ scope = new Analyser(
+ type, self, elScope, app
+ );
+ } else {
+ state = false;
+ scope.remove();
+ delete scope;
+ scope = null;
+ height = "100%";
+ top = "0px";
+ }
+
+ if (!noSaveState) {
+ self.storage.showScope = state;
+ self.saveStorage();
+ }
+ $(".waveform").css({height: height, top: top});
+ }
+
+ this.createNewInstance = function() {
+ var element = $("<div />").addClass("waveform").appendTo("#twist_waveforms");
+ let index = waveformFiles.length;
+
+ if (index < 0) index = 0;
+ waveformTabs.push(
+ $("<td />").text("New file").click(function() {
+ if (self.isPlaying()) return;
+ self.waveform = index;
+ }).addClass("wtab_selected").appendTo("#twist_waveform_tabs")
+ );
+ undoLevels.push(0);
+ self.waveforms.push(
+ new Waveform({
+ target: element,
+ latencyCorrection: latencyCorrection,
+ showcrossfades: true,
+ crossFadeWidth: 1,
+ timeBar: true,
+ markers: [
+ {preset: "selectionstart"},
+ {preset: "selectionend"},
+ ]
+ })
+ );
+ showLoadNewPrompt();
+ self.waveform = index;
+ };
+
+
+
+
+
+ this.removeInstance = function(i) {
+ if (!i) i = instanceIndex;
+ if (i < 0 || i > this.instances.length - 1) {
+ return;
+ }
+ self.instances[instanceindex].close();
+ if (instanceIndex == i) {
+ instanceIndex = i + ((i == 0) ? 1 : -1);
+ self.instances[instanceIndex].show();
+ }
+ };
+
+ t
+
+ var remoteSessionID;
+ var remoteSending = false;
+ this.sendErrorState = async function (errorText) {
+ if (remoteSending) return;
+ remoteSending = true;
+ var data = {
+ request_type: "LogError",
+ error: {
+ text: errorText,
+ lastOperation: lastOperation()
+ }
+ };
+
+ if (self.currentTransform) {
+ var state = await self.currentTransform.getState();
+ data.error.transformState = state;
+ }
+
+ if (remoteSessionID) {
+ data.session_id = remoteSessionID;
+ }
+ var resp = await fetch("/service/", {
+ method: "POST",
+ headers: {
+ "Content-type": "application/json"
+ },
+ body: JSON.stringify(data)
+ });
+ var json = await resp.json();
+ if (json.session_id && !remoteSessionID) {
+ remoteSessionID = json.session_id;
+ }
+ remoteSending = false;
+ }
+
+ this.errorHandler = function(text, onComplete) {
+ var errorText = (!text) ? errorState : text;
+ self.sendErrorState(errorText);
+ self.setPlaying(false);
+ self.showPrompt(errorText, onComplete);
+ errorState = null;
+ };
+
+ function playPositionHandler(noPlayhead, onComplete) {
+ function callback(ndata) {
+ if (ndata.status == 1) {
+ self.setPlaying(true);
+ if (!noPlayhead) {
+ watchdog.start("audition");
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ playheadInterval = setInterval(async function(){
+ var val = await app.getControlChannel("playposratio");
+ watchdog.setActive(val);
+ if (val < 0 || val > 1) {
+ clearInterval(playheadInterval);
+ }
+ self.waveform.movePlayhead(val);
+ }, 50);
+ }
+ } else {
+ self.setPlaying(false);
+ if (ndata.status == -1) {
+ self.errorHandler("Not enough processing power to transform in realtime");
+ }
+
+ app.removeCallback(ndata.cbid);
+ if (!noPlayhead) {
+ watchdog.stop();
+ self.waveform.movePlayhead(0);
+ if (playheadInterval) {
+ clearInterval(playheadInterval);
+ }
+ }
+ if (onComplete) onComplete();
+ }
+ }
+ return app.createCallback(callback, true);
+ }
+
+ function operation(instr, oncompleteOrCbidOverride, showLoading, selection, noLogScript) {
+ var s = (selection) ? selection : self.waveform.selected;
+ errorState = "Operation error";
+ if (showLoading) {
+ setLoadingStatus(true);
+ }
+ var cbid;
+ if (!oncompleteOrCbidOverride || typeof(oncompleteOrCbidOverride) == "function") {
+ cbid = app.createCallback(function(ndata) {
+ self.waveform.cover(false);
+ if (oncompleteOrCbidOverride) {
+ oncompleteOrCbidOverride(ndata);
+ } else if (ndata.status && ndata.status <= 0) {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file is too large";
+ }
+ self.errorHandler(text);
+ }
+ if (showLoading) {
+ setLoadingStatus(false);
+ }
+ });
+ } else {
+ cbid = oncompleteOrCbidOverride;
+ }
+ if (!noLogScript) {
+ pushOperationLog({type: "operation", instr: instr, selection: s, instanceIndex: instanceIndex});
+ }
+ app.insertScore(instr, [0, 1, cbid, s[0], s[1], s[2]]);
+ }
+
+ this.isPlaying = function() {
+ return playing;
+ };
+
+
+
+ this.pasteSpecial = function() {
+ if (playing) return;
+ var elPasteSpecial = $("<div />");
+ elPasteSpecial.append($("<h4 />").text("Paste special"));
+ var def = {
+ instr: "twst_pastespecial",
+ parameters: [
+ {name: "Repetitions", channel: "repetitions", min: 1, max: 40, step: 1, dfault: 1, automatable: false},
+ {name: "Mix paste", channel: "mixpaste", step: 1, dfault: 0, automatable: false},
+ {name: "Mix crossfade", channel: "mixfade", automatable: false, conditions: [{channel: "mixpaste", operator: "eq", value: 1}]}
+ ]
+ };
+ var tf = new Transform(elPasteSpecial, def, self);
+
+ $("<button />").text("Paste").click(function(){
+ self.hidePrompt();
+ self.waveform.cover(true);
+ operation("twst_pastespecial", globalCallbackHandler, true);
+ }).appendTo(elPasteSpecial);
+
+ $("<button />").text("Cancel").click(function(){
+ self.hidePrompt();
+ }).appendTo(elPasteSpecial);
+ self.showPrompt(elPasteSpecial, null, true);
+
+ };
+
+ this.developerConsole = function() {
+ $("#twist_developer").show();
+ $("#twist_inject_devcsound").click(async function() {
+ var code = $("#twist_devcsound").val();
+ var result = await app.compileOrc(code);
+ if (result == 0) {
+ if (!self.storage.develop) {
+ self.storage.develop = {};
+ }
+ self.storage.develop.csound = code;
+ self.saveStorage();
+ self.showPrompt("Successfully injected Csound code");
+ }
+ });
+ $("#twist_inject_devjson").click(async function() {
+ var code = $("#twist_devjson").val();
+ try {
+ var json = JSON.parse(code);
+ } catch (e) {
+ return self.errorHandler("Cannot parse JSON: " + e);
+ }
+ try {
+ self.loadTransforms(json);
+ } catch (e) {
+ return self.errorHandler("Cannot load transform: " + e);
+ }
+ if (!self.storage.develop) {
+ self.storage.develop = {};
+ }
+ self.storage.develop.json = code;
+ self.saveStorage();
+ self.showPrompt("Successfully injected transform definition");
+ });
+ $("#twist_exit_devcode").click(async function() {
+ $("#twist_developer").hide();
+ });
+ };
+
+ this.play = function() {
+ if (playing) return;
+ auditioning = false;
+ recording = false;
+ operation("twst_play", playPositionHandler(), false, null, true);
+ };
+
+ this.stop = function() {
+ if (!playing) return;
+ self.waveform.cover(false);
+ app.insertScore("twst_stop");
+ };
+
+ function formatFileName(name) {
+ if (!name) name = waveformTabs[instanceIndex].text();
+ if (!name.toLowerCase().endsWith(".wav")) {
+ name += ".wav";
+ }
+
+ // HACK TODO: WASM can't overwrite files
+ name = name.substr(0, name.lastIndexOf(".")) + "." + saveNumber + name.substr(name.lastIndexOf("."));
+ saveNumber ++;
+ // END HACK
+ return name;
+ }
+
+ this.downloadFile = async function(path, name) {
+ if (!name) name = formatFileName(name);
+ var content = await app.readFile(path);
+ var blob = new Blob([content], {type: "audio/wav"});
+ var url = window.URL.createObjectURL(blob);
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a[0].click();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ app.unlinkFile(path);
+ }, 20000);
+ };
+
+ var saveNumber = 1;
+ this.saveFile = function(name, onComplete) {
+ if (playing) return;
+ if (!name) name = formatFileName(name);
+ var cbid = app.createCallback(async function(ndata){
+ await self.downloadFile("/" + name, name);
+ if (onComplete) onComplete();
+ setLoadingStatus(false);
+ });
+ setLoadingStatus(true, true, "Saving");
+ app.insertScore("twst_savefile", [0, 1, cbid, name]);
+ };
+
+ function getAutomationData(start, end) {
+ var calls = [];
+ if (!self.currentTransform) return calls;
+ var automations = self.currentTransform.getAutomationData(start, end);
+ if (automations && automations.length > 0) {
+ for (let i in automations) {
+ if (automations[i].type == "modulation") {
+ calls.push(automations[i].data[0] + " \\\"" + automations[i].data[1] + "\\\"");
+ } else if (automations[i].type == "automation") {
+ calls.push("chnset linseg:k(" + automations[i].data + "), \\\"" + automations[i].channel + "\\\"");
+ }
+ }
+ }
+ return calls;
+ }
+
+ function handleAutomation(onready, calls) {
+ if (calls.length == 0) {
+ return onready(0);
+ }
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ onready(1);
+ } else {
+ self.errorHandler("Cannot parse automation data");
+ }
+ });
+
+ var call = [0, 1, cbid];
+ for (let c of calls) {
+ call.push(c);
+ }
+ app.insertScore("twst_automationprepare", call);
+ }
+
+ function compileVariScript(script, onComplete) {
+ var cbid = app.createCallback(function(ndata){
+ onComplete(ndata.status == 1);
+ // should maybe automatically refresh
+ });
+ }
+
+
+ function fftsizeCheck(selected, duration) {
+ if (self.currentTransform) {
+ for (var p in self.currentTransform.parameters) {
+ if (p.indexOf("fftsize") != -1) {
+ var val = self.currentTransform.parameters[p].getValue();
+ var minTime = (val / sr) * 2;
+ if ((selected[1] - selected[0]) * duration < minTime) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ this.record = async function() {
+ if (playing) return;
+ auditioning = false;
+ recording = true;
+ await app.enableAudioInput();
+ errorState = "Recording error";
+ self.waveform.cover(true);
+ var cbid = playPositionHandler();
+ var s = self.waveform.selected;
+ var items = [0, 1, cbid, s[0], s[1], s[2]];
+ app.insertScore("twst_record", items);
+ };
+
+ this.audition = function() {
+ if (playing) return;
+ if (!self.currentTransform) {
+ return self.play();
+ }
+ self.currentTransform.saveState();
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+
+ auditioning = true;
+ recording = false;
+ errorState = "Playback error";
+ handleAutomation(function(automating){
+ var cbid = playPositionHandler();
+ var items = [
+ 0, 1, cbid, s[0], s[1], s[2],
+ self.currentTransform.instr, automating,
+ elCrossfades[0].val(), elCrossfades[1].val()
+ ];
+ app.insertScore("twst_audition", items);
+ }, getAutomationData(s[0], s[1]));
+
+ };
+
+
+ var scriptStack = [];
+ function applyScript(audition) {
+ if (playing) return;
+ var lastData;
+ var script = scriptStack.shift();
+ if (!script) {
+ setLoadingStatus(false);
+ if (lastData) {
+ console.log("ass", lastData);
+ globalCallbackHandler(lastData);
+ }
+ self.setPlaying(false);
+ return;
+ }
+
+ if (audition) auditioning = true;
+ self.setPlaying(true);
+ if (script.type == "operation") {
+ if (audition) {
+ return self.errorHandler("Only transform scripts can be auditioned");
+ }
+ self.waveform.cover(true);
+ onComplete = (script.instr == "twst_copy") ? null : globalCallbackHandler;
+ operation(script.instr, function(ndata){
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ }, true, script.selection);
+ } else if (script.type == "transform") {
+ errorState = ((audition) ? "Audition" : "Transform" ) + " commit error";
+ if (!audition) {
+ setLoadingStatus(true, true);
+ }
+
+ for (let channel in script.channels) {
+ app.setControlChannel(channel, script.channels[channel]);
+ }
+ handleAutomation(function(automating){
+ if (audition) {
+ var cbid = playPositionHandler();
+ } else {
+ var cbid = app.createCallback(function(ndata) {
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition);
+ });
+ }
+ var instr = "twst_" + ((audition) ? "audition" : "commit");
+
+ app.insertScore(instr, [
+ 0, -1, cbid, script.selection[0], script.selection[1], script.selection[2], script.instr, automating, script.crossfades[0], script.crossfades[1]
+ ]);
+ }, script.automation);
+ }
+ }
+
+ this.applyScript = async function(script, audition) {
+ if (playing) return;
+ scriptStack = [];
+ if (Array.isArray(script)) {
+ if (audition) {
+ return self.errorHandler("Only single scripts can be auditioned");
+ }
+ scriptStack = script;
+ } else {
+ scriptStack = [script];
+ }
+ if (self.storage.autosave && !audition) {
+ self.saveFile(null, function() {
+ applyScript(audition);
+ });
+ } else {
+ applyScript(audition);
+ }
+ };
+
+ async function innerCommit() {
+ if (playing) return;
+ if (!self.currentTransform) return;
+ var s = self.waveform.selected;
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+ watchdog.start("commit");
+ self.setPlaying(true);
+ setLoadingStatus(true, true);
+ var calls = getAutomationData(s[0], s[1]);
+
+ self.currentTransform.saveState();
+ var state = await self.currentTransform.getState();
+ state.type = "transform";
+ state.automation = calls;
+ state.crossfades = [elCrossfades[0].val(), elCrossfades[1].val()];
+ state.selection = [s[0], s[1], s[2]];
+ state.instanceIndex = instanceIndex;
+ pushOperationLog(state);
+
+ handleAutomation(function(automating){
+ var cbid = app.createCallback(function(ndata) {
+ watchdog.stop();
+ setLoadingStatus(false);
+ self.setPlaying(false);
+ if (ndata.status > 0) {
+ globalCallbackHandler(ndata);
+ } else {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file is too large";
+ }
+ self.errorHandler(text);
+ }
+ });
+ errorState = "Transform commit error";
+ app.insertScore("twst_commit", [0, -1, cbid, s[0], s[1], s[2], self.currentTransform.instr, automating, state.crossfades[0],state.crossfades[1]]);
+ }, calls);
+ }
+
+ this.commit = async function() {
+ if (self.storage.autosave) {
+ self.saveFile(null, function() {
+ innerCommit();
+ });
+ } else {
+ innerCommit();
+ }
+ };
+
+ this.createIcon = function(definition) {
+ var state = true;
+ var active = true;
+ function formatPath(i) {
+ return "../base/icon/" + i + ".svg";
+ }
+ var el = $("<img />");
+
+ var obj = {
+ el: el,
+ setState: function(tstate) {
+ if (!definition.icon2) return;
+ state = tstate;
+ if (state) {
+ el.attr("src", formatPath(definition.icon));
+ } else {
+ el.attr("src", formatPath(definition.icon2));
+ }
+
+ },
+ setActive: function(state) {
+ if (state) {
+ el.css("opacity", 1);
+ active = true;
+ } else {
+ el.css("opacity", 0.4);
+ active = false;
+ }
+ }
+ };
+
+ el.addClass("icon").css("opacity", 1).attr("src", formatPath(definition.icon)).on("mouseover", function(event){
+ var label = (!state && definition.label2) ? definition.label2 : definition.label;
+ self.tooltip.show(event, label);
+ }).on("mouseout", function(){
+ self.tooltip.hide();
+ }).click(function(el) {
+ if (active) definition.click(obj);
+ });
+ return obj;
+ }
+
+ function buildWavecontrols() {
+ var el = $("#twist_wavecontrols_inner");
+ var onPlayDisables = [];
+
+ var play = self.createIcon({label: "Play", icon: "play", label2: "Stop", icon2: "stop", click: function(obj){
+ if (self.isPlaying()) {
+ self.stop();
+ } else {
+ self.play();
+ }
+ }});
+ var audition = self.createIcon({label: "Audition", icon: "audition", label2: "Stop", icon2: "stop", click: function(obj){
+ if (self.isPlaying()) {
+ self.stop();
+ } else {
+ self.audition();
+ }
+ }});
+ var crossfade = self.createIcon({label: "Show crossfades", icon: "crossfade", label2: "Hide crossfades", icon2: "hide", click: function(obj){
+ var el = $(".crossfade");
+ if (el.is(":visible")) {
+ obj.setState(true);
+ el.hide();
+ self.storage.showCrossfades = false;
+ elCrossfades[0].val(0).trigger("input");
+ elCrossfades[1].val(0).trigger("input");
+ } else {
+ el.show();
+ obj.setState(false);
+ self.storage.showCrossfades = true;
+ }
+ self.saveStorage();
+ }});
+
+ var record = self.createIcon({label: "Record", icon: "record", label2: "Stop", icon2: "stop", click: function() {
+ if (self.isPlaying()) {
+ self.stop();
+ } else {
+ self.record();
+ }
+ }});
+
+ var items = [
+ {label: "Zoom selection", icon: "zoomSelection", click: function() {self.waveform.zoomSelection();}},
+ {label: "Zoom in", icon: "zoomIn", click: function() {self.waveform.zoomIn();}},
+ {label: "Zoom out", icon: "zoomOut", click: function() {self.waveform.zoomOut();}},
+ {label: "Show all", icon: "showAll", click: function() {self.waveform.setRegion(0, 1);}},
+ {label: "Cut", icon: "cut", disableOnPlay: true, click: self.cut},
+ {label: "Copy", icon: "copy", disableOnPlay: true, click: self.copy},
+ {label: "Paste", icon: "paste", disableOnPlay: true, click: self.paste},
+ {label: "Paste special", icon: "pasteSpecial", disableOnPlay: true, click: self.pasteSpecial},
+ {label: "Rewind", icon: "rewind", disableOnPlay: true, click: self.moveToStart},
+ play,
+ audition,
+ {label: "Commit", icon: "commit", disableOnPlay: true, click: self.commit},
+ record,
+ {label: "Save", icon: "save", disableOnPlay: true, click: self.saveFile},
+ {label: "Script", icon: "script", click: self.scriptEdit},
+ {label: "Developer", icon: "develop", click: self.developerConsole},
+ crossfade
+ ];
+
+ for (let i of items) {
+ var icon;
+ if (i.icon) {
+ icon = self.createIcon(i);
+ if (i.disableOnPlay) {
+ onPlayDisables.push(icon);
+ }
+ } else {
+ icon = i;
+ }
+ $("<td />").append(icon.el).appendTo(el);
+ }
+
+ twist.onPlays.push(async function(playing, auditioning, recording) {
+ if (playing) {
+ if (auditioning) {
+ play.setActive(false);
+ audition.setState(false);
+ record.setActive(false);
+ } else if (recording) {
+ audition.setActive(false);
+ play.setActive(false);
+ record.setState(false);
+ } else {
+ audition.setActive(false);
+ play.setState(false);
+ record.setActive(false);
+ }
+ } else {
+ audition.setActive(true);
+ play.setActive(true);
+ play.setState(true);
+ audition.setState(true);
+ record.setActive(true);
+ record.setState(true);
+ }
+ for (let o of onPlayDisables) {
+ o.setActive(!playing);
+ }
+ });
+
+ for (let e of ["In", "Out"]) {
+ let elRange = $("<input />").addClass("tp_slider").attr("type", "range").attr("min", 0).attr("max", 0.45).attr("step", 0.00001).val(0).on("input", function() {
+ if (e == "In") {
+ self.waveform.crossFadeInRatio = $(this).val();
+ } else {
+ self.waveform.crossFadeOutRatio = $(this).val();
+ }
+ });
+ elCrossfades.push(elRange);
+ $("<td />").addClass("crossfade").append($("<div />").css("font-size", "8pt").text("Crossfade " + e)).append(elRange).appendTo(el);
+ }
+
+ var el = $(".crossfade");
+ if (self.storage.hasOwnProperty("showCrossfades")) {
+ if (self.storage.showCrossfades) {
+ crossfade.setState(false);
+ el.show();
+ } else {
+ crossfade.setState(true);
+ el.hide();
+ }
+ } else {
+ crossfade.setState(false);
+ el.show();
+ }
+
+ }
+
+ this.loadTransforms = function(transform) {
+ if (transform) {
+ var developObj;
+ for (var t in appdata.transforms) {
+ if (appdata.transforms[t].name == "Develop") {
+ developObj = appdata.transforms[t];
+ break;
+ }
+ }
+ if (!developObj) {
+ developObj = {name: "Develop", contents: []};
+ appdata.transforms.push(developObj);
+ } else {
+ for (var c in developObj.contents) {
+ if (developObj.contents[c].name == transform.name) {
+ delete developObj.contents[c];
+ }
+ }
+ }
+ developObj.contents.push(transform);
+ }
+
+ $("#twist_panetree").empty();
+ var ttv = new TransformsTreeView({
+ target: "twist_panetree",
+ items: appdata.transforms
+ }, self);
+ };
+
+ this.showHelp = function() {
+ $("#twist_help").show();
+ };
+
+ this.showAbout = function() {
+ var el = $("<div />");
+ var x = $("<h3 />").text("twist").appendTo(el);
+ $("<p />").text("Version " + appdata.version.toFixed(1)).appendTo(el);
+ $("<p />").css("font-size", "12px").text("By Richard Knight 2024").appendTo(el);
+
+ var skewMax = 30;
+ var skew = 0;
+ var skewDirection = true;
+ var twistInterval = setInterval(function(){
+ if (skewDirection) {
+ if (skew < skewMax) {
+ skew ++;
+ } else {
+ skewDirection = false;
+ }
+ } else {
+ if (skew > -skewMax) {
+ skew --;
+ } else {
+ skewDirection = true;
+ }
+ }
+ x.css("transform", "skewX(" + skew + "deg)");
+ }, 10);
+
+ self.showPrompt(el, function(){
+ clearInterval(twistInterval);
+ });
+ };
+
+ async function handleFileDrop(e, obj) {
+ e.preventDefault();
+ if (!e.originalEvent.dataTransfer && !e.originalEvent.files) {
+ return;
+ }
+ if (e.originalEvent.dataTransfer.files.length == 0) {
+ return;
+ }
+ self.hidePrompt();
+ setLoadingStatus(true, false, "Loading");
+ for (const item of e.originalEvent.dataTransfer.files) {
+ if (!audioTypes.includes(item.type)) {
+ return self.errorHandler("Unsupported file type", showLoadNewPrompt);
+ }
+ if (item.size > maxsize) {
+ return self.errorHandler("File too large", showLoadNewPrompt);
+ }
+ errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ await app.writeFile(item.name, buffer);
+ var cbid = app.createCallback(async function(ndata){
+ await app.unlinkFile(item.name);
+ if (ndata.status == -1) {
+ return self.errorHandler("File not valid", showLoadNewPrompt);
+ } else if (ndata.status == -2) {
+ return self.errorHandler("File too large", showLoadNewPrompt);
+ } else {
+ self.waveformTab.text(item.name);
+ await globalCallbackHandler(ndata);
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ waveformFiles[instanceIndex] = item.name;
+ self.hidePrompt();
+ setLoadingStatus(false);
+ }
+ });
+ app.insertScore("twst_loadfile", [0, 1, cbid, item.name]);
+ }
+ }
+
+ async function globalCallbackHandler(ndata) {
+ if (ndata.status && ndata.status <= 0) {
+ self.errorHandler();
+ return;
+ }
+
+ if (ndata.hasOwnProperty("undolevel")) {
+ self.undoLevel = ndata.undolevel;
+ }
+
+ if (ndata.hasOwnProperty("delete")) {
+ if (typeof(ndata.delete) == "string") {
+ app.unlinkFile(ndata.delete);
+ } else {
+ for (let d of ndata.delete) {
+ app.unlinkFile(d);
+ }
+ }
+ }
+
+ if (ndata.hasOwnProperty("selstart")) {
+ self.waveform.setSelection(ndata.selstart, ndata.selend);
+ }
+
+ if (ndata.hasOwnProperty("waveL")) {
+ self.waveform.cover(true);
+ errorState = "Overview refresh error";
+ var wavedata = [];
+ var duration = ndata.duration;
+ var tbL = await app.getTable(ndata.waveL);
+ wavedata.push(tbL);
+ if (ndata.hasOwnProperty("waveR")) {
+ var tbR = app.getTable(ndata.waveR);
+ wavedata.push(tbR);
+ }
+ self.waveform.setData(wavedata, ndata.duration);
+ self.waveform.cover(false);
+ }
+
+ }
+
+ this.bootAudio = function() {
+ var channelDefaultItems = ["dcblockoutputs", "tanhoutputs", "maxundo"];
+
+ for (var i of channelDefaultItems) {
+ if (self.storage.hasOwnProperty(i)) {
+ app.setControlChannel(i, self.storage[i]);
+ }
+ }
+
+ twist.setLoadingStatus(false);
+
+ if (!self.storage.hasOwnProperty("firstLoadDone")) {
+ self.storage.firstLoadDone = true;
+ self.saveStorage();
+ self.showPrompt($("#twist_welcome").detach().show(), self.createNewInstance);
+ } else {
+ self.createNewInstance();
+ }
+
+ if (self.storage.showScope) {
+ self.toggleScope(true);
+ }
+ };
+
+ this.boot = function() {
+ self.audioContext = new AudioContext();
+ if (self.storage.theme) {
+ self.setTheme(self.storage.theme, true);
+ }
+
+ if (self.storage.hasOwnProperty("showShortcuts")) {
+ if (self.storage.showShortcuts) {
+ $("#twist_wavecontrols_inner").show();
+ } else {
+ $("#twist_wavecontrols_inner").hide();
+ }
+ }
+
+ if (self.storage.develop) {
+ if (self.storage.develop.csound) {
+ $("#twist_devcsound").val(self.storage.develop.csound);
+ }
+ if (self.storage.develop.json) {
+ $("#twist_devjson").val(self.storage.develop.json);
+ }
+ }
+ $("#loading_background").css("opacity", 1).animate({opacity: 0.2}, 1000);
+
+ Object.defineProperty(this, "waveformTab", {
+ get: function() { return waveformTabs[instanceIndex]; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "otherInstanceNames", {
+ get: function() {
+ var data = {};
+ for (var i in waveformTabs) {
+ if (i != instanceIndex) {
+ data[i] = waveformTabs[i].text();
+ }
+ }
+ return data
+ },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "instanceIndex", {
+ get: function() {
+ return instanceIndex
+ },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "undoLevel", {
+ get: function() {
+ return undoLevels[instanceIndex];
+ },
+ set: function(x) {
+ undoLevels[instanceIndex] = x;
+ }
+ });
+
+ Object.defineProperty(this, "waveform", {
+ get: function() { return self.waveforms[instanceIndex]; },
+ set: function(x) {
+ if (instanceIndex != x) {
+ if (self.waveformTab) {
+ self.waveformTab.removeClass("wtab_selected").addClass("wtab_unselected");
+ }
+ if (self.waveform) {
+ self.waveform.hide();
+ }
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ instanceIndex = x;
+ self.waveformTab.removeClass("wtab_unselected").addClass("wtab_selected");
+ self.waveform.show();
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ } else {
+ self.showPrompt("Error changing instance");
+ }
+ });
+ app.insertScore("twst_setinstance", [0, 1, cbid, x]);
+
+ }
+ }
+ });
+
+ $("#twist_help").click(function() {
+ $(this).hide();
+ });
+
+ $("<td />").text("+").click(function() {
+ self.createNewInstance();
+ }).appendTo("#twist_waveform_tabs").addClass("wtab_selected");
+
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ }).on("drop", function(e) {
+ handleFileDrop(e, self);
+ });
+
+ buildWavecontrols();
+ self.loadTransforms();
+ };
+
+}; // end twist
+
+$(function() {
+
+ var csOptions = ["--omacro:TWST_FAILONLAG=1"];
+ window.twist = new Twist(appdata);
+ window.app = new CSApplication({
+ csdUrl: "twist.csd",
+ csOptions: csOptions,
+ onPlay: function () {
+ twist.bootAudio();
+ },
+ errorHandler: twist.errorHandler,
+ ioReceivers: {percent: twist.setPercent}
+ });
+
+ $("#start").click(function() {
+ $("#start").hide();
+ twist.boot();
+ twist.setLoadingStatus(true, false, "Preparing audio engine");
+ app.play(function(text){
+ twist.setLoadingStatus(true, false, text);
+ }, twist.audioContext);
+ });
+
+});
\ No newline at end of file diff --git a/site/app/twist/developer_documentation.html b/site/app/twist/developer_documentation.html new file mode 100644 index 0000000..f44f778 --- /dev/null +++ b/site/app/twist/developer_documentation.html @@ -0,0 +1,742 @@ +<html>
+<head>
+ <script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+ <style type="text/css">
+ body {
+ font-family: Arial, sans-serif;
+ }
+
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 1px solid black;
+ }
+
+ pre {
+ font-family: Monospace, Courier, sans-serif;
+ background-color: #ccffff;
+ }
+
+ #container_overview {
+ background-color: #ddddff;
+ }
+
+ #container_json {
+ background-color: #ddffdd;
+ }
+
+ #container_csound {
+ background-color: #ddffff;
+ }
+
+ #container_examples {
+ background-color: #ffffdd;
+ }
+
+ </style>
+ <script type="text/javascript">
+ var documentation = {};
+ documentation.opcodes = [
+ {
+ name: "twst_param",
+ ins: [
+ ["Sname", "Name of the parameter to obtain"]
+ ],
+ outs: [
+ ["kvalue", "Value of the parameter"]
+ ],
+ description: "Obtain a parameter at k-rate. The name should correspond to the {json(channel)} in the definition for the given transform",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {name: "Frequency", min: 20, max: 8000, dfault: 440}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\nkfreq twst_param "frequency"\nif (ileft == 1) then\n\t aL oscil 1, kfreq\nendif\nif (iright == 1) then\n\taR oscil 1, kfreq\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_parami",
+ ins: [
+ ["Sname", "Name of the parameter to obtain"]
+ ],
+ outs: [
+ ["ivalue", "Value of the parameter"]
+ ],
+ description: "Obtain a parameter at init time. The name should correspond to the {json(channel)} in the definition for the given transform",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {name: "Frequency", min: 20, max: 8000, dfault: 440}
+ ]
+ },
+ exampleCsound: 'ifreq twst_parami "frequency"\naout oscil 1, ifreq\nouts aout, aout'
+ },
+ {
+ name: "twst_tf_isoffline",
+ outs: [
+ ["ioffline", "Whether processing is offline"]
+ ],
+ description: "Get a boolean signifying whether the current operation is a commit (1) or audition (0)",
+ exampleJson: {
+ name: "Reverse",
+ instr: "twst_tfi_example_reverse",
+ parameters: []
+ },
+ exampleCsound: 'ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate\nifnL, ifnR twst_tfi_getfn\nioffline twst_tf_isoffline\napos linseg (iendsamp - istartsamp) - 1, ilength, 0\nif (ileft == 1) then\n\tif (ioffline == 1) then\n\t\tifntempL ftgentmp 0, 0, -ftlen(ifnL), -2, 0\n\t\ttableicopy ifntempL, ifnL\n\t\taL table3 apos, ifntempL\n\telse\n\t\taL table3 apos, ifnL\n\tendif\nendif\nif (iright == 1) then\n\tif (ioffline == 1) then\n\t\tifntempR ftgentmp 0, 0, -ftlen(ifnR), -2, 0\n\t\ttableicopy ifntempR, ifnR\n\t\taR table3 apos, ifntempR\n\telse\n\t\taR table3 apos, ifnR\n\tendif\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_getinput",
+ outs: [
+ ["aL", "Left channel"],
+ ["aR", "Right channel"],
+ ["ileft", "Whether the left channel is to be processed"],
+ ["iright", "Whether the right channel is to be processed"]
+ ],
+ description: "Get input audio and channel flags for the current transform process. The transform should utilise ileft and iright, which are set to either 0 or 1, to process the inputs accordingly. If the instrument does not process audio (ie, generates new audio), then this opcode can still be used to obtain ileft and iright. This can also be obtained from {csound(twst_tf_getstate)}",
+ exampleJson: {
+ name: "Gain",
+ instr: "twst_tf_example_gain",
+ parameters: [
+ {name: "Gain"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\nkgain twst_param "gain"\nif (ileft == 1) then\n\taL *= kgain\nendif\nif (iright == 1) then\n\taR *= kgain\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_getfinput",
+ ins: [
+ ["fftsize", "FFT size", "{preset(fftsize)}"]
+ ],
+ outs: [
+ ["fL", "Left channel"],
+ ["fR", "Right channel"],
+ ["aL", "Left channel"],
+ ["aR", "Right channel"],
+ ["ileft", "Whether the left channel is to be processed"],
+ ["iright", "Whether the right channel is to be processed"]
+ ],
+ description: "Get input audio as a PVS stream along with channel flags for the current transform process. The transform should utilise ileft and iright, which are set to either 0 or 1, to process the inputs accordingly. FFT size is optional and obtains the value from {preset(fftsize)} if not specified. Frequency/phase lock is also applied according to the parameter in the preset group {presetgroup(pvsynth)}",
+ exampleJson: {
+ name: "Repitcher",
+ instr: "twst_tf_example_pvscale",
+ parameters: [
+ {name: "Pitch scaling", channel: "scale", min: 0.5, max: 2, dfault: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"}
+ ]
+ },
+ exampleCsound: 'fL, fR, aL, aR, ileft, iright twst_getfinput\nkscale twst_param "scale"\nif (ileft == 1) then\n\tfoutL pvscale fL, kscale\n\taL twst_tf_fresynth foutL\nendif\nif (iright == 1) then\n\tfoutL pvscale fL, kscale\n\taR twst_tf_fresynth foutR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_fresynth",
+ ins: [
+ ["fsig", "Input PVS stream"]
+ ],
+ outs: [
+ ["aout", "Resynthesised audio"]
+ ],
+ description: "Resynthesise the PVS stream provided using the values of parameter preset group {presetgroup(pvsynth)}",
+ exampleJson: {
+ name: "Repitcher",
+ instr: "twst_tf_example_pvscale",
+ parameters: [
+ {name: "Pitch scaling", channel: "scale", min: 0.5, max: 2, dfault: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'fL, fR, aL, aR, ileft, iright twst_getfinput\nkscale twst_param "scale"\nif (ileft == 1) then\n\tfoutL pvscale fL, kscale\n\taL twst_tf_fresynth foutL\nendif\nif (iright == 1) then\n\tfoutL pvscale fL, kscale\n\taR twst_tf_fresynth foutR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_pitchscale",
+ outs: [
+ ["kpitchscale", "Pitch scaling ratio (1 = normal; 2 = one octave above)"]
+ ],
+ description: "Obtain the pitch scaling value from the parameter preset group {presetgroup(pitchscale)}",
+ exampleJson: {
+ name: "Repitcher",
+ instr: "twst_tf_example_pvscale",
+ parameters: [
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "pitchscale"}
+ ]
+ },
+ exampleCsound: 'fL, fR, aL, aR, ileft, iright twst_getfinput\nkscale twst_tf_pitchscale\nif (ileft == 1) then\n\tfoutL pvscale fL, kscale\n\taL twst_tf_fresynth foutL\nendif\nif (iright == 1) then\n\tfoutL pvscale fL, kscale\n\taR twst_tf_fresynth foutR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_pitchscale_custom",
+ ins: [
+ ["SchanPrepend", "String to prepend the preset channel name with"]
+ ],
+ outs: [
+ ["kpitchscale", "Pitch scaling ratio (1 = normal; 2 = one octave above)"]
+ ],
+ description: "Obtain the pitch scaling value from the parameter preset group {presetgroup(pitchscale)} but with channel names prepended with the specified string, to be used with the {json(channelprepend)} attribute",
+ exampleJson: {
+ name: "Repitcher",
+ instr: "twst_tf_example_pvscale",
+ parameters: [
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {presetgroup: "pitchscale", channelprepend: "custom"}
+ ]
+ },
+ exampleCsound: 'fL, fR, aL, aR, ileft, iright twst_getfinput\nkscale twst_tf_pitchscale \"custom\"\nif (ileft == 1) then\n\tfoutL pvscale fL, kscale\n\taL twst_tf_fresynth foutL\nendif\nif (iright == 1) then\n\tfoutL pvscale fL, kscale\n\taR twst_tf_fresynth foutR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_freq",
+ outs: [
+ ["kfreq", "Frequency in Hz"]
+ ],
+ description: "Obtain the frequency value at k-rate from the parameter preset group {presetgroup(notefreq)}",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {presetgroup: "notefreq"}
+ ]
+ },
+ exampleCsound: 'kfreq twst_tf_freq\naout oscil 1, kfreq\nouts aout, aout'
+ },
+ {
+ name: "twst_tf_freqi",
+ outs: [
+ ["ifreq", "Frequency in Hz"]
+ ],
+ description: "Obtain the frequency value at init time from the parameter preset group {presetgroup(notefreq)}, which should also have the {json(automatable)} attribute set to false",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {presetgroup: "notefreq", automatable: false},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'ifreq twst_tf_freqi\naout oscil 1, ifreq\nouts aout, aout'
+ },
+ {
+ name: "twst_tf_freq_custom",
+ ins: [
+ ["SchanPrepend", "String to prepend the preset channel name with"]
+ ],
+ outs: [
+ ["kfreq", "Frequency in Hz"]
+ ],
+ description: "Obtain the frequency value at k-rate from the parameter preset group {presetgroup(notefreq)} but with channel names prepended with the specified string, to be used with the {json(channelprepend)} attribute",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {presetgroup: "notefreq", channelprepend: "custom"}
+ ]
+ },
+ exampleCsound: 'kfreq twst_tf_freq_custom "custom"\naout oscil 1, kfreq\nouts aout, aout'
+ },
+ {
+ name: "twst_tf_freqi_custom",
+ ins: [
+ ["SchanPrepend", "String to prepend the preset channel name with"]
+ ],
+ outs: [
+ ["ifreq", "Frequency in Hz"]
+ ],
+ description: "Obtain the frequency value at init time from the parameter preset group {presetgroup(notefreq)} but with channel names prepended with the specified string, to be used with the {json(channelprepend)} attribute",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {presetgroup: "notefreq", channelprepend: "custom", automatable: false}
+ ]
+ },
+ exampleCsound: 'ifreq twst_tf_freqi_custom "custom"\naout oscil 1, ifreq\nouts aout, aout'
+ },
+ {
+ name: "twst_tf_getwaveform",
+ ins: [
+ ["inumber", "Reference number of the wave", "{preset(wave)}"]
+ ],
+ outs: [
+ ["ifn", "f-table number"]
+ ],
+ description: "Obtain an f-table at init time from the parameter preset {preset(wave)}. This can be overridden with {p(inumber)}, a value which corresponds to the array of available waveforms which is [Sine, Saw, Pulse, Triangle]",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {preset: "wave", automatable: false}
+ ]
+ },
+ exampleCsound: 'ifn twst_tf_getwaveform\naout oscil 1, 440, ifn\outs aout, aout'
+ },
+ {
+ name: "twst_tf_getwaveformk",
+ ins: [
+ ["inumber", "Reference number of the wave", "{preset(wave)}"]
+ ],
+ outs: [
+ ["kfn", "f-table number"]
+ ],
+ description: "Obtain an f-table at k-rate from the parameter preset group {preset(wave)}. This can be overridden with inumber, a value which corresponds to the array of available waveforms which is [Sine, Saw, Pulse, Triangle]",
+ exampleJson: {
+ name: "Oscillator",
+ instr: "twst_tf_example_osc",
+ parameters: [
+ {preset: "wave"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'kfn twst_tf_getwaveformk\naout oscilikt 1, 440, kfn\outs aout, aout'
+ },
+ {
+ name: "twst_tf_getwintype",
+ outs: [
+ ["ifn", "f-table number"]
+ ],
+ description: "Obtain an f-table at init time from the parameter preset group {preset(wintype)}. This may be Hanning, Hamming or Half sine as selected in the UI",
+ exampleJson: {
+ name: "Sndwarp",
+ instr: "twst_tfi_exsndwarp",
+ parameters: [
+ {name: "Time scale", channel: "timescale", min: 0.1, max: 10, dfault: 1, automatable: false},
+ {preset: "wintype", automatable: false}
+ ]
+ },
+ exampleCsound: 'ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate\nitimescale = twst_parami("timescale")\nifnWindow = twst_tf_getwintype()\np3 = ilength * itimescale\natime linseg 0, p3, ilength\nifnL, ifnR twst_tfi_getfn\nif (ileft == 1) then\n\taL sndwarp 1, atime, 1, ifnL, 0, 4410, 441, 4, ifnWindow, 1\nendif\nif (iright == 1) then\n\taR sndwarp 1, atime, apitchscale, ifnR, 0, 4410, 441, 4, ifnWindow, 1\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_getwintypek",
+ outs: [
+ ["kfn", "f-table number"]
+ ],
+ description: "Obtain an f-table at k-rate from the parameter preset group {preset(wintype)}. This may be Hanning, Hamming or Half sine as selected in the UI",
+ exampleJson: {
+ name: "Wintype",
+ instr: "twst_tf_wintype",
+ parameters: [
+ {preset: "wintype"}
+ ]
+ },
+ exampleCsound: 'kfnWindow = twst_tf_getwintypek()\naout oscil 1, 440\naenv oscilikt 1, 10, kfnWindow\naout *= aenv\nouts aout, aout'
+ },
+ {
+ name: "twst_getcrossinput",
+ outs: [
+ ["aL", "Left channel from instance"],
+ ["aR", "Right channel from instance"],
+ ["ileft", "whether the left channel is selected"],
+ ["iright", "whether the right channel is selected"]
+ ],
+ description: "Obtain an audio stream from the file instance selected in a parameter preset {preset(instance)}. ileft and iright correspond to the selected channels, and the audio is played according to the parameter preset {preset(looptype)}",
+ exampleJson: {
+ name: "Multiplier",
+ instr: "twst_tf_multiplier",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\naxL, axR, ixleft, ixright twst_getcrossinput\nif (ileft == 1 && ixleft == 1) then\n\taL *= axL\nendif\nif (iright == 1 && ixright == 1) then\n\taR *= axR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_getfcrossinput",
+ outs: [
+ ["fL", "Left channel from instance"],
+ ["fR", "Right channel from instance"],
+ ["ileft", "whether the left channel is selected"],
+ ["iright", "whether the right channel is selected"]
+ ],
+ description: "Obtain a PVS stream from the file instance selected in a parameter preset {preset(instance)}. ileft and iright correspond to the selected channels, and the audio is played according to the parameter preset {preset(looptype)}. The FFT size is taken from {preset(fftsize)}",
+ exampleJson: {
+ name: "Morpher",
+ instr: "twst_tf_exmorph",
+ inputs: 2,
+ parameters: [
+ {preset: "instance", name: "Cross instance"},
+ {preset: "instanceloop"},
+ {name: "Amplitude amount", channel: "amp", description: "Amplitude interpolation", dfault: 1, min: 0, max: 1},
+ {name: "Frequency amount", channel: "freq", description: "Frequency interpolation", dfault: 1, min: 0, max: 1},
+ {presetgroup: "pvanal"},
+ {presetgroup: "pvsynth"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'fL, fR, aL, aR, ileft, iright twst_getfinput\nfLo, fRo, ilefto, irighto twst_getfcrossinput\nkamp = twst_param:k("amp")\nkfreq = twst_param:k("freq")\n\nif (ileft == 1 && ilefto == 1) then\n\tfoutL pvsmorph fL, fLo, kamp, kfreq\n\taL twst_tf_fresynth foutL\nendif\n\nif (iright == 1 && irighto == 1) then\n\tfoutR pvsmorph fR, fRo, kamp, kfreq\n\taR twst_tf_fresynth foutR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_getcrossdata",
+ outs: [
+ ["ifnL", "f-table containing left channel audio"],
+ ["ifnR", "f-table containing right channel audio"],
+ ["istart", "selection start in samples"],
+ ["ilen", "selection length in samples"],
+ ["ileft", "whether the left channel is selected"],
+ ["iright", "whether the right channel is selected"]
+ ],
+ description: "Obtain data from the file instance selected in a parameter preset {preset(instance)}. The f-tables are the complete file, and the start and length correspond to the selected area. ileft and iright also correspond to the selected channels",
+ exampleJson: {
+ name: "Multiplier",
+ instr: "twst_tf_multiplier",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {preset: "instanceloop"}
+ ]
+ },
+ exampleCsound: 'ixfnL, ixfnR, ixstart, ixlen, ixleft, ixright twst_getcrossdata\nprint ixlen\naL, aR, ileft, iright twst_getinput\naxL, axR, ixleft, ixright twst_getcrossinput\nif (ileft == 1 && ixleft == 1) then\n\taL *= axL\nendif\nif (iright == 1 && ixright == 1) then\n\taR *= axR\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tfi_getcrossfn",
+ outs: [
+ ["ifnL", "f-table containing left channel audio"],
+ ["ifnR", "f-table containing right channel audio"],
+ ],
+ description: "Obtain an f-table from the file instance selected in a parameter preset {preset(instance)}, which has been sliced from the original file, based on the selection area. This may be necessary for some opcodes that read from a f-table, such as those that have no control over the read point, when used for convolution or cross synthesis",
+ exampleJson: {
+ name: "Convolve",
+ instr: "twst_tfi_exdconv",
+ inputs: 2,
+ parameters: [
+ {preset: "instance"},
+ {name: "Size ratio", min: 0.00001, max: 1, dfault: 0.1, lagHint: -1, channel: "sizeratio", automatable: false},
+ {presetgroup: "applymode"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput \nifnLo, ifnRo twst_tfi_getcrossfn\nisizeratio = twst_parami("sizeratio")\nif (ileft == 1) then\n\taL dconv aL, isizeratio * ftlen(ifnLo), ifnLo\nendif\nif (iright == 1) then\n\taR dconv aR, isizeratio * ftlen(ifnRo), ifnRo\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tfi_getfn",
+ outs: [
+ ["ifnL", "f-table containing left channel audio"],
+ ["ifnR", "f-table containing right channel audio"],
+ ],
+ description: "Obtain f-tables which have been sliced from the original file, based on the selection area. This may be necessary for some opcodes that read from a f-table, such as those that have no control over the read point",
+ exampleJson: {
+ name: "Sndwarp",
+ instr: "twst_tfi_exsndwarp",
+ parameters: [
+ {name: "Time scale", channel: "timescale", min: 0.1, max: 10, dfault: 1, automatable: false},
+ {preset: "wintype", automatable: false}
+ ]
+ },
+ exampleCsound: 'ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate\nitimescale = twst_parami("timescale")\nifnWindow = twst_tf_getwintype()\np3 = ilength * itimescale\natime linseg 0, p3, ilength\nifnL, ifnR twst_tfi_getfn\nif (ileft == 1) then\n\taL sndwarp 1, atime, 1, ifnL, 0, 4410, 441, 4, ifnWindow, 1\nendif\nif (iright == 1) then\n\taR sndwarp 1, atime, apitchscale, ifnR, 0, 4410, 441, 4, ifnWindow, 1\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_setlatencysamples",
+ ins: [
+ ["isamples", "Number of samples latency"]
+ ],
+ description: "Set the expected processing latency in samples. This is then used to offset any writing and output accordingly. This should ideally be used for any buffered or windowed operations. However, {csound(twst_getfinput)} already sets this based on the FFT size",
+ exampleJson: {
+ name: "Hilbert pitch scale",
+ instr: "twst_tf_exhilbertpitchscale",
+ parameters: [
+ {presetgroup: "pitchscale"},
+ {preset: "fftsize"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\nifftsize = twst_parami("fftsize")\nkscale = twst_tf_pitchscale()\ntwst_setlatencysamples(ifftsize)\n\nif (ileft == 1) then\n\tahL1, ahL2 hilbert2 aL, ifftsize, ifftsize / 4\n\tamL, afmL fmanal ahL1, ahL2\n\taLx oscil amL, afmL * kscale\nendif\nif (iright == 1) then\n\tahR1, ahR2 hilbert2 aR, ifftsize, ifftsize / 4\n\tamR, afmR fmanal ahR1, ahR2\n\taRx oscil amR, afmR * kscale\nendif\nouts aLx, aRx'
+ },
+ {
+ name: "twst_setlatencyseconds",
+ ins: [
+ ["iseconds", "Number of seconds latency"]
+ ],
+ description: "Set the expected processing latency in seconds. This is then used to offset any writing and output accordingly. This should ideally be used for any buffered or windowed operations. However, {csound(twst_getfinput)} already sets this based on the FFT size",
+ exampleJson: {
+ name: "Hilbert pitch scale",
+ instr: "twst_tf_exhilbertpitchscale",
+ parameters: [
+ {presetgroup: "pitchscale"},
+ {preset: "fftsize"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\nifftsize = twst_parami("fftsize")\nkscale = twst_tf_pitchscale()\ntwst_setlatencyseconds(1 / ifftsize)\n\nif (ileft == 1) then\n\tahL1, ahL2 hilbert2 aL, ifftsize, ifftsize / 4\n\tamL, afmL fmanal ahL1, ahL2\n\taLx oscil amL, afmL * kscale\nendif\nif (iright == 1) then\n\tahR1, ahR2 hilbert2 aR, ifftsize, ifftsize / 4\n\tamR, afmR fmanal ahR1, ahR2\n\taRx oscil amR, afmR * kscale\nendif\nouts aLx, aRx'
+ },
+ {
+ name: "twst_getlatencyseconds",
+ outs: [
+ ["iseconds", "Number of seconds latency"]
+ ],
+ description: "Obtain the expected processing latency in seconds, as previously set by {csound(twst_setlatencysamples)}, {csound(twst_setlatencyseconds)} or {csound(twst_getfinput)}",
+ exampleJson: {
+ name: "Hilbert pitch scale",
+ instr: "twst_tf_exhilbertpitchscale",
+ parameters: [
+ {presetgroup: "pitchscale"},
+ {preset: "fftsize"},
+ {preset: "applymode"}
+ ]
+ },
+ exampleCsound: 'aL, aR, ileft, iright twst_getinput\nifftsize = twst_parami("fftsize")\nkscale = twst_tf_pitchscale()\ntwst_setlatencysamples(ifftsize)\nprint twst_getlatencyseconds()\nif (ileft == 1) then\n\tahL1, ahL2 hilbert2 aL, ifftsize, ifftsize / 4\n\tamL, afmL fmanal ahL1, ahL2\n\taLx oscil amL, afmL * kscale\nendif\nif (iright == 1) then\n\tahR1, ahR2 hilbert2 aR, ifftsize, ifftsize / 4\n\tamR, afmR fmanal ahR1, ahR2\n\taRx oscil amR, afmR * kscale\nendif\nouts aLx, aRx'
+ },
+ {
+ name: "twst_tf_setplayposition",
+ ins: [
+ ["kposition", "Playback position ratio"]
+ ],
+ description: "Override the displayed playback position. The supplied kposition must be between 0 and 1, and corresponds to the selected area being played or auditioned. Normal operation would be equivalent to line(0, p3, 1)",
+ exampleJson: {
+ name: "Direct time sndwarp",
+ instr: "twst_tfi_directsndwarp",
+ parameters: [
+ {name: "Read time", channel: "readtime"},
+ {preset: "wintype", automatable: false}
+ ]
+ },
+ exampleCsound: 'ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate\nktime = twst_param:k("readtime")\ntwst_tf_setplayposition ktime\natime = a(ktime * ilength)\nifnWindow = twst_tf_getwintype()\nifnL, ifnR twst_tfi_getfn\nif (ileft == 1) then\n\taL sndwarp 1, atime, 1, ifnL, 0, 4410, 441, 4, ifnWindow, 1\nendif\nif (iright == 1) then\n\taR sndwarp 1, atime, apitchscale, ifnR, 0, 4410, 441, 4, ifnWindow, 1\nendif\nouts aL, aR'
+ },
+ {
+ name: "twst_tf_getstate",
+ outs: [
+ ["ileft", "Whether the left channel is selected"],
+ ["iright", "Whether the right channel is selected"],
+ ["istart", "Start sample number of selection"],
+ ["iend", "End sample number of selection"],
+ ["ilens", "Length of selection in seconds"]
+ ],
+ description: "Obtain details about the current selection. If the source is mono, only ileft will be equal to 1",
+ exampleJson: {
+ name: "Direct time sndwarp",
+ instr: "twst_tfi_directsndwarp",
+ parameters: [
+ {name: "Read time", channel: "readtime"},
+ {preset: "wintype", automatable: false}
+ ]
+ },
+ exampleCsound: 'ileft, iright, istartsamp, iendsamp, idocut, ilength twst_tf_getstate\nktime = twst_param:k("readtime")\ntwst_tf_setplayposition ktime\natime = a(ktime * ilength)\nifnWindow = twst_tf_getwintype()\nifnL, ifnR twst_tfi_getfn\nif (ileft == 1) then\n\taL sndwarp 1, atime, 1, ifnL, 0, 4410, 441, 4, ifnWindow, 1\nendif\nif (iright == 1) then\n\taR sndwarp 1, atime, apitchscale, ifnR, 0, 4410, 441, 4, ifnWindow, 1\nendif\nouts aL, aR'
+ }
+ ];
+
+ function linkage(text) {
+ var re = /{(preset|presetgroup|json|csound)\((.*?)\)}/g;
+ do {
+ match = re.exec(text);
+ if (match) {
+ text = text.replaceAll(match[0], "<a href=\"#" + match[1] + "_" + match[2] + "\">" + match[2] + "</a>");
+ }
+ } while (match);
+ return text;
+ }
+
+ function buildOpcodes() {
+ var elTarget = $("#opcodes");
+ for (let index in documentation.opcodes) {
+ let o = documentation.opcodes[index];
+ var html = ""
+ if (o.outs) {
+ var names = [];
+ for (var x of o.outs) names.push(x[0]);
+ html += "<i>" + names.join(", ") + "</i> "
+ }
+ html += "<b>" + o.name + "</b>";
+ if (o.ins) {
+ var names = [];
+ for (var x of o.ins) {
+ if (x[2]) { // has default
+ names.push("[" + x[0] + "=" + x[2] + "]");
+ } else {
+ names.push(x[0]);
+ }
+ }
+ html += " <i>" + names.join(", ") + "</i>"
+ }
+
+ $("<p />").html(linkage(html)).attr("id", "csound_" + o.name).appendTo(elTarget);
+ if (o.ins || o.outs) {
+ var ul = $("<ul />").appendTo(elTarget);
+ if (o.outs) {
+ for (var x of o.outs) {
+ var html = "<i>" + x[0] + "</i> " + x[1];
+ $("<li />").html(linkage(html)).appendTo(ul);
+ }
+ }
+ if (o.ins) {
+ for (var x of o.ins) {
+ var html = "<i>" + x[0] + "</i> " + x[1];
+ if (x[2]) html += " <i>[default: " + x[2] + "</i>]"
+ $("<li />").html(linkage(html)).appendTo(ul);
+ }
+ }
+ }
+ elTarget.append($("<p />").html(linkage(o.description)));
+
+ if (o.exampleCsound && o.exampleJson) {
+ var cs = "instr " + o.exampleJson.instr + "\n\t$TWST_TRANSFORM\n"
+ cs += o.exampleCsound.replace(/^/gm, "\t");
+ cs += "\nendin"
+ var exampleCsound = $("<pre />").hide().text(cs).attr("id", "csex_" + index);
+ let exampleCsoundShown = false;
+ $("<a />").attr("href", "#").text("Csound example").click(function(e) {
+ e.preventDefault();
+ if (!exampleCsoundShown) {
+ $("#csex_" + index).show();
+ exampleCsoundShown = true;
+ } else {
+ $("#csex_" + index).hide();
+ exampleCsoundShown = false;
+ }
+ }).appendTo($("<p />").appendTo(elTarget));
+ exampleCsound.appendTo(elTarget);
+ var exampleJson = $("<pre />").hide().text(JSON.stringify(o.exampleJson, null, "\t")).attr("id", "jsex_" + index);
+ let exampleJsonShown = false;
+ $("<a />").attr("href", "#").text("Corresponding definition example").click(function(e) {
+ e.preventDefault();
+ if (!exampleJsonShown) {
+ $("#jsex_" + index).show();
+ exampleJsonShown = true;
+ } else {
+ $("#jsex_" + index).hide();
+ exampleJsonShown = false;
+ }
+ }).appendTo($("<p />").appendTo(elTarget));
+ exampleJson.appendTo(elTarget);
+ }
+
+ elTarget.append($("<hr />"));
+ }
+ }
+
+
+ $(function() {
+ buildOpcodes();
+ });
+ </script>
+
+</head>
+<body>
+ <h1>Extending twist</h1>
+ <div id="container_overview">
+ <h2>Overview</h2>
+ Twist can quite easily be extended to feature additional transforms. These can be tested and used on the fly with the <i>developer console</i> within twist, and are encouraged to be submitted for inclusion in the live application which can be done <a href="https://csound.1bpm.net/contact/?type=twist_submit">here</a>, via the <i>Help > Submit transform code</i> menu option, or via the link in the <i>developer console</i><br /><br />
+ In order to write new transforms for twist, familiarity with JSON and Csound is required. The UI components including parameters available to the end user are defined with JSON (detailed in the <a href="#json">transform definition</a> section, and the actual audio processing is defined with Csound code (detailed in the <a href="#csound">audio processing with Csound</a> section. Additional twist opcodes are provided to the developer in order to ease integration.<br />
+ Each transform requires a transform definition as a JSON object, and at least one Csound instrument. While each section describes the API to be used, full examples are provided in the <a href="#opcodes">Csound opcode</a> subsection.
+
+
+ </div><div id="container_json">
+ <h2 id="json">Transform definition with JSON</h2>
+ The transform definition is a JSON object, which should at the very least have the keys <a href="#json_name">name</a> and <a href="#json_instr">instr</a> defined. The possible keys for the top-level transform definition are as follows, and if a default value is applicable it is shown to the right of the equals sign in the name column:
+
+ <table><tbody>
+ <tr><td><h5 id="json_name">name</h5></td><td>Name as seen in the twist user interface</td></tr>
+ <tr><td><h5 id="json_instr">instr</h5></td><td>Csound named instrument, which is to be called to carry out the processing</td></tr>
+ <tr><td><h5>inputs = 1</h5></td><td>Number of input files the transform requires. This defaults to 1 but may be set to 2 for cross-processing transforms and such</td></tr>
+ <tr><td><h5>description = ""</h5></td><td>Description of the transform</td></tr>
+ <tr><td><h5>author = ""</h5></td><td>Author name and other relevant details</td></tr>
+ <tr><td><h5>parameters = []</h5></td><td><a href="#parameter">Parameter definitions</a> in an array</td></tr>
+ <tr><td><h5>twine = false</h5></td><td>Whether the transform will be available as a twine insert. Only <a href="#csound_rule_tfi">transforms using live input</a> can be used for this purpose</td></tr>
+ <tr><td><h5>unstable = false</h5></td><td>Should be set to true if the transform is expected to be unstable and may cause crashes. This will result in a warning displayed when the transform is loaded</td></tr>
+ </tbody></table>
+
+
+ <h4 id="parameter">Parameter definition</h4>
+ The parameter definition is a JSON object, which may have any of the following keys. If min == 0, max == 1 and step == 1, the parameter appears as a checkbox which provides the value 1 when checked and 0 when unchecked. If <a href="#parameter_options">options</a> is supplied, then the parameter appears as a drop-down select box. In other cases the parameter is displayed as a range slider with an adjacent number input box.<br /><br />
+ The only required key for a parameter definition is <a href="#parameter_name">name</a>. In this case, a parameter would be with a range of 0 to 1, with the default step amount and sending on the channel with the lowercase equivalent of the name.<br /><br />
+ The possible keys for a parameter definition are as follows, and if a default value is applicable it is shown to the right of the equals sign in the name column:
+
+ <table><tbody>
+ <tr><td><h5 id="parameter_name">name</h5></td><td>Name of the parameter to be shown in the interface</td></tr>
+ <tr><td><h5>description = ""</h5></td><td>Description of the parameter</td></tr>
+ <tr><td><h5 id="parameter_channel">channel = name.toLowerCase()</h5></td><td>Channel name which should correspond to that which is requested by <a href="#csound_twst_param">twst_param</a> in the <a href="#json_instr">transform instrument</a>. Defaults to the lowercase parameter name</td></tr>
+ <tr><td><h5>min = 0</h5></td><td>Numeric minimum accepted value</td></tr>
+ <tr><td><h5>max = 1</h5></td><td>Numeric maximum accepted value</td></tr>
+ <tr><td><h5>step = 0.0000001</h5></td><td>Incremental allowance of the value, should numeric</td></tr>
+ <tr><td><h5 id="parameter_dfault">dfault = 1</h5></td><td>Numeric default value</td></tr>
+ <tr><td><h5 id="parameter_options">options = null</h5></td><td>Array containing options to be displayed in a drop-down select box. If supplied, the minimum, maximum and step values are redundant. <a href="#parameter_dfault">dfault</a> corresponds to the index of the array to be the default value. If <a href="#parameter_asvalue">asvalue</a> is set, then the value supplied to Csound will be the value provided in the options array; otherwise it will be the index of the value</td></tr>
+ <tr><td><h5 id="parameter_asvalue">asvalue = false</h5></td><td>Whether the selected item from <a href="#parameter_options">options</a> should be provided to Csound as the actual value rather than the array index</td></tr>
+ <tr><td><h5>hidden = false</h5></td><td>Whether the parameter should be hidden. May be useful passing static data from the interface to Csound</td></tr>
+ <tr><td><h5>conditions = null</h5></td><td>An array of <a href="#condition">Condition</a> objects which are all to be met for the parameter to be shown</td></tr>
+ <tr><td><h5>hostrange = false</h5></td><td>For child parameters (namely those in modulations), whether the min, max, step, dfault, options and asvalue attributes should be inherited from the parent</td></tr>
+ <tr><td><h5 id="parameter_preset">preset = null</h5></td><td>The name of a <a href="#preset">preset</a> to be used. Any definition attributes provided by the preset may be overriden</td></tr>
+ <tr><td><h5 id="parameter_presetgroup">presetgroup = null</h5></td><td>The name of a <a href="#presetgroup">presetgroup</a> to be used, which will provide a number of parameters in place of the current definition
+ <tr><td><h5>nameprepend = null</h5></td><td>The string which will be prepended to parameter names, if presetgroup is specified
+ <tr><td><h5>channelprepend = null</h5></td><td>The string which will be prepended to parameter channels, if presetgroup is specified
+ </tbody></table>
+
+ <hr />
+ <h4 id="condition">Condition</h4>
+ The condition definition is a JSON object, which should include all of the following keys:
+ <table><tbody>
+ <tr><td><h5>channel</h5></td><td>Parameter <a href="#parameter_channel">channel</a> to evaluate</td></tr>
+ <tr><td><h5>operator</h5></td><td>Operator type, which may be eq (equal), neq (not equal), lt (less than), gt (greater than), le (less than or equal to) or ge (greater than or equal to)</td></tr>
+ <tr><td><h5>value</h5></td><td>Static value to check against the above</td></tr>
+ </tbody></table>
+
+ <hr />
+ <h4 id="preset">Presets</h4>
+ These are available as values to specify in the <a href="#parameter_presetgroup">presetgroup</a> parameter attribute and alter set the parameter up as follows
+ <table><tbody>
+ <tr><td><h5>amp</h5></td><td>Amplitude slider with min: 0 and max: 1, channel: "amp"</td></tr>
+ <tr><td><h5 id="preset_fftsize">fftsize</h5></td><td>FFT size drop down which may be transparently utilised by <a href="#csound_twst_getfinput">twst_getfinput</a> and <a href="#csound_twst_getfcrossinput">twst_getfcrossinput</a>, or accessed directly via the channel "fftsize" or the specified channel name with <a href="#csound_twst_param">twst_param</a></td></tr>
+ <tr><td><h5 id="preset_wave">wave</h5></td><td>f-table selector which may be transparently utilised by <a href="#csound_twst_tf_getwaveform">twst_tf_getwaveform</a>, <a href="#csound_twst_tf_getwaveformk">twst_tf_getwaveformk</a>, or accessed directly via the channel "wave" or the specified channel name with <a href="#csound_twst_param">twst_param</a> or <a href="#csound_twst_paramk">twst_paramk</a></td></tr>
+ <tr><td><h5>applymode</h5></td><td>Apply mode drop down, which may be Replace, Mix, Modulate or Demodulate. Used internally by twist at the rendering stage</td></tr>
+ <tr><td><h5>note</h5></td><td>MIDI note number drop-down, displaying note names between MIDI note number 21 (A0) and 127 (G#9) and returning the MIDI note number to the channel</td></tr>
+ <tr><td><h5 id="preset_wintype">wintype</h5></td><td>Window type drop-down which may be utilised by <a href="#csound_twst_tf_getwintype">twst_tf_getwintype</a>, <a href="#csound_twst_tf_getwintypek">twst_tf_getwintypek</a> or accessed directly via the channel "wintype" or the specified channel name with <a href="#csound_twst_param">twst_param</a> or <a href="#csound_twst_paramk">twst_paramk</a></td></tr>
+ <tr><td><h5 id="preset_instance">instance</h5></td><td>Drop down selecting a file open in twist, other than that which is currently open. Utilised interally by <a href="#csound_twst_getcrossinput">twst_getcrossinput</a> and <a href="#csound_twst_getfcrossinput">twst_getfcrossinput</a></td></tr>
+ <tr><td><h5 id="preset_instanceloop">instanceloop</h5></td><td>Drop down selecting either None, Forward, Backward or Ping-pong to denote the loop type of the other selected instance, used internally for cross-processing transforms within <a href="#csound_twst_getcrossinput">twst_getcrossinput</a>, <a href="#csound_twst_getfcrossinput">twst_getfcrossinput</a> and <a href="#csound_twst_getfcrossdata">twst_getfcrossdata</a></td></tr>
+ </tbody></table>
+
+ <hr />
+ <h4 id="presetgroup">Preset groups</h4>
+ These are available as values to specify in the <a href="#parameter_presetgroup">presetgroup</a> parameter attribute.
+ <table><tbody>
+ <tr><td><h5>pvanal</h5></td><td>Provides <a href="#preset_fftsize">FFT size</a> and a frequency/phase locking checkbox, used internally in the provision of PVS stream data within <a href="#csound_twst_getfinput">twst_getfinput</a> and <a href="#csound_twst_getfcrossinput">twst_getfcrossinput</a></td></tr>
+ <tr><td><h5>pvresmode</h5></td><td>Provides parameters which control the resynthesis approach as used by <a href="#csound_twst_tf_fresynth">twst_tf_fresynth</a>. A drop down permits selection between overlap-add and additive approaches, with the latter showing several further parameters when selected</td></tr>
+ <tr><td><h5 id="presetgroup_pitchscale">pitchscale</h5></td><td>Provides a scaling mode drop down with semitones or ratio as options. The selected scaling is presented via <a href="#csound_twst_tf_pitchscale">twst_tf_pitchscale</a> as a ratio</td></tr>
+ <tr><td><h5 id="presetgroup_notefreq">notefreq</h5></td><td>Shows an option of selecting a note name from a drop down, or specifying the frequency in Hz. The computed frequency is provided to Csound via <a href="#csound_twst_tf_freq">twst_tf_freq</a> and <a href="#csound_twst_tf_freqi">twst_tf_freqi</a></td></tr>
+ </tbody></table>
+
+
+ </div><div id="container_csound">
+
+ <h2 id="csound">Audio processing with Csound</h2>
+ Audio processing is carried out for the corresponding JSON transform definition by invoking the Csound instrument specified in the <a href="#json_instr">instr</a> key. Multiple Csound instruments and opcodes may be utilised, however it should be noted that the Csound instrument is called using <i>subinstr</i>, and offline/commit processing is carried out using audio rate processing within a k-rate loop. The only known limitation this imposes is that additional/auxilliary instruments may not usually be called from the initial instrument in a way that would affect synchronisation of the offline processing aspect - ie, opcodes such as <i>schedule</i> and <i>event</i> should not be used except in careful circumstances where the synchronisation is respected - for example where the scheduled instrument only complete init time processing, or completes in a single k-cycle. However, auxilliary instruments may be called using <i>subinstr</i>.<br /><br />
+ Instruments can generate audio, utilise direct feed of audio, or access table data directly. The latter is useful if the output should be a different duration to the input. <br />
+ A number of opcodes to ease integration with the UI and transform definition are provided by twist, detailed below with examples in the <a href="#opcodes">Opcode reference</a> subsection.
+ <h3>Rules and style guide</h3>
+ The rules and style guide should be adhered to where appropriate, especially if opcodes are to be submitted for inclusion in the live application.
+ <ul>
+ <li id="csound_rule_tfi">Instruments referenced by the transform definition should be named prepended with <i>twst_tf_</i> if they generate audio or use direct input (obtained with <a href="#csound_twst_getinput">twst_getinput</a> or <a href="#csound_twst_getfinput">twst_getfinput</a>) - or prepended with <i>twst_tfi_</i> if table access is to be used (with <a href="#csound_twst_tfi_getfn">twst_tfi_getfn</a></li>
+ <li>The first line of the instrument must be <i>$TWST_TRANSFORM</i> to mark it as a twist transform</li>
+ <li>Auxilliary instruments and user-defined opcodes should be named prepended with the name of the initial instrument</li>
+ <li>Instruments may generate audio or process audio input obtained from calls to <a href="#csound_twst_getinput">twst_getinput</a>, <a href="#csound_twst_getfinput">twst_getfinput</a> or <a href="#csound_twst_tfi_getfn">twst_tfi_getfn</a></li>
+ <li>Instruments must emit stereo audio signals using the <i>outs</i> opcode. Depending on the processing action, either of the outputs may be a silent signal or the same as the input</li>
+ <li>Instruments should be prepared to process or generate left and right channels according to the <i>ileft</i> and <i>iright</i> values from the call to <a href="#csound_twst_getinput">twst_getinput</a>, <a href="#csound_twst_getfinput">twst_getfinput</a> or <a href="#csound_twst_tf_getstate">twst_tf_getstate</a>. A channel not applicable to the request must still be emitted, but may be a silent signal or the same as the input - the audition/commit process will only use the output for the channel requested by the user in the UI</li>
+ <li>Any global objects created must not persist after the instrument has finished. For example, <i>ftgentmp</i> must be used rather than <i>ftgen</i> - unless <i>ftfree</i> is used on the f-table accordingly</li>
+ <li><i>print</i> opcodes and other console output opcodes should not be used except for debugging purposes</li>
+ <li>0dbfs is set at 1, so anything reliant on this should adhere accordingly</li>
+ <li>Opcodes are limited to those available in the Csound WASM build - this is generally everything, but one noted example of an exclusion is <i>fractalnoise</i>. If otherwise unexplainable errors are encountered, this may be due to an unavailable opcode</li>
+ </ul>
+ <h3>Opcode reference</h3>
+ <div id="opcodes"></div>
+
+ </div><div id="container_examples">
+
+ <h2>Examples from the live application</h2>
+ All of the JSON transform definitions <a href="../twirl/appdata.js">can be seen here</a>, under the <i>transforms</i> key.<br />
+ Csound code in the live application is split across several files which are as follows. Each file generally corresponds to the section in the JSON.
+ <ul>
+ <li><a href="/udo/twist/transforms/amplitude.udo">amplitude</a></li>
+ <li><a href="/udo/twist/transforms/cross_processing.udo">cross_processing</a></li>
+ <li><a href="/udo/twist/transforms/delay.udo">delay</a></li>
+ <li><a href="/udo/twist/transforms/filter.udo">filter</a></li>
+ <li><a href="/udo/twist/transforms/frequency.udo">frequency</a></li>
+ <li><a href="/udo/twist/transforms/amplitude.udo">amplitude</a></li>
+ <li><a href="/udo/twist/transforms/general.udo">general</a></li>
+ <li><a href="/udo/twist/transforms/generate.udo">generate</a></li>
+ <li><a href="/udo/twist/transforms/granular.udo">granular</a></li>
+ <li><a href="/udo/twist/transforms/harmonic.udo">harmonic</a></li>
+ <li><a href="/udo/twist/transforms/reverb.udo">reverb</a></li>
+ <li><a href="/udo/twist/transforms/spectral.udo">spectral</a></li>
+ <li><a href="/udo/twist/transforms/warping.udo">warping</a></li>
+ </ul>
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twist/documentation.html b/site/app/twist/documentation.html new file mode 100644 index 0000000..694279e --- /dev/null +++ b/site/app/twist/documentation.html @@ -0,0 +1,181 @@ +<html>
+<head>
+ <script type="text/javascript" src="/code/jquery.js"></script>
+ <style type="text/css">
+ body {
+ font-family: Arial, sans-serif;
+ }
+
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 1px solid black;
+ }
+
+ pre {
+ font-family: Monospace, Courier, sans-serif;
+ background-color: #ccffff;
+ }
+
+ </style>
+
+</head>
+<body>
+ <h1>Overview</h1>
+ twist is an audio editor and transformer, inspired by Cooledit, Cecilia, Audition, Mammut, Soundshaper and CDP among others. It provides wave editing functions in addition to unique audio effects and transforms.
+
+ <h1>Concept</h1>
+ twist allows for waveform editing and applying transforms. Transforms include effects and other more involved sound processing techniques. Centrally there is a waveform editor, and to the left is a tree view list of available transforms by category. A transform can be loaded by pressing on the name in the relevant submenu, after which the parameters will be displayed at the bottom of the screen. <br /><br />
+ A transform can be <i>auditioned</i> (previewed) or <i>committed</i> (applied), which will be applicable to the selected region of the waveform, or all of it if nothing is selected.
+ <br /><br />
+ At current, twist can only load and process sounds of up to about 5 minutes in length. Some transforms require extensive computation and may not properly audition - in these cases a message will be shown and playback stopped. As a result, twist is ideal for detailed processing of short sounds which may be then utilised as samples or compositional components in a DAW or other such software.
+
+ <h1>Basic usage</h1>
+ Sounds can be loaded by dragging them into the browser, or new files may be created. When you load twist or create a new instance with the <i>+</i> button to the bottom left of the waveform view, you'll be prompted to drag a file into the browser or create a new file of a fixed duration. <br /><br />
+
+ Once you have a sound ready in twist, you can use the waveform view as you would with a typical waveform editor. Regions can be selected by click/dragging the mouse or using the handles at the top of the waveform view. Zooming can be accomplished with the relevant options under the <i>view</i> menu, or with the shortcut buttons. Typical cut/copy/paste and undo operations are also provided under the <i>edit</i> menu and with keyboard shortcuts. <br /><br />
+
+ Icons may be hovered over to see a tooltip detailing what pressing it will do, while keyboard shortcuts for items are shown on the drop-down menu. <br /><br />
+
+ <table><tbody>
+ <tr>
+ <td><img src="../twirl/icon/showAll.svg"></td>
+ <td>Show all</td>
+ <td>Reset the zoom level so all of the waveform can be seen</td>
+ </tr>
+
+ <tr>
+ <td><img src="../twirl/icon/rewind.svg"></td>
+ <td>Rewind</td>
+ <td>Rewind the playback point and clear the current waveform selection</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/play.svg"></td>
+ <td>Play</td>
+ <td>Play the selected region of the waveform</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/audition.svg"></td>
+ <td>Audition</td>
+ <td>Preview the currently-loaded transform on the selected region of the waveform</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/commit.svg"></td>
+ <td>Commit</td>
+ <td>Apply the currently-loaded transform to the selected region of the waveform</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/record.svg"></td>
+ <td>Record</td>
+ <td>Record live input to the selected region of the waveform</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/cut.svg"></td>
+ <td>Cut</td>
+ <td>Cut the selected region of the waveform to the clipboard</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/copy.svg"></td>
+ <td>Copy</td>
+ <td>Copy the selected region of the waveform to the clipboard</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/paste.svg"></td>
+ <td>Paste</td>
+ <td>Paste the clipboard contents to the playback point or start of the selected waveform region</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/pasteSpecial.svg"></td>
+ <td>Paste special</td>
+ <td>Open a dialog to allow pasting the clipboard contents with extended options such as repeat number and mixing</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/zoomSelection.svg"></td>
+ <td>Zoom selection</td>
+ <td>Zoom the view to the selected region of the waveform</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/zoomIn.svg"></td>
+ <td>Zoom in</td>
+ <td>Zoom in the waveform view</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/zoomOut.svg"></td>
+ <td>Zoom out</td>
+ <td>Zoom out the waveform view</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/showAll.svg"></td>
+ <td>Show all</td>
+ <td>Zoom out to show all of the waveform</td>
+ </tr>
+
+ </tbody></table>
+
+ <h1>Applying transforms</h1>
+ When a transform has been loaded, the parameters at the bottom of the screen can be modified and are applicable to auditioning and committing. Certain parameters may be altered while auditioning, and can also be automated or modulated, while other parameters are only applicable at initialisation of the auditioning process and thus cannot be modified during. <br /><br />
+ A crossfade between the original and transformed audio can be specified with the crossfade in/out sliders underneath the waveform. The applicable crossfade will be shown on the waveform view relative to the region which is to be transformed. <br /><br />
+ At the side of each parameter, there are up to four icons, which are as follows:
+ <table><tbody>
+ <tr>
+ <td><img src="../twirl/icon/reset.svg"></td>
+ <td>Reset</td>
+ <td>Reset the parameter to the default value</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/randomise.svg"></td>
+ <td>Include in randomisation</td>
+ <td>Include the parameter in transform randomisation. Unselected parameters will display the icon in a lighter colour</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/automate.svg"></td>
+ <td>Automate</td>
+ <td>Display spline automation for the parameter to allow a time-varying value to be entered</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/modulate.svg"></td>
+ <td>Modulate</td>
+ <td>Display modulation options for the parameter to allow for a parametric time-varying value</td>
+ </tr>
+ </tbody></table><br />
+
+ Additionally to the top-right there are two icons globally applicable to all parameters:
+ <table><tbody>
+ <tr>
+ <td><img src="../twirl/icon/randomise.svg"></td>
+ <td>Randomise</td>
+ <td>Randomise all parameters that are included in randomisation according to the icon detailed above. Randomisation may also affect modulations, which will consequently display the modulation details for the given parameter</td>
+ </tr>
+ <tr>
+ <td><img src="../twirl/icon/reset.svg"></td>
+ <td>Reset</td>
+ <td>Reset all parameters to the default value, removing modulations and automation</td>
+ </tr>
+ </tbody></table>
+
+ <h2>Modulation</h2>
+ When a parameter has modulation enabled, the normal parameter input will not be shown, and instead an area will appear with modulation settings. This can be closed and the normal parameter input returned to with the following icon aside the parameter row: <br />
+ <img src="../twirl/icon/close.svg">
+ <br /><br />
+ When there is more than one waveform open in twist, cross-adaptive modulations are available in the <i>modulation type</i> drop-down box. Cross-adaptive modulations use analysis of another waveform to inform the value of the parameter. For each cross-adaptive modulation, there is an <i>instance</i> drop-down box to select the other waveform to use as an analysis source (from which the selected region will be used), and <i>cross instance loop type</i> to specify the loop type should the length of the region in the analysis waveform be shorter than that of the current waveform.
+
+ <h2>Automation</h2>
+ When a parameter has automation enabled, the normal parameter input will not be shown, and an overlay atop the waveform with a spline editor will be displayed. As a result, the selection cannot be altered by dragging across the waveform unless the automation is hidden. However, the selection shortcuts and menu options can be used, in addition to the selection handles at the top of the waveform view. Multiple automated parameters can be displayed at once, although only one can be edited. In the case that multiple parameters are automated, the following button aside the parameter row can be used to select it: <br />
+ <img src="../twirl/icon/show.svg"><br />
+ Anywhere within the spline editor can be pressed to add a new point. Existing points can be hovered over to see the parameter name, time and value. <br /><br />
+ At the side of the parameter row, this icon can be pressed to disable the automation:<br />
+ <img src="../twirl/icon/close.svg"><br /><br />
+ At the top right of the transform parameters, the following icon can be used to hide all automation, but keep it enabled:<br />
+ <img src="../twirl/icon/hide.svg"><br />
+ To display the automation again, the select icon next to the parameter should be used.
+
+ <h1>Scripting</h1>
+ Scripting is not currently documented in full but is fairly self-explanatory. By using the <i>script</i> toolbar shortcut, or the <i>Action > Scripting</i> option on the menu, the script page is shown. By using <i>Load last operation</i> or <i>Load all session operations</i>, you can see the transforms and operations you have previously applied. The script then may be edited, saved and/or auditioned/committed again. <br />
+ Scripts may be a single JSON object or an array of JSON objects which will be applied serially. Each of the parameter details are stored including automation and modulation. The <i>selection</i> key contains an array of three numbers: the first and second and normalised values between 0 and 1 specifying the region of the waveform which is to be transformed, and the third designates the channel (0 = left, 1 = right (if applicable), -1 = all applicable). The <i>instanceIndex</i> key and others referencing index are a 0-based index of the loaded waveforms in twist.
+
+ <h1>Developer</h1>
+ New transforms can be developed and tested in twist. Full details and API reference are on the <a href="developer_documentation.html">developer documentation</a> page.
+</body>
+</html>
\ No newline at end of file diff --git a/site/app/twist/index.html b/site/app/twist/index.html new file mode 100644 index 0000000..4652991 --- /dev/null +++ b/site/app/twist/index.html @@ -0,0 +1,98 @@ +<!doctype html>
+<html lang="en-GB">
+ <head>
+ <title>twist</title>
+ <script type="text/javascript" src="https://apps.csound.1bpm.net/code/jquery.js"></script>
+ <script src="https://apps.csound.1bpm.net/code/d3.v7.min.js"></script>
+ <script type="text/javascript" src="../base/base.js"></script>
+ <script type="text/javascript" src="../twirl/twirl.js"></script>
+ <script type="text/javascript" src="../twirl/appdata.js"></script>
+ <script type="text/javascript" src="../twirl/transform.js"></script>
+ <script type="text/javascript" src="../base/waveform.js"></script>
+ <script type="text/javascript" src="../base/spline-edit.js"></script>
+ <script type="text/javascript" src="../base/analyser.js"></script>
+ <script type="text/javascript" src="twist_ui.js"></script>
+ <script type="text/javascript" src="twist.js"></script>
+ <link rel="stylesheet" href="../twirl/theme.css">
+ <link rel="stylesheet" href="../twirl/twirl.css">
+ <link rel="stylesheet" href="twist.css">
+ <script type="text/javascript">
+ $(twist_startisolated);
+ </script>
+ </head>
+ <body>
+ <div id="twist_start">
+ <div id="twist_start_invoke">
+ <h1>twist</h1>
+ <p>audio transformer</p>
+ <div id="twist_start_invokebig">Press to begin</div>
+ </div>
+ </div>
+
+ <div id="twist">
+ <div id="twist_menubar"></div>
+ <div id="twist_main">
+ <div id="twist_views">
+ <div id="twist_analyser"></div>
+ <div id="twist_waveforms"></div>
+ <div id="twist_splines"></div>
+ </div>
+ <div id="twist_sidepane">
+ <div id="twist_panetree"></div>
+ </div>
+ <div id="twist_controls">
+ <div id="twist_wavecontrols">
+ <table><tbody><tr id="twist_waveform_tabs"></tr><tbody></table>
+ <table><tbody><tr id="twist_wavecontrols_inner"></tr><tbody></table>
+ </div>
+ <div id="twist_controls_inner"></div>
+ </div>
+ </div>
+ <div id="twist_welcome">
+ <h4>Hello</h4>
+ Hover over icons and parameter names to see what they do. Transforms can be selected
+ from the menu on the left; the current file can have the transform auditioned (previewed) or committed (applied). Check out the help and settings for further tips and customisation.<br />
+ At the moment, there is a limitation on files to around five minutes in duration.
+ </div>
+ <div id="twist_script" class="fullscreen_overlay">
+ <h3>Scripting</h3>
+ Scripts can be an individual JSON object or an array of objects in which case they will be committed sequentially. Only single transform scripts can be auditioned.
+ <hr />
+ <textarea id="twist_scriptsource" class="twist_devcode"></textarea>
+ <br />
+ <button id="twist_scriptstop">Stop</button>
+ <button id="twist_scriptaudition" class="twist_scriptbutton">Audition</button>
+ <button id="twist_scriptcommit" class="twist_scriptbutton">Commit</button>
+ <button id="twist_scriptloadlast" class="twist_scriptbutton">Load last</button>
+ <button id="twist_scriptloadall" class="twist_scriptbutton">Load all</button>
+ <button id="twist_scriptcancel" class="twist_scriptbutton">Cancel</button>
+ </div>
+ <div id="twist_developer" class="fullscreen_overlay">
+ <h3>Developer console</h3>
+ Code for transforms can be tested here. The code and definition should follow the guidance and API documentation <a id="twist_developer_documentation" href="developer_documentation.html" target="_blank">provided here.</a> The JSON definition should be a single transform as a JSON object, but mutiple transforms may be loaded individually.<br />
+ Contributions of transforms are warmly welcomed and <a id="twist_developer_submit" href="https://csound.1bpm.net/contact/?type=twist_submit" target="_blank">can be submitted here.</a>
+ <h4>Csound code</h4>
+ <textarea class="twist_devcode" id="twist_devcsound"></textarea>
+ <br /><button id="twist_inject_devcsound">Load Csound orchestra code</button>
+ <hr />
+ <h4>JSON transform definition</h4>
+ <textarea class="twist_devcode" id="twist_devjson"></textarea>
+ <br /><button id="twist_inject_devjson">Load JSON</button>
+ <hr />
+ <button id="twist_exit_devcode">Exit</button>
+ </div>
+ <div id="twist_crash">
+ <h2>twist has crashed.</h2>
+ We are working hard on ironing out all the bugs, but some still occur. To help, details of the last transform you attempted to audition or commit have been sent to the developers.
+ <a href=".">Press here to reload the application.</a>
+ <hr />
+ <div id="twist_crash_recovery">Attempting to recover your work...</div>
+ </div>
+ <div id="twist_hidden_links">
+ <a id="twist_contact" href="https://csound.1bpm.net/contact/?type=general&app=twist" target="_blank">Contact</a>
+ <a id="twist_reportbug" href="https://csound.1bpm.net/contact/?type=report_bug&app=twist" target="_blank">Report bug</a>
+ <a id="twist_documentation" href="documentation.html" target="_blank">Documentation</a>
+ </div>
+ </div>
+ </body>
+</html>
\ No newline at end of file diff --git a/site/app/twist/twist.csd b/site/app/twist/twist.csd new file mode 100644 index 0000000..ccd4085 --- /dev/null +++ b/site/app/twist/twist.csd @@ -0,0 +1,19 @@ +<CsoundSynthesizer>
+<CsOptions>
+-odac
+</CsOptions>
+<CsInstruments>
+sr = 44100
+ksmps = 64
+nchnls = 2
+0dbfs = 1
+seed 0
+nchnls_i = 2
+
+#include "/twist/twist.udo"
+
+</CsInstruments>
+<CsScore>
+f0 z
+</CsScore>
+</CsoundSynthesizer>
\ No newline at end of file diff --git a/site/app/twist/twist.css b/site/app/twist/twist.css new file mode 100644 index 0000000..935ef88 --- /dev/null +++ b/site/app/twist/twist.css @@ -0,0 +1,309 @@ +body {
+ font-family: var(--fontFace);
+ background-color: #000000;
+ color: var(--fgColor1);
+ user-select: none;
+ cursor: arrow;
+}
+
+#twist_hidden_links {
+ display: none;
+}
+
+#twist_crash {
+ font-family: "Nouveau IBM";
+ background-color: #b3240b;
+ color: #e8dedc;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ width: 100%;
+ height: 100%;
+ z-index: 666;
+ user-select: none;
+ cursor: not-allowed;
+ display: none;
+}
+
+#twist_scriptstop {
+ display: none;
+}
+
+#twist_menubar {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ right: 0px;
+ height: 20px;
+ z-index: 6;
+}
+
+a {
+ color: var(--fgColor3);
+ font-weight: bold;
+ text-decoration: none;
+}
+
+#twist_welcome {
+ display: none;
+ font-size: var(--fontSizeDefault);
+}
+
+#twist_main {
+ position: absolute;
+ z-index: 5;
+ background-color: var(--bgColor1);
+ left: 0px;
+ top: 20px;
+ width: 100%;
+ bottom: 0px;
+}
+
+.waveform {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+}
+
+#twist_views {
+ position: absolute;
+ left: 15%;
+ right: 0px;
+ top: 0px;
+ height: 50%;
+}
+
+#twist_analyser {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ height: 40%;
+ width: 100%;
+ background-color: var(--bgColor1);
+ display: none;
+}
+
+#twist_waveforms {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ bottom: 0px;
+ width: 100%;
+}
+
+#twist_splines {
+ position: absolute;
+ left: 0px;
+ top: 0px;
+ bottom: 0px;
+ margin-top: 15px;
+ margin-bottom: 15px;
+ width: 100%;
+ display: none;
+ z-index: 20;
+ background-color: var(--waveformOverlayColor);
+ opacity: 0.5;
+}
+
+.twist_scope {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+}
+
+.waveform_overlay {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background-color: var(--waveformOverlayColor);
+ opacity: 0.95;
+ left: 0px;
+ top: 0px;
+ z-index: 30;
+}
+
+.waveform_overlay_mid {
+ font-size: 12pt;
+ padding-top: 100px;
+ text-align: center;
+}
+
+
+#twist_sidepane {
+ position: absolute;
+ background-color: var(--bgColor3);
+ left: 0px;
+ top: 0px;
+ height: 100%;
+ width: 15%;
+ overflow-y: scroll;
+ overflow-x: auto;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+#twist_controls {
+ position: absolute;
+ background-color: var(--bgColor1);
+ left: 15%;
+ top: 50%;
+ bottom: 0px;
+ right: 0px;
+}
+
+#twist_controls_inner {
+ position: absolute;
+ background-color: var(--bgColor4);
+ left: 0px;
+ top: 70px;
+ bottom: 0px;
+ width: 100%;
+ overflow-y: scroll;
+ overflow-x: auto;
+ scrollbar-color: var(--scrollbarColor);
+}
+
+#twist_wavecontrols {
+ position: absolute;
+ overflow: hidden;
+ left: 0px;
+ top: 0px;
+ height: 70px;
+ width: 100%;
+}
+
+#twist_waveform_tabs {
+ cursor: pointer;
+}
+
+#twist_help {
+ z-index: 60;
+ position: absolute;
+ background-color: var(--bgColor1);
+ opacity: 0.9;
+ width: 100%;
+ height: 100%;
+ top: 0px;
+ left: 0px;
+ overflow-y: scroll;
+ overflow-x: auto;
+ scrollbar-color: var(--scrollbarColor);
+ display: none;
+ cursor: pointer;
+}
+
+#twist_panetree {
+ font-size: var(--fontSizeDefault);
+ font-family: var(--fontFace);
+}
+
+button {
+ border: var(--buttonBorder);
+ font-color: var(--fgColor3);
+ color: var(--fgColor3);
+ background-color: var(--bgColor4);
+ font-size: var(--fontSizeDefault);
+ padding: 2px;
+ font-family: var(--fontFace);
+ white-space: nowrap;
+}
+
+select {
+ background-color: var(--bgColor2);
+ color: var(--fgColor2);
+}
+
+input[type="checkbox"] {
+ accent-color: var(--bgColor1);
+}
+
+.automate_container {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ z-index: 125;
+ display: none;
+}
+
+.twist_devcode {
+ background-color: var(--codeBgColor);
+ color: var(--codeFgColor);
+ font-size: var(--codeFontSize);
+ font-family: var(--codeFontFace);
+ width: 80%;
+ height: 20%;
+}
+
+#twist_scriptsource {
+ height: 60%;
+ overflow-y: auto;
+ overflow-x: hide;
+}
+
+#twist_developer {
+ overflow-y: auto;
+ overflow-x: hide;
+}
+
+.fullscreen_overlay {
+ position: fixed;
+ display: none;
+ z-index: 60;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: var(--bgColor3);
+ font-size: var(--fontSizeDefault);
+ opacity: 0.96;
+}
+
+#twist_start {
+ z-index: 300;
+ position: fixed;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+ background-color: var(--bgColor2);
+ cursor: pointer;
+}
+
+#twist_start_invoke {
+ z-index: 202;
+ text-align: centre;
+ margin: 0px;
+ position: absolute;
+ top: 20%;
+ left: 20%;
+ width: 60%;
+ height: 40%;
+}
+
+#twist_start_invokebig {
+ font-size: 48pt;
+}
+
+.wtab_selected {
+ font-size: var(--fontSizeDefault);
+ font-weight: bold;
+ background-color: var(--tabSelectedBgColor);
+ color: var(--tabSelectedFgColor);
+ padding: 3px;
+ border: 1px solid black;
+ border-top: 0;
+}
+
+.wtab_unselected {
+ font-size: var(--fontSizeDefault);
+ background-color: var(--tabUnselectedBgColor);
+ color: var(--tabUnselectedFgColor);
+ font-weight: normal;
+ padding: 3px;
+ border: 1px solid black;
+}
+
diff --git a/site/app/twist/twist.js b/site/app/twist/twist.js new file mode 100644 index 0000000..a7a248c --- /dev/null +++ b/site/app/twist/twist.js @@ -0,0 +1,1248 @@ +var OperationWatchdog = function(twist) {
+ var self = this;
+ var active = false;
+ var lastValues = [true, true];
+ var firstActive = true;
+ var checkInterval;
+ var timeoutTime = 30000;
+ var alivetimeoutTime = 3500;
+ var context;
+
+ function crash() {
+ self.stop();
+ twirl.sendErrorState({text: "Unhandled exception in " + context});
+ var el = $("#twist_crash").show();
+ var elSr = $("#twist_crash_recovery");
+
+ function doomed() {
+ elSr.empty().append($("<h4 />").text("Sorry, unfortunately your work cannot be saved."));
+ }
+
+ var doomedTimeout = setTimeout(doomed, 6000);
+
+ var cbid = app.createCallback(function(ndata) {
+ if (doomedTimeout) clearTimeout(doomedTimeout);
+
+ if (!ndata.left && !ndata.right) {
+ return doomed();
+ }
+ elSr.empty();
+ var text;
+ var linkLeft = $("<a />").attr("href", "#").text("Download").click(function(e){
+ e.preventDefault();
+ twist.downloadFile("/crashL.wav");
+ });
+ if (ndata.left && !ndata.right) {
+ elSr.append($("<h4 />").text("Your work has been recovered:"));
+ elSr.append(linkLeft);
+ } else {
+ elSr.append($("<h4 />").text("Your work has been recovered as separate left/right channels:"));
+ linkLeft.text("Download left channel").appendTo(elSr);
+ elSr.append("<br />");
+ var linkRight = $("<a />").attr("href", "#").text("Download right channel").click(function(e){
+ e.preventDefault();
+ twist.downloadFile("/crashR.wav");
+ }).appendTo(elSr);
+ }
+
+ });
+ app.getCsound().compileOrc("iwrittenL = 0\niwrittenR = 0\nif (gitwst_bufferL[gitwst_instanceindex] > 0) then\niwrittenL ftaudio gitwst_bufferL[gitwst_instanceindex], \"/crashL.wav\", 14\nendif\nif (gitwst_bufferR[gitwst_instanceindex] > 0) then\niwrittenR ftaudio gitwst_bufferR[gitwst_instanceindex], \"/crashR.wav\", 14\nendif\nio_sendstring(\"callback\", sprintf(\"{\\\"cbid\\\":" + cbid + ",\\\"left\\\":%d,\\\"right\\\":%d}\", iwrittenL, iwrittenR))\n");
+ }
+
+ function checkAlive() {
+ var alive = false;
+ var aliveTimeout = setTimeout(crash, alivetimeoutTime);
+ var cbid = app.createCallback(function(){
+ clearTimeout(aliveTimeout);
+ alive = true;
+ });
+ app.insertScore("twst_checkalive", [0, 1, cbid]);
+ }
+
+ this.start = function(startContext) {
+ active = true;
+ context = startContext;
+ firstActive = true;
+ lastValues = [true, true];
+ if (checkInterval) clearInterval(checkInterval);
+ checkInterval = setInterval(function() {
+ if (lastValues[0] === lastValues[1]) {
+ checkAlive();
+ }
+ }, timeoutTime);
+ };
+
+ this.setActive = function(value) {
+ if (!active) return;
+ if (firstActive) {
+ firstActive = false;
+ } else {
+ lastValues[0] = lastValues[1];
+ }
+ lastValues[1] = value;
+ };
+
+ this.stop = function() {
+ active = false;
+ firstActive = true;
+ lastValues = [true, true];
+ if (checkInterval) clearInterval(checkInterval);
+ };
+};
+
+var Twist = function() {
+ twirl.init();
+ var self = this; // TODO deprecate this in favour of below
+ var twist = this;
+ this.storage = localStorage.getItem("twist");
+ if (self.storage) {
+ self.storage = JSON.parse(self.storage);
+ } else {
+ self.storage = {
+ dcblockoutputs: 1,
+ tanhoutputs: 1,
+ maxundo: 2,
+ showShortcuts: 1,
+ commitHistoryLevel: 16,
+ scopeType: 0
+ };
+ }
+
+ twist.version = 1;
+ this.currentTransform = null;
+ var errorState;
+ var instanceIndex = 0;
+ this.waveforms = [];
+ var waveformFiles = [];
+ var waveformTabs = [];
+ var waveformLoaded = [];
+ this.playheadInterval = null;
+ var playing = false;
+ var auditioning = false;
+ var recording = false;
+ this.onPlays = [];
+ this.onInstanceChangeds = [];
+ this.operationLog = [];
+ var sr = 44100;
+ var undoLevels = [];
+ var onSave;
+ this.visible = false;
+ this.playbackLoop = false;
+ this.twine = null;
+ this.hasClipboard = false;
+ this.watchdog = new OperationWatchdog(twist);
+ this.ui = new TwistUI(twist);
+
+ this.setPlaying = function(state) {
+ if (playing == state) return;
+ playing = state;
+ for (var o of twist.onPlays) {
+ o(playing, auditioning, recording);
+ }
+ if (twist.currentTransform) {
+ twist.currentTransform.setPlaying(state);
+ }
+ twist.ui.setPlaying(state);
+
+ if (!state) {
+ twist.watchdog.stop();
+ twist.waveform.movePlayhead(0);
+ if (twist.playheadInterval) {
+ clearInterval(twist.playheadInterval);
+ }
+ }
+ };
+
+ this.saveStorage = function() {
+ localStorage.setItem("twist", JSON.stringify(twist.storage));
+ };
+
+ this.lastOperation = function() {
+ return twist.operationLog[twist.operationLog.length - 1];
+ };
+
+ this.clearOperationLog = function() {
+ twist.operationLog = [];
+ };
+
+ async function pushOperationLog(operation, logChannels) {
+ var max = twist.storage.commitHistoryLevel;
+ if (!max) {
+ twist.storage.commitHistoryLevel = max = 16;
+ }
+ if (twist.operationLog.length + 1 >= max) {
+ twist.operationLog.shift();
+ }
+ if (logChannels) {
+ if (!operation.channels) operation.channels = {};
+ for (let c of logChannels) {
+ operation.channels[c] = await app.getControlChannel(c);
+ }
+ }
+ twist.operationLog.push(operation);
+ }
+
+ this.createNewInstance = function(noShowLoadNew) {
+ var element = $("<div />").addClass("waveform").appendTo("#twist_waveforms");
+ let index = waveformFiles.length;
+
+ if (index < 0) index = 0;
+ waveformTabs.push(
+ $("<td />").text("New file").click(function() {
+ if (twist.isPlaying()) return;
+ twist.waveform = index;
+ }).addClass("wtab_selected").appendTo("#twist_waveform_tabs")
+ );
+ undoLevels.push(0);
+ var waveform = new Waveform({
+ target: element,
+ latencyCorrection: twirl.latencyCorrection,
+ showcrossfades: true,
+ crossFadeWidth: 1,
+ timeBar: true,
+ markers: [
+ {preset: "selectionstart"},
+ {preset: "selectionend"},
+ ]
+ })
+ waveform.onRegionChange = function(region) {
+ if (twist.currentTransform) {
+ twist.currentTransform.redraw(region);
+ }
+ };
+ twist.waveforms.push(waveform);
+ if (!noShowLoadNew) twist.ui.showLoadNewPrompt();
+ twist.waveform = index;
+ for (let o of twist.onInstanceChangeds) {
+ o(true, index);
+ }
+ };
+
+
+ function removeInstance(i) {
+ if (!i) i = instanceIndex;
+ if (twist.waveforms.length == 1 || i < 0 || i > twist.waveforms.length - 1) {
+ return;
+ }
+ twist.waveforms[i].destroy();
+ delete twist.waveforms[i];
+ waveformTabs[i].remove();
+ waveformLoaded[instanceIndex] = false;
+ delete waveformTabs[i]
+ if (instanceIndex == i) {
+ instanceIndex = i + ((i == 0) ? 1 : -1);
+ twist.waveform.show();
+ }
+ for (let o of twist.onInstanceChangeds) {
+ o(false, i);
+ }
+ }
+
+ this.closeInstance = function(i) {
+ removeInstance(i);
+ };
+
+
+
+ this.errorHandler = async function(text, onComplete) {
+ var errorObj = {
+ lastOperation: twist.lastOperation()
+ };
+ if (twist.currentTransform) {
+ var state = await twist.currentTransform.getState();
+ errorObj.transformState = state;
+ }
+
+ twirl.errorHandler(text, onComplete, errorObj);
+ twist.setPlaying(false);
+ };
+
+ function playPositionHandler(noPlayhead, onComplete, monitorChannels) {
+ function callback(ndata) {
+ if (ndata.status == 1) { // playing
+ twist.setPlaying(true);
+ if (!noPlayhead) {
+ twist.watchdog.start("audition");
+ if (twist.playheadInterval) {
+ clearInterval(twist.playheadInterval);
+ }
+ twist.playheadInterval = setInterval(async function(){
+ var val = await app.getControlChannel("twst_playposratio");
+ twist.watchdog.setActive(val);
+ if (val < 0 || val > 1) {
+ clearInterval(twist.playheadInterval);
+ }
+
+ var monitorValues;
+ if (monitorChannels) {
+ monitorValues = [];
+ monitorValues.push((monitorChannels[0]) ? await app.getControlChannel(monitorChannels[0]) : null);
+ monitorValues.push((monitorChannels[1]) ? await app.getControlChannel(monitorChannels[1]) : null);
+ } else {
+ monitorValues = null;
+ }
+ twist.waveform.movePlayhead(val, monitorValues);
+ }, 50);
+ }
+ return;
+ }
+ // stopped
+ app.removeCallback(ndata.cbid);
+
+ if (twist.playbackLoop && ndata.status == 0 && onComplete) {
+ return onComplete(ndata);
+ }
+ twist.setPlaying(false);
+
+ if (ndata.status == -1) {
+ var container = $("<div />");
+ $("<p />").text("Not enough processing power to transform in realtime").appendTo(container);
+ var lagHintHtml = twist.currentTransform.getLagHints();
+ if (lagHintHtml) {
+ $("<p />").html(lagHintHtml).appendTo(container);
+ }
+
+ return twirl.prompt.show(container);
+ } else if (ndata.status == 2) { // record complete
+ globalCallbackHandler(ndata);
+ }
+ if (onComplete) onComplete(ndata);
+
+ }
+ return app.createCallback(callback, true);
+ }
+
+ function operation(options) {
+ var s = (options.selection) ? options.selection : twist.waveform.selected;
+ errorState = "Operation error";
+ if (options.showLoading) {
+ twist.ui.setLoadingStatus(true);
+ }
+ var cbid;
+ if (!options.onComplete || typeof(options.onComplete) == "function") {
+ cbid = app.createCallback(function(ndata) {
+ twist.waveform.cover(false);
+ if (options.onComplete) {
+ options.onComplete(ndata);
+ } else if (ndata.status && ndata.status <= 0) {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file would be too large";
+ }
+ twist.errorHandler(text);
+ }
+ if (options.showLoading) {
+ twist.ui.setLoadingStatus(false);
+ }
+ });
+ } else {
+ cbid = options.onComplete;
+ }
+ if (!options.noLogScript) {
+ pushOperationLog({
+ type: "operation",
+ instr: options.instr,
+ name: options.name,
+ selection: s,
+ instanceIndex: instanceIndex
+ }, options.logScriptChannels);
+ }
+ app.insertScore(options.instr, [0, 1, cbid, s[0], s[1], s[2], (options.noCheckpoint) ? 1 : 0]);
+ }
+
+ this.isPlaying = function() {
+ return playing;
+ };
+
+ this.redraw = function() {
+ if (twist.currentTransform) {
+ twist.currentTransform.redraw();
+ }
+ for (let w of twist.waveforms) {
+ w.redraw();
+ }
+ };
+
+ this.undo = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_undo",
+ name: "Undo",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ noLogScript: true
+ });
+ };
+
+ this.cut = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_cut",
+ name: "Cut",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ });
+ twist.hasClipboard = true;
+ };
+
+ this.trim = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_trim",
+ name: "Trim",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ });
+ };
+
+ this.delete = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_delete",
+ name: "Delete",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ });
+ };
+
+ this.copy = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_copy",
+ name: "Copy",
+ showLoading: true,
+ });
+ twist.hasClipboard = true;
+ };
+
+ this.paste = function() {
+ if (playing) return;
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_paste",
+ name: "Paste",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ });
+ };
+
+ this.moveToNextTransient = function() {
+ if (playing) return;
+ var cbid = app.createCallback(globalCallbackHandler);
+ var s = twist.waveform.selected;
+ app.insertScore("twst_nexttransient",
+ [0, 1, cbid, s[1], s[1], s[2]]
+ );
+ };
+
+ this.selectToNextTransient = function() {
+ if (playing) return;
+ var cbid = app.createCallback(globalCallbackHandler);
+ var s = twist.waveform.selected;
+ var selend = (s[0] == s[1]) ? s[1] + 0.000001 : s[1];
+ app.insertScore("twst_nexttransient",
+ [0, 1, cbid, s[0], selend, s[2]]
+ );
+ };
+
+ this.moveToStart = function() {
+ if (playing) return;
+ twist.waveform.setSelection(0);
+ };
+
+ this.moveToEnd = function() {
+ if (playing) return;
+ twist.waveform.setSelection(1);
+ };
+
+ this.selectAll = function() {
+ if (playing) return;
+ twist.waveform.setSelection(0, 1);
+ };
+
+ this.selectNone = function() {
+ if (playing) return;
+ twist.waveform.setSelection(0);
+ };
+
+ this.selectToEnd = function() {
+ if (playing) return;
+ twist.waveform.alterSelection(null, 1);
+ }
+
+ this.selectFromStart = function() {
+ if (playing) return;
+ twist.waveform.alterSelection(0, null);
+ }
+
+ this.pasteSpecial = function() {
+ if (playing) return;
+ var elPasteSpecial = $("<div />");
+ elPasteSpecial.append($("<h4 />").text("Paste special"));
+ var def = {
+ instr: "twst_pastespecial",
+ parameters: [
+ {name: "Repetitions", channel: "repetitions", min: 1, max: 40, step: 1, dfault: 1, automatable: false},
+ {name: "Mix paste", channel: "mixpaste", step: 1, dfault: 0, automatable: false}
+ ]
+ };
+ var tf = new twirl.transform.Transform({
+ element: elPasteSpecial,
+ definition: def,
+ host: twist
+ });
+
+ $("<button />").text("Paste").click(function(){
+ twist.ui.hidePrompt();
+ twist.waveform.cover(true);
+ operation({
+ instr: "twst_pastespecial",
+ name: "Paste special",
+ onComplete: globalCallbackHandler,
+ showLoading: true,
+ logScriptChannels: ["twst_pastespecial_repetitions", "twst_pastespecial_mixpaste"]
+ });
+
+ }).appendTo(elPasteSpecial);
+
+ $("<button />").text("Cancel").click(function(){
+ twist.ui.hidePrompt();
+ }).appendTo(elPasteSpecial);
+ twist.ui.showPrompt(elPasteSpecial, null, true);
+
+ };
+
+
+ this.play = function(playOverride) {
+ if (!waveformLoaded[instanceIndex] || (playing && !playOverride)) return;
+ auditioning = false;
+ recording = false;
+ operation({
+ instr: "twst_play",
+ name: "Play",
+ onComplete: playPositionHandler(false, function(ndata){
+ if (ndata.status != 3 && twist.playbackLoop) { // 3 = user-stopped
+ twist.play(true);
+ }
+ }),
+ noLogScript: true
+ });
+ };
+
+ this.stop = function() {
+ if (!playing || !waveformLoaded[instanceIndex]) return;
+ twist.waveform.cover(false);
+ app.insertScore("twst_stop");
+ };
+
+ var saveNumber = 1;
+ function formatFileName(name) {
+ if (!name) name = waveformTabs[instanceIndex].text();
+ if (!name.toLowerCase().endsWith(".wav")) {
+ name += ".wav";
+ }
+
+ // HACK TODO: WASM can't overwrite files
+ name = name.substr(0, name.lastIndexOf(".")) + "." + (saveNumber ++) + name.substr(name.lastIndexOf("."));
+ // END HACK
+ return name;
+ }
+
+ this.downloadFile = async function(path, name) {
+ if (!name) name = formatFileName(name);
+ var content = await app.readFile(path);
+ var blob = new Blob([content], {type: "audio/wav"});
+ var url = window.URL.createObjectURL(blob);
+ var a = $("<a />").attr("href", url).attr("download", name).appendTo($("body")).css("display", "none");
+ a[0].click();
+ setTimeout(function(){
+ a.remove();
+ window.URL.revokeObjectURL(url);
+ app.unlinkFile(path);
+ }, 20000);
+ };
+
+ this.saveFile = function(name, onComplete) {
+ if (playing) return;
+ if (onSave) {
+ twirl.loading.show("Processing");
+ var cbid = app.createCallback(function(ndata){
+ twirl.loading.hide();
+ onSave(ndata.tables);
+ });
+ app.insertScore("twst_getbuffers", [0, 1, cbid]);
+ return;
+ }
+ if (!name) name = formatFileName(name);
+ var cbid = app.createCallback(async function(ndata){
+ await self.downloadFile("/" + name, name);
+ if (onComplete) onComplete();
+ self.ui.setLoadingStatus(false);
+ });
+ self.ui.setLoadingStatus(true, true, "Saving");
+ app.insertScore("twst_savefile", [0, 1, cbid, name]);
+ };
+
+ function getAutomationData(start, end) {
+ var calls = [];
+ if (!self.currentTransform) return calls;
+ var automations = self.currentTransform.getAutomationData(start, end);
+ if (automations && automations.length > 0) {
+ for (let i in automations) {
+ if (automations[i].type == "modulation") {
+ calls.push(automations[i].data[0] + " \"" + automations[i].data[1] + "\"");
+ } else if (automations[i].type == "automation") {
+ calls.push("chnset linseg:k(" + automations[i].data + "), \"" + automations[i].channel + "\"");
+ }
+ }
+ }
+ return calls;
+ }
+
+ function handleAutomation(onready, calls) {
+ if (calls.length == 0) {
+ return onready(0);
+ }
+
+ var instr = "instr twst_automaterun\n";
+ for (let c of calls) {
+ instr += c + "\n";
+ }
+ instr += "a_ init 0\nout a_\nendin\n";
+ app.compileOrc(instr).then(function(status){
+ if (status < 0) {
+ self.errorHandler("Cannot parse automation data");
+ } else {
+ onready(1);
+ }
+ });
+ /*
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ onready(1);
+ } else {
+ self.errorHandler("Cannot parse automation data");
+ }
+ });
+
+ var call = [0, 1, cbid];
+ for (let c of calls) {
+ call.push(c);
+ }
+ app.insertScore("twst_automationprepare", call);
+ */
+ }
+
+
+ function fftsizeCheck(selected, duration) {
+ if (self.currentTransform) {
+ for (var p in self.currentTransform.parameters) {
+ if (p.indexOf("fftsize") != -1) {
+ var val = self.currentTransform.parameters[p].getValue();
+ var minTime = (val / sr) * 2;
+ if ((selected[1] - selected[0]) * duration < minTime) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ this.record = async function() {
+ if (!waveformLoaded[instanceIndex] ||playing) return;
+ auditioning = false;
+ recording = true;
+ await app.enableAudioInput();
+ errorState = "Recording error";
+ self.waveform.cover(true);
+ var s = self.waveform.selected;
+ var monitorChannels;
+ if (self.waveform.channels == 1) {
+ monitorChannels = ["recordmonitorL"];
+ } else {
+ if (s[2] == -1) {
+ monitorChannels = ["recordmonitorL", "recordmonitorR"];
+ } else if (s[2] == 0) {
+ monitorChannels = ["recordmonitorL", null];
+ } else if (s[2] == 1) {
+ monitorChannels = [null, "recordmonitorR"];
+ }
+ }
+ self.waveform.resetDrawOneValue();
+ var cbid = playPositionHandler(null, null, monitorChannels);
+ var items = [0, 1, cbid, s[0], s[1], s[2]];
+ app.insertScore("twst_record", items);
+ };
+
+ this.audition = function(playOverride) {
+ if (!waveformLoaded[instanceIndex] || (playing && !playOverride)) return;
+ if (!self.currentTransform) {
+ return self.play();
+ }
+ self.currentTransform.saveState();
+ var s = self.waveform.selected;
+ if (s[0] == s[1]) {
+ s[0] = 0;
+ s[1] = 1;
+ }
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+
+ auditioning = true;
+ recording = false;
+ errorState = "Playback error";
+ handleAutomation(function(automating){
+ var cbid = playPositionHandler(false, function(ndata){
+ if (ndata.status != 3 && self.playbackLoop) { // 3 = user-stopped
+ self.audition(true);
+ }
+ });
+ var xfade = self.ui.getCrossFadeValues();
+ var items = [
+ 0, 1, cbid, s[0], s[1], s[2],
+ self.currentTransform.instr, automating,
+ xfade[0], xfade[1]
+ ];
+ app.insertScore("twst_audition", items);
+ }, getAutomationData(s[0], s[1]));
+
+ };
+
+
+ var scriptStack = [];
+ function applyScript(audition, first, lastData) {
+ if (playing) return;
+ var noCheckpoint = !first;
+ var script = scriptStack.shift();
+ if (!script) {
+ self.ui.setLoadingStatus(false);
+ if (lastData) {
+ globalCallbackHandler(lastData);
+ }
+ self.setPlaying(false);
+ return;
+ }
+
+ if (audition) auditioning = true;
+ self.setPlaying(true);
+
+ if (script.type == "operation") {
+ if (audition) {
+ return self.errorHandler("Only transform scripts can be auditioned");
+ }
+ self.ui.setLoadingStatus(true);
+ self.waveform.cover(true);
+ onComplete = (script.instr == "twst_copy") ? null : globalCallbackHandler;
+
+ operation({
+ instr: script.instr,
+ name: script.name,
+ onComplete: function(ndata){
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition, false, lastData);
+ },
+ showLoading: true,
+ selection: script.selection,
+ noLogScript: true,
+ noCheckpoint: noCheckpoint
+ });
+
+ } else if (script.type == "transform") {
+ errorState = ((audition) ? "Audition" : "Transform" ) + " commit error";
+ if (!audition) {
+ self.ui.setLoadingStatus(true, true);
+ }
+
+ for (let channel in script.channels) {
+ app.setControlChannel(channel, script.channels[channel]);
+ }
+ handleAutomation(function(automating){
+ if (audition) {
+ var cbid = playPositionHandler();
+ } else {
+ var cbid = app.createCallback(function(ndata) {
+ lastData = ndata;
+ self.setPlaying(false);
+ applyScript(audition, false, lastData);
+ });
+ }
+ var instr = "twst_" + ((audition) ? "audition" : "commit");
+
+ app.insertScore(instr, [
+ 0, -1, cbid, script.selection[0], script.selection[1], script.selection[2], script.instr, automating, script.crossfades[0], script.crossfades[1], (noCheckpoint) ? 1 : 0
+ ]);
+ }, script.automation);
+ }
+ }
+
+ this.applyScript = async function(script, audition) {
+ if (playing) return;
+ scriptStack = [];
+ if (Array.isArray(script)) {
+ if (audition) {
+ return self.errorHandler("Only single scripts can be auditioned");
+ }
+ scriptStack = script;
+ } else {
+ scriptStack = [script];
+ }
+ if (self.storage.autosave && !audition) {
+ self.saveFile(null, function() {
+ applyScript(audition, true);
+ });
+ } else {
+ applyScript(audition, true);
+ }
+ };
+
+ async function innerCommit() {
+ if (playing) return;
+ if (!self.currentTransform) return;
+ var s = self.waveform.selected;
+ if (s[0] == s[1]) {
+ s[0] = 0;
+ s[1] = 1;
+ }
+ if (!fftsizeCheck(s, self.waveform.duration)) {
+ return self.errorHandler("Length too short for this transform");
+ }
+ self.watchdog.start("commit");
+ self.setPlaying(true);
+ self.ui.setLoadingStatus(true, true, null);
+ var calls = getAutomationData(s[0], s[1]);
+
+ self.currentTransform.saveState();
+ var state = await self.currentTransform.getState();
+ state.type = "transform";
+ state.automation = calls;
+ state.crossfades = self.ui.getCrossFadeValues();
+ state.selection = [s[0], s[1], s[2]];
+ state.instanceIndex = instanceIndex;
+ pushOperationLog(state);
+
+ handleAutomation(function(automating){
+ var cbid = app.createCallback(function(ndata) {
+ self.watchdog.stop();
+ self.ui.setLoadingStatus(false);
+ self.setPlaying(false);
+ if (ndata.status > 0) {
+ globalCallbackHandler(ndata);
+ } else {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file is too large";
+ }
+ self.errorHandler(text);
+ }
+ });
+ errorState = "Transform commit error";
+ app.insertScore("twst_commit", [0, -1, cbid, s[0], s[1], s[2], self.currentTransform.instr, automating, state.crossfades[0],state.crossfades[1]]);
+ }, calls);
+ }
+
+ this.commit = async function() {
+ if (!waveformLoaded[instanceIndex]) return;
+ if (self.storage.autosave) {
+ self.saveFile(null, function() {
+ innerCommit();
+ });
+ } else {
+ innerCommit();
+ }
+ };
+
+ this.loadTransforms = function(transform) {
+ if (transform) {
+ var developObj;
+ for (var t in twirl.appdata.transforms) {
+ if (twirl.appdata.transforms[t].name == "Develop") {
+ developObj = twirl.appdata.transforms[t];
+ break;
+ }
+ }
+ if (!developObj) {
+ developObj = {name: "Develop", contents: []};
+ twirl.appdata.transforms.push(developObj);
+ } else {
+ for (var c in developObj.contents) {
+ if (developObj.contents[c].name == transform.name) {
+ delete developObj.contents[c];
+ }
+ }
+ }
+ developObj.contents.push(transform);
+ }
+
+ $("#twist_panetree").empty();
+ var ttv = new twirl.transform.TreeView({
+ element: $("#twist_panetree"),
+ items: twirl.appdata.transforms,
+ click: function(definition, path) {
+ if (twist.currentTransform) {
+ twist.currentTransform.remove();
+ }
+ twist.currentTransform = new twirl.transform.Transform({
+ element: $("#twist_controls_inner"),
+ definition: definition,
+ splineElement: $("#twist_splines"),
+ useStorage: true,
+ path: path,
+ otherInstanceNamesFunc: function() {
+ return twist.otherInstanceNames;
+ },
+ instancesFunc: function() {
+ return twist.waveforms;
+ },
+ getRegionFunc: function() {
+ return twist.waveform.getRegion();
+ },
+ getDurationFunc: function() {
+ return twist.waveform.getDuration();
+ },
+ onHideAutomation: function() {
+ twist.ui.deleteSupressed = false;
+ console.log("twist.ui.deleteSupressed", twist.ui.deleteSupressed);
+ },
+ onShowAutomation: function() {
+ twist.ui.deleteSupressed = true;
+ console.log("twist.ui.deleteSupressed", twist.ui.deleteSupressed);
+ },
+ host: twist
+ });
+ }
+ });
+ };
+
+ this.createEmpty = function(name, duration, channels) {
+ if (name.trim() == "") {
+ name = "New file";
+ }
+ var cbid = app.createCallback(async function(ndata) {
+ twist.waveformTab.text(name);
+ await globalCallbackHandler(ndata);
+ if (twist.currentTransform) {
+ twist.currentTransform.refresh();
+ }
+ waveformFiles[instanceIndex] = name;
+ waveformLoaded[instanceIndex] = true;
+ twist.ui.setLoadingStatus(false);
+ });
+ twist.ui.hidePrompt();
+ twist.ui.setLoadingStatus(true, false, "Creating");
+ app.insertScore("twst_createempty", [0, 1, cbid, duration, channels]);
+ };
+
+ this.setVisible = function(state) {
+ twist.visible = state;
+ var el = $("#twist");
+ if (state) {
+ el.show();
+ } else {
+ el.hide();
+ }
+ };
+
+ this.editInTwigs = function() {
+ if (!window.twigs) {
+ return twirl.prompt.show("twigs is unavailable in this session");
+ }
+ twirl.loading.show("Processing");
+ var cbid = app.createCallback(function(ndata){
+ twirl.loading.hide();
+ twigs.loadFileFromFtable(waveformFiles[instanceIndex], ndata.tables, function(ldata){
+ if (ldata.status > 0) {
+ self.setVisible(false);
+ twigs.setVisible(true);
+ }
+ }, onSave);
+ });
+ app.insertScore("twst_getbuffers", [0, 1, cbid]);
+ };
+
+ this.loadFileFromClipboard = function() {
+ if (!twist.hasClipboard) {
+ return twirl.prompt.show("Cannot create: clipboard is empty");
+ }
+ errorState = "File loading error";
+ twirl.loading.show("Loading");
+ var cbid = app.createCallback(async function(ndata){
+ self.waveformTab.text("Clipboard");
+ await globalCallbackHandler(ndata);
+ waveformFiles[instanceIndex] = "Clipboard";
+ waveformLoaded[instanceIndex] = true;
+ twirl.loading.hide();
+ });
+ app.insertScore("twst_loadclipboard", [0, 1, cbid]);
+ };
+
+ this.loadFileFromFtable = function(name, tables, onComplete, onSaveFunc) {
+ errorState = "File loading error";
+ twirl.loading.show("Loading file");
+
+ var cbid = app.createCallback(async function(ndata){
+ twirl.loading.hide();
+ if (ndata.status > 0) {
+ if (waveformTabs.length == 0) {
+ self.createNewInstance(true);
+ instanceIndex = 0;
+ }
+ self.waveformTab.text(name);
+ waveformLoaded[instanceIndex] = true;
+ await globalCallbackHandler(ndata);
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ waveformFiles[instanceIndex] = name;
+ self.ui.hidePrompt();
+ onSave = onSaveFunc;
+ } else if (ndata.status == -1) {
+ twirl.prompt.show("File not valid");
+ } else if (ndata.status == -2) {
+ twirl.prompt.show("File too large");
+ } else {
+ twirl.prompt.show("File loading error");
+ }
+ if (onComplete) {
+ onComplete(ndata);
+ }
+ });
+ var call = [0, 1, cbid];
+ for (let t of tables) {
+ call.push(t);
+ }
+ app.insertScore("twst_loadftable", call);
+ };
+
+
+ async function handleFileDrop(e, obj) {
+ e.preventDefault();
+ if (!e.originalEvent.dataTransfer && !e.originalEvent.files) {
+ return;
+ }
+ if (e.originalEvent.dataTransfer.files.length == 0) {
+ return;
+ }
+ self.ui.hidePrompt();
+ self.ui.setLoadingStatus(true, true, "Loading");
+ for (const item of e.originalEvent.dataTransfer.files) {
+ if (!twirl.audioTypes.includes(item.type)) {
+ return self.errorHandler("Unsupported file type", self.ui.showLoadNewPrompt);
+ }
+ if (item.size > twirl.maxFileSize) {
+ return self.errorHandler("File too large", self.ui.showLoadNewPrompt);
+ }
+ errorState = "File loading error";
+ var content = await item.arrayBuffer();
+ const buffer = new Uint8Array(content);
+ await app.writeFile(item.name, buffer);
+ var cbid = app.createCallback(async function(ndata){
+ await app.unlinkFile(item.name);
+ if (ndata.status == -1) {
+ return self.errorHandler("File not valid", self.ui.showLoadNewPrompt);
+ } else if (ndata.status == -2) {
+ return self.errorHandler("File too large", self.ui.showLoadNewPrompt);
+ } else {
+ self.waveformTab.text(item.name);
+ await globalCallbackHandler(ndata);
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ }
+ waveformFiles[instanceIndex] = item.name;
+ waveformLoaded[instanceIndex] = true;
+ self.ui.hidePrompt();
+ self.ui.setLoadingStatus(false);
+ onSave = false;
+ }
+ });
+ app.insertScore("twst_loadfile", [0, 1, cbid, item.name]);
+ }
+ }
+
+ async function globalCallbackHandler(ndata) {
+ if (ndata.status && ndata.status <= 0) {
+ var text;
+ if (ndata.status == -2) {
+ text = "Resulting file would be too large";
+ }
+ self.errorHandler(text);
+ return;
+ }
+
+ self.watchdog.start("refresh");
+
+ if (ndata.hasOwnProperty("undolevel")) {
+ self.undoLevel = ndata.undolevel;
+ }
+
+ if (ndata.hasOwnProperty("delete")) {
+ if (typeof(ndata.delete) == "string") {
+ app.unlinkFile(ndata.delete);
+ } else {
+ for (let d of ndata.delete) {
+ app.unlinkFile(d);
+ }
+ }
+ }
+
+ if (ndata.hasOwnProperty("selstart")) {
+ self.waveform.setSelection(ndata.selstart, ndata.selend);
+ }
+
+ if (ndata.hasOwnProperty("waveL")) {
+ self.waveform.cover(true);
+ errorState = "Overview refresh error";
+ setTimeout(async function(){
+ var wavedata = [];
+ var tbL = await app.getTable(ndata.waveL);
+ wavedata.push(tbL);
+ if (ndata.hasOwnProperty("waveR")) {
+ var tbR = app.getTable(ndata.waveR);
+ wavedata.push(tbR);
+ }
+ self.waveform.setData(wavedata, ndata.duration);
+ self.waveform.cover(false);
+ }, 10);
+ }
+ self.watchdog.stop();
+ }
+
+ this.bootAudio = async function(twine) {
+ var channelDefaultItems = ["dcblockoutputs", "tanhoutputs", "maxundo"];
+
+ for (var i of channelDefaultItems) {
+ if (self.storage.hasOwnProperty(i)) {
+ app.setControlChannel("twst_" + i, self.storage[i]);
+ }
+ }
+ sr = await app.getCsound().getSr();
+ if (!twine) self.ui.postBoot();
+ };
+
+ var booted = false;
+ this.boot = function(twine) {
+ if (booted) return;
+ booted = true;
+ twirl.boot();
+ self.ui.boot();
+
+ Object.defineProperty(this, "waveformTab", {
+ get: function() { return waveformTabs[instanceIndex]; },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "otherInstanceNames", {
+ get: function() {
+ var data = {};
+ for (var i in waveformTabs) {
+ if (i != instanceIndex) {
+ data[i] = waveformTabs[i].text();
+ }
+ }
+ return data
+ },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "instanceIndex", {
+ get: function() {
+ return instanceIndex
+ },
+ set: function(x) {}
+ });
+
+ Object.defineProperty(this, "undoLevel", {
+ get: function() {
+ return undoLevels[instanceIndex];
+ },
+ set: function(x) {
+ undoLevels[instanceIndex] = x;
+ }
+ });
+
+ Object.defineProperty(this, "waveform", {
+ get: function() { return self.waveforms[instanceIndex]; },
+ set: function(x) {
+ if (instanceIndex != x) {
+ if (self.waveformTab) {
+ self.waveformTab.removeClass("wtab_selected").addClass("wtab_unselected");
+ }
+ if (self.waveform) {
+ self.waveform.hide();
+ }
+ var cbid = app.createCallback(function(ndata){
+ if (ndata.status == 1) {
+ instanceIndex = x;
+ self.waveformTab.removeClass("wtab_unselected").addClass("wtab_selected");
+ self.waveform.show();
+ if (self.currentTransform) {
+ self.currentTransform.refresh();
+ self.currentTransform.redraw(self.waveform.getRegion());
+ }
+ } else {
+ self.ui.showPrompt("Error changing instance");
+ }
+ });
+ app.insertScore("twst_setinstance", [0, 1, cbid, x]);
+
+ }
+ }
+ });
+
+ if (!twine) {
+ $("<td />").text("+").click(function() {
+ self.createNewInstance();
+ }).appendTo("#twist_waveform_tabs").addClass("wtab_selected");
+
+ $("body").on("dragover", function(e) {
+ e.preventDefault();
+ e.originalEvent.dataTransfer.effectAllowed = "all";
+ e.originalEvent.dataTransfer.dropEffect = "copy";
+ return false;
+ }).on("dragleave", function(e) {
+ e.preventDefault();
+ }).on("drop", function(e) {
+ handleFileDrop(e, self);
+ });
+ } else {
+ self.twine = twine;
+ }
+
+ self.loadTransforms();
+ };
+
+}; // end twist
+
+function twist_startisolated() {
+ var csOptions = ["--omacro:TWST_FAILONLAG=1"];
+ window.twist = new Twist();
+ twist.setVisible(true);
+ window.app = new CSApplication({
+ csdUrl: "twist.csd",
+ csOptions: csOptions,
+ onPlay: function () {
+ twist.bootAudio();
+ },
+ errorHandler: twist.errorHandler,
+ ioReceivers: {percent: twist.ui.setPercent}
+ });
+
+ $("#twist_start").click(function() {
+ $(this).hide();
+ twist.boot();
+ twist.ui.setLoadingStatus(true, false, "Preparing audio engine");
+ app.play(function(text){
+ twist.ui.setLoadingStatus(true, false, text);
+ twirl.latencyCorrection = twirl.audioContext.outputLatency * 1000;
+ }, twirl.audioContext);
+ });
+}
+
+
\ No newline at end of file diff --git a/site/app/twist/twist_ui.js b/site/app/twist/twist_ui.js new file mode 100644 index 0000000..08e5fe1 --- /dev/null +++ b/site/app/twist/twist_ui.js @@ -0,0 +1,674 @@ +var twistTopMenuData = [
+ {name: "File", contents: [
+ {name: "New", disableOnPlay: true, shortcut: {name: "Ctrl N", ctrlKey: true, key: "n"}, click: function(twist) {
+ twist.createNewInstance();
+ }, condition: function(twist) {
+ return (!twist.twine);
+ }},
+ {name: "Save", disableOnPlay: true, shortcut: {name: "Ctrl S", ctrlKey: true, key: "s"}, click: function(twist) {
+ twist.saveFile();
+ }},
+ {name: "Close", disableOnPlay: true, shortcut: {name: "Ctrl W", ctrlKey: true, key: "w"}, click: function(twist) {
+ twist.closeInstance();
+ }, condition: function(twist) {
+ return (!twist.twine && twist.waveforms.length != 1);
+ }},
+ {name: "Edit in twigs", click: function(twist) {
+ twist.editInTwigs();
+ }, condition: function(twist) {
+ return window.hasOwnProperty("Twigs");
+ }}
+ ]},
+ {name: "Edit", contents: [
+ {name: "Undo", disableOnPlay: true, shortcut: {name: "Ctrl Z", ctrlKey: true, key: "z"}, click: function(twist) {
+ twist.undo();
+ }, condition: function(twist) {
+ return (twist.storage.maxundo > 0 && twist.undoLevel > 0);
+ }},
+ {preset: "divider"},
+ {name: "Copy", disableOnPlay: true, shortcut: {name: "Ctrl C", ctrlKey: true, key: "c"}, click: function(twist) {
+ twist.copy();
+ }},
+ {name: "Cut", disableOnPlay: true, shortcut: {name: "Ctrl X", ctrlKey: true, key: "x"}, click: function(twist) {
+ twist.cut();
+ }},
+ {name: "Paste", disableOnPlay: true, shortcut: {name: "Ctrl V", ctrlKey: true, key: "v"}, click: function(twist) {
+ twist.paste();
+ }, condition: function(twist) {
+ return twist.hasClipboard;
+ }},
+ {name: "Paste special", disableOnPlay: true, shortcut: {name: "Ctrl shift V", ctrlKey: true, shiftKey: true, key: "v"}, click: function() {
+ twist.pasteSpecial();
+ }, condition: function(twist) {
+ return twist.hasClipboard;
+ }},
+ {name: "Trim", disableOnPlay: true, shortcut: {name: "T", key: "t"}, click: function() {
+ twist.trim();
+ }},
+ {name: "Delete", disableOnPlay: true, shortcut: {name: "Del", key: "delete"}, keyCondition: function(twist) {
+ return !twist.ui.deleteSupressed;
+ }, click: function(twist) {
+ twist.delete();
+ }},
+ {preset: "divider"},
+ {name: "Select all", shortcut: {name: "Ctrl A", ctrlKey: true, key: "a"}, click: function(twist) {
+ twist.selectAll();
+ }},
+ {name: "Select to end", shortcut: {name: "W", key: "w"}, click: function(twist) {
+ twist.selectToEnd();
+ }},
+ {name: "Select from start", shortcut: {name: "Q", key: "q"}, click: function(twist) {
+ twist.selectFromStart();
+ }},
+ {name: "Select none", shortcut: {name: "Ctrl M", ctrlKey: true, key: "m"}, click: function(twist) {
+ twist.selectNone();
+ }},
+ {name: "Move to next transient", shortcut: {name: "[",key: "["}, click: function(twist) {
+ twist.moveToNextTransient();
+ }},
+ {name: "Select to next transient", shortcut: {name: "]",key: "]"}, click: function(twist) {
+ twist.selectToNextTransient();
+ }}
+ ]},
+ {name: "View", contents: [
+ {name: "Zoom selection", shortcut: {name: "Z", key: "z"}, click: function(twist) {
+ twist.waveform.zoomSelection();
+ }},
+ {name: "Zoom in", shortcut: {name: "+", key: "+"}, click: function(twist) {
+ twist.waveform.zoomIn();
+ }},
+ {name: "Zoom out", shortcut: {name: "-", key: "-"}, click: function(twist) {
+ twist.waveform.zoomOut();
+ }},
+ {name: "Show all", shortcut: {name: "0", key: "0"}, click: function(twist) {
+ twist.waveform.setRegion(0, 1);
+ }},
+ {preset: "divider"},
+ {name: "Toggle analysis", click: function(twist){
+ twist.ui.toggleScope();
+ }},
+ {name: "Toggle layout", shortcut: {name: "L", key: "l"}, click: function(twist){
+ twist.ui.toggleLayout();
+ }},
+ ]},
+ {name: "Action", contents: [
+ {name: "Play/stop", shortcut: {name: "Space", key: " "}, click: function(twist) {
+ if (twist.isPlaying()) {
+ twist.stop();
+ } else {
+ twist.play();
+ }
+ }},
+ {name: "Audition", disableOnPlay: true, shortcut: {name: "Enter", key: "enter"}, click: function(twist) {
+ twist.audition();
+ }},
+ {name: "Commit", disableOnPlay: true, shortcut: {name: "Alt enter", altKey: true, key: "enter"}, click: function(twist) {
+ twist.commit();
+ }},
+ {name: "Record", disableOnPlay: true, shortcut: {name: "R", key: "r"}, click: function(twist) {
+ twist.record();
+ }},
+ {preset: "divider"},
+ {name: "Scripting", shortcut: {name: "Ctrl K", ctrlKey: true, key: "k"}, click: function(twist) {
+ twist.ui.scriptEdit();
+ }},
+ {name: "Developer", shortcut: {name: "Ctrl L", ctrlKey: true, key: "l"}, click: function(twist) {
+ twist.ui.developerConsole();
+ }},
+
+ ]},
+ {name: "Transform", contents: [
+ {name: "Randomise", shortcut: {name: "Z", key: "z"}, click: function(twist) {
+ twist.currentTransform.randomise();
+ }, condition: function(twist) {
+ return (twist.currentTransform) ? true : false;
+ }},
+ {name: "Reset", shortcut: {name: "R", key: "r"}, click: function(twist) {
+ twist.currentTransform.reset();
+ }, condition: function(twist) {
+ return (twist.currentTransform) ? true : false;
+ }},
+ {name: "Hide automation", shortcut: {name: "H", key: "h"}, click: function(twist) {
+ twist.currentTransform.hideAllAutomation();
+ }, condition: function(twist) {
+ return (twist.currentTransform) ? true : false;
+ }}
+ ]},
+ {name: "Options", contents: [
+ {name: "Settings", click: function(twist) {
+ twist.ui.showSettings();
+ }}
+ ]},
+ {name: "Help", contents: [
+ {name: "Help", click: function(twist){
+ $("#twist_documentation")[0].click();
+ }},
+ {name: "Developer reference", click: function(twist){
+ $("#twist_developer_documentation")[0].click();
+ }},
+ {name: "Report bug", click: function(twist){
+ $("#twist_reportbug")[0].click();
+ }},
+ {name: "Contact owner", click: function(twist){
+ $("#twist_contact")[0].click();
+ }},
+ {name: "Submit transform code", click: function(twist){
+ $("#twist_developer_submit")[0].click();
+ }},
+ {name: "About", click: function(twist) {
+ twist.ui.showAbout();
+ }},
+ ]},
+];
+
+
+var TwistUI = function(twist) {
+ var self = this;
+ var scope;
+ var elCrossfades = [];
+ var topMenu = new twirl.TopMenu(twist, twistTopMenuData, $("#twist_menubar"));
+ this.deleteSupressed = false;
+
+ this.setPlaying = function(state) {
+ if (scope) {
+ scope.setPlaying(state);
+ }
+ if (state) {
+ $(".twist_scriptbutton").hide();
+ $("#twist_scriptstop").show();
+ } else {
+ $(".twist_scriptbutton").show();
+ $("#twist_scriptstop").hide();
+ }
+ };
+
+ this.getCrossFadeValues = function() {
+ return [elCrossfades[0].val(), elCrossfades[1].val()];
+ };
+
+
+ var contractedWaveform = false;
+ function setLayout() {
+ var elViews = $("#twist_views");
+ var elWave = $("#twist_waveforms");
+ var elSpline = $("#twist_splines");
+ var elScope = $("#twist_analyser");
+ var elControls = $("#twist_controls");
+
+ if (contractedWaveform) {
+ elViews.css({height: "20%"});
+ elControls.css({top: "20%"});
+ } else {
+ elViews.css({height: "50%"});
+ elControls.css({top: "50%"});
+ }
+
+ if (scope) {
+ elScope.css({height: "40%", top: "0px"});
+ elWave.css({top: "40%"});
+ elSpline.css({top: elWave.css("top")});
+ } else {
+ elWave.css({top: "0px"});
+ elSpline.css({top: "0px"});
+ }
+
+ twist.redraw();
+ }
+
+ this.toggleLayout = function() {
+ contractedWaveform = !contractedWaveform;
+ setLayout();
+ };
+
+ this.toggleScope = function(noSaveState) {
+ var state;
+ if (!scope) {
+ state = true;
+ var elScope = $("<div />").addClass("twist_scope").appendTo($("#twist_analyser"));
+ var type = (twist.storage.scopeType) ? twist.storage.scopeType : 0;
+ scope = new Analyser(
+ type, twist, elScope, app
+ );
+ $("#twist_analyser").show();
+ } else {
+ $("#twist_analyser").hide();
+ state = false;
+ scope.remove();
+ delete scope;
+ scope = null;
+ }
+
+ if (!noSaveState) {
+ twist.storage.showScope = state;
+ twist.saveStorage();
+ }
+ setLayout();
+ };
+
+
+ this.tooltip = twirl.tooltip;
+
+ this.boot = function() {
+ if (twist.storage.hasOwnProperty("showShortcuts")) {
+ if (twist.storage.showShortcuts) {
+ $("#twist_wavecontrols_inner").show();
+ } else {
+ $("#twist_wavecontrols_inner").hide();
+ }
+ }
+
+ if (twist.storage.develop) {
+ if (twist.storage.develop.csound) {
+ $("#twist_devcsound").val(twist.storage.develop.csound);
+ }
+ if (twist.storage.develop.json) {
+ $("#twist_devjson").val(twist.storage.develop.json);
+ }
+ }
+ $("#loading_background").css("opacity", 1).animate({opacity: 0.2}, 1000);
+ };
+
+ this.postBoot = function() {
+ self.setLoadingStatus(false);
+
+ if (!twist.storage.hasOwnProperty("firstLoadDone")) {
+ twist.storage.firstLoadDone = true;
+ twist.saveStorage();
+ self.showPrompt($("#twist_welcome").detach().show(), twist.createNewInstance);
+ } else {
+ twist.createNewInstance();
+ }
+
+ if (twist.storage.showScope) {
+ self.toggleScope(true);
+ }
+ };
+
+ this.hidePrompt = function() {
+ twirl.prompt.hide();
+ };
+
+ this.showPrompt = function(text, oncomplete, noButton) {
+ twirl.prompt.show(text, oncomplete, noButton);
+ if (twist.playheadInterval) {
+ twist.waveform.movePlayhead(0);
+ clearInterval(twist.playheadInterval);
+ }
+ if (self.waveform) {
+ self.waveform.cover(false);
+ }
+ };
+
+
+ this.showLoadNewPrompt = function() {
+ var elNewFile = $("<div />").css({"font-size": "var(--fontSizeDefault)"});
+ if (twist.hasClipboard) {
+ $("<button />").text("Create from clipboard").appendTo(elNewFile).click(function(){
+ twist.loadFileFromClipboard();
+ twirl.prompt.hide();
+ });
+ }
+
+ elNewFile.append($("<h3 />").text("Drag an audio file here to load")).append($("<p />").text("or"));
+
+ var elEmpty = $("<div />").appendTo(elNewFile);
+ $("<h4 />").text("Create an empty file").css("cursor", "pointer").appendTo(elEmpty);
+
+ var tpDuration = new twirl.transform.Parameter({
+ definition: {name: "Duration", min: 0.1, max: 60, dfault: 10, automatable: false, fireChanges: false},
+ host: twist
+ });
+
+ var tpChannels = new twirl.transform.Parameter({
+ definition: {name: "Channels", min: 1, max: 2, dfault: 2, step: 1, automatable: false, fireChanges: false},
+ host: twist
+ });
+
+ var tpName = new twirl.transform.Parameter({
+ definition: {name: "Name", type: "string", dfault: "New file", fireChanges: false},
+ host: twist
+ });
+
+ var tb = $("<tbody />");
+ $("<table />").append(tb).css("margin", "0 auto").appendTo(elEmpty);
+ tb.append(tpDuration.getElementRow(true)).append(tpChannels.getElementRow(true)).append(tpName.getElementRow(true));
+
+ $("<button />").text("Create").appendTo(elEmpty).click(function() {
+ twist.createEmpty(tpName.getValue(), tpDuration.getValue(), tpChannels.getValue());
+ });
+
+
+ self.showPrompt(elNewFile, null, true);
+ }
+
+
+ this.setTheme = function(name, nosave) {
+ twirl.setTheme(name, nosave);
+ };
+
+ this.showSettings = function() {
+ var settings = [
+ {
+ name: "Commit history limit",
+ description: "Number of transform states to store (can be accessed via the script editor). 0 = infinite",
+ min: 0, max: 32, step: 1, dfault: 16, storageKey: "commitHistoryLevel"
+ },
+ {
+ name: "Undo levels",
+ description: "Number of undo levels stored. Large numbers may affect memory usage",
+ min: 0, max: 32, step: 1, dfault: 2, storageKey: "maxundo",
+ onChange: function(val) {
+ app.setControlChannel("twst_maxundo", val);
+ }
+ },
+ {
+ name: "Analysis type",
+ description: "Type of analysis to be shown",
+ options: ["Frequency", "Oscilloscope"],
+ dfault: 0,
+ storageKey: "scopeType",
+ onChange: function(val) {
+ if (scope) scope.setType(val);
+ }
+ },
+ {
+ name: "Show shortcuts",
+ description: "Show shortcuts toolbar below waveform",
+ bool: true,
+ storageKey: "showShortcuts",
+ dfault: 1,
+ onChange: function(val) {
+ if (val) {
+ $("#twist_wavecontrols_inner").show();
+ } else {
+ $("#twist_wavecontrols_inner").hide();
+ }
+ }
+ },
+ {
+ name: "DC block processing",
+ description: "Apply DC blocking to all processing",
+ bool: true,
+ storageKey: "dcblockoutputs",
+ dfault: 0,
+ onChange: function(val) {
+ app.setControlChannel("twst_dcblockoutputs", val);
+ }
+ },
+ {
+ name: "Tanh limit all processing",
+ description: "Apply tanh to all processing",
+ bool: true,
+ storageKey: "tanhoutputs",
+ dfault: 0,
+ onChange: function(val) {
+ app.setControlChannel("twst_tanhtanhoutputs", val);
+ }
+ },
+ {
+ name: "Autosave before each commit",
+ description: "Automatically save file locally before each new commit",
+ bool: true,
+ storageKey: "autosave",
+ dfault: 0
+ }
+ ];
+ twirl.showSettings(twist, settings);
+ };
+
+
+ this.setPercent = function(percent) {
+ twist.watchdog.setActive(percent);
+ twirl.loading.setPercent(percent);
+ };
+
+ this.setLoadingStatus = function(state, showpercent, text) {
+ if (state) {
+ twirl.loading.show(text, showpercent);
+ } else {
+ twirl.loading.hide();
+ }
+ };
+
+ this.scriptEdit = function() {
+ var el = $("#twist_script").show();
+ var te = $("#twist_scriptsource");
+
+
+ function runScript(audition) {
+ try {
+ var script = JSON.parse(te.val());
+ } catch (e) {
+ twist.errorHandler("Cannot parse script: " + e);
+ return false;
+ }
+ twist.applyScript(script, audition);
+ return true;
+ };
+
+
+ $("#twist_scriptaudition").unbind().click(function(){
+ runScript(true);
+ });
+
+ $("#twist_scriptstop").unbind().click(function(){
+ twist.stop();
+ });
+
+ $("#twist_scriptcommit").unbind().click(function(){
+ if (runScript(false)) {
+ el.hide();
+ }
+ });
+
+ $("#twist_scriptloadlast").unbind().click(function(){
+ te.val(JSON.stringify(twist.lastOperation(), null, 2));
+ });
+
+ $("#twist_scriptloadall").unbind().click(function(){
+ te.val(JSON.stringify(twist.operationLog, null, 2));
+ });
+
+ $("#twist_scriptcancel").unbind().click(function(){
+ el.hide();
+ });
+ };
+
+ this.developerConsole = function() {
+ $("#twist_developer").show();
+ $("#twist_inject_devcsound").click(async function() {
+ var code = $("#twist_devcsound").val();
+ var result = await app.compileOrc(code);
+ if (result == 0) {
+ if (!twist.storage.develop) {
+ twist.storage.develop = {};
+ }
+ twist.storage.develop.csound = code;
+ twist.saveStorage();
+ self.showPrompt("Successfully injected Csound code");
+ }
+ });
+ $("#twist_inject_devjson").click(async function() {
+ var code = $("#twist_devjson").val();
+ try {
+ var json = JSON.parse(code);
+ } catch (e) {
+ return twist.errorHandler("Cannot parse JSON: " + e);
+ }
+ try {
+ twist.loadTransforms(json);
+ } catch (e) {
+ return twist.errorHandler("Cannot load transform: " + e);
+ }
+ if (!twist.storage.develop) {
+ twist.storage.develop = {};
+ }
+ twist.storage.develop.json = code;
+ twist.saveStorage();
+ self.showPrompt("Successfully injected transform definition");
+ });
+ $("#twist_exit_devcode").click(async function() {
+ $("#twist_developer").hide();
+ });
+ };
+
+ function buildWavecontrols() {
+ var el = $("#twist_wavecontrols_inner");
+ var onPlayDisables = [];
+
+ var play = twirl.createIcon({label: "Play", icon: "play", label2: "Stop", icon2: "stop", click: function(obj){
+ if (twist.isPlaying()) {
+ twist.stop();
+ } else {
+ twist.play();
+ }
+ }});
+ var audition = twirl.createIcon({label: "Audition", icon: "audition", label2: "Stop", icon2: "stop", click: function(obj){
+ if (twist.isPlaying()) {
+ twist.stop();
+ } else {
+ twist.audition();
+ }
+ }});
+
+
+ var record = twirl.createIcon({label: "Record", icon: "record", label2: "Stop", icon2: "stop", click: function() {
+ if (twist.isPlaying()) {
+ twist.stop();
+ } else {
+ twist.record();
+ }
+ }});
+
+ var items = [
+ {label: "Rewind", icon: "rewind", disableOnPlay: true, click: function() { twist.moveToStart() }},
+ play,
+ audition,
+ {label: "Commit", icon: "commit", disableOnPlay: true, click: function() { twist.commit() }},
+ record,
+ {preset: "spacer"},
+ {label: "Cut", icon: "cut", disableOnPlay: true, click: function() { twist.cut() }},
+ {label: "Copy", icon: "copy", disableOnPlay: true, click: function() { twist.copy() }},
+ {label: "Paste", icon: "paste", disableOnPlay: true, click: function() { twist.paste() }},
+ {label: "Paste special", icon: "pasteSpecial", disableOnPlay: true, click: function() { twist.pasteSpecial() }},
+ {label: "Trim", icon: "trim", disableOnPlay: true, click: function() { twist.trim() }},
+ {preset: "spacer"}
+ ];
+
+ for (let i of items) {
+ var icon;
+ var td = $("<td />");
+ if (i.preset && i.preset == "spacer") {
+ td.css("width", "20px");
+ } else {
+ if (i.icon) {
+ icon = twirl.createIcon(i);
+ if (i.disableOnPlay) {
+ onPlayDisables.push(icon);
+ }
+ } else {
+ icon = i;
+ }
+ td.append(icon.el);
+ }
+ td.appendTo(el);
+ }
+
+ twist.onPlays.push(async function(playing, auditioning, recording) {
+ if (playing) {
+ if (auditioning) {
+ play.setActive(false);
+ audition.setState(false);
+ record.setActive(false);
+ } else if (recording) {
+ audition.setActive(false);
+ play.setActive(false);
+ record.setState(false);
+ } else {
+ audition.setActive(false);
+ play.setState(false);
+ record.setActive(false);
+ }
+ } else {
+ audition.setActive(true);
+ play.setActive(true);
+ play.setState(true);
+ audition.setState(true);
+ record.setActive(true);
+ record.setState(true);
+ }
+ for (let o of onPlayDisables) {
+ o.setActive(!playing);
+ }
+ });
+
+ for (let e of ["In", "Out"]) {
+ let elRange = $("<input />").addClass("twirl_slider").attr("type", "range").attr("min", 0).attr("max", 0.45).attr("step", 0.00001).val(0).on("input", function() {
+ if (e == "In") {
+ twist.waveform.crossFadeInRatio = $(this).val();
+ } else {
+ twist.waveform.crossFadeOutRatio = $(this).val();
+ }
+ });
+ elCrossfades.push(elRange);
+ $("<td />").addClass("crossfade").append($("<div />").css("font-size", "var(--fontSizeSmall)").text("Crossfade " + e)).append(elRange).appendTo(el);
+ }
+
+ $("<td />").css("font-size", "var(--fontSizeSmall").append("Loop playback<br />").append(
+ $("<input />").addClass("tp_checkbox").attr("type", "checkbox").change(function(){
+ twist.playbackLoop = $(this).is(":checked");
+ })
+ ).appendTo(el);
+
+ };
+
+ function formatVersion(ver) {
+ ver = ver.toString();
+ var major = ver.substr(0, 1);
+ var remainder = ver.substr(1);
+ if (remainder.length == 2) {
+ return major + "." + remainder;
+ } else {
+ var mid = remainder.substr(1, 2);
+ var minor = remainder.substr(2);
+ return major + "." + mid + "." + minor;
+ }
+ }
+
+ this.showAbout = async function() {
+ var csVer = await app.getCsound().getVersion();
+ var apiVer = await app.getCsound().getAPIVersion();
+ var el = $("<div />");
+ var x = $("<h3 />").text("twist").appendTo(el);
+ $("<p />").css("font-size", "12px").text("By Richard Knight 2024").appendTo(el);
+ $("<p />").text("Version " + twist.version.toFixed(1)).appendTo(el);
+ $("<p />").text("Csound " + formatVersion(csVer) + "; API " + formatVersion(apiVer)).appendTo(el);
+
+ var skewMax = 30;
+ var skew = 0;
+ var skewDirection = true;
+ var twistInterval = setInterval(function(){
+ if (skewDirection) {
+ if (skew < skewMax) {
+ skew ++;
+ } else {
+ skewDirection = false;
+ }
+ } else {
+ if (skew > -skewMax) {
+ skew --;
+ } else {
+ skewDirection = true;
+ }
+ }
+ x.css("transform", "skewX(" + skew + "deg)");
+ }, 10);
+
+ self.showPrompt(el, function(){
+ clearInterval(twistInterval);
+ });
+ };
+
+
+ buildWavecontrols();
+};
\ No newline at end of file diff --git a/site/app/twist/version notes.txt b/site/app/twist/version notes.txt new file mode 100644 index 0000000..462fe92 --- /dev/null +++ b/site/app/twist/version notes.txt @@ -0,0 +1,11 @@ +0.1
+ transient detect movement
+ new transforms
+ feedback
+ convolution feedback
+ instance chopper
+ strobe
+ convolution impulses/preset sound loads
+ source release
+ filter apply mode
+ display csound version
\ No newline at end of file |