gibberwocky
Version:
music sequencing for Live and Max/MSP
1,612 lines (1,300 loc) • 2.78 MB
HTML
<html>
<head>
<meta charset="utf-8">
<title>Gibberwocky</title>
<!-- css_insert_start -->
<style>
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 2px 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-ruler {
border-left: 1px solid #ccc;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
/* Hack to make IE7 behave */
*zoom:1;
*display:inline;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor { position: absolute; }
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
-webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
-moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
.CodeMirror-hint {
margin: 0;
padding: 0 4px;
border-radius: 2px;
max-width: 19em;
overflow: hidden;
white-space: pre;
color: black;
cursor: pointer;
}
li.CodeMirror-hint-active {
background: #08f;
color: white;
}
.vtree ul.vtree-subtree, .vtree li.vtree-leaf {
margin: 0;
padding: 0;
list-style-type: none;
position: relative;
}
.vtree li.vtree-leaf {
background-position: -90px 0;
background-repeat: repeat-y;
min-height: 18px;
line-height: 18px;
}
.vtree li.vtree-leaf::before {
content: '';
width: 18px;
height: 18px;
position: absolute;
background-position: -36px 0;
}
.vtree li.vtree-leaf li.vtree-leaf {
margin-left: 18px;
}
.vtree li.vtree-leaf:last-child {
background-image: none;
}
.vtree li.vtree-leaf.closed ul.vtree-subtree {
display: none;
}
.vtree li.vtree-leaf.vtree-has-children > span.vtree-toggle {
display: block;
width: 18px;
height: 18px;
background-position: -72px 0;
position: absolute;
left: 0;
top: 0;
}
.vtree li.vtree-leaf.vtree-has-children.closed > span.vtree-toggle {
background-position: -54px 0;
}
.vtree a.vtree-leaf-label {
line-height: 18px;
display: inline-block;
vertical-align: top;
cursor: pointer;
max-width: 100%;
margin-left: 18px;
padding: 0 2px;
}
.vtree li.vtree-leaf a.vtree-leaf-label:hover {
background-color: #e7f4f9;
outline: 1px solid #d8f0fa;
}
.vtree li.vtree-leaf.vtree-selected > a.vtree-leaf-label {
background-color: #beebff;
outline: 1px solid #99defd;
}
.vtree-contextmenu {
position: absolute;
z-index: 9999999;
border: solid 1px #ccc;
background: #eee;
padding: 0px;
margin: 0px;
display: none;
}
.vtree-contextmenu li {
list-style: none;
padding: 1px 5px;
margin: 0px;
color: #333;
line-height: 20px;
height: 20px;
cursor: default;
}
.vtree-contextmenu li:hover {
color: #fff;
background-color: #3399ff;
}
.vtree li.vtree-leaf, .vtree li.vtree-leaf::before, .vtree li.vtree-leaf.vtree-has-children > span.vtree-toggle {
background-image: url(data:image/png;base64,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);
}
.microlib_tabs_nav {
width: 100%;
height: 26px;
}
.microlib_tabs_nav_item {
float: left;
height: 26px;
padding: 0 10px;
line-height: 26px;
border-right: 1px solid #000;
border-bottom: 1px solid #000;
}
.microlib_tabs_nav_item:hover,
.microlib_tabs_nav_item.microlib_active {
background: #000;
color:white;
cursor: pointer;
}
.microlib_tabs_tab {
padding: 5px;
display: none;
}
.microlib_tabs_tab.microlib_active {
display: block;
}
.CodeMirror-highlight { background:red !important }
body {
font-family:Menlo, monospace;
font-size:1em;
background:rgba(46,50,53,1);
margin:0; padding:0;
color:rgb( 153 ) !important;
}
#editor {
width:63%;
height:100%;
display:inline-block;
}
/* TODO: fix in max and change width to 30% before publishing. */
#sidebar {
display:inline-block;
width:35%;
float:right;
height:100%;
border-left:1px black solid;
box-sizing:border-box;
overflow:scroll;
font-family:sans-serif;
font-weight:lighter;
font-size:1em
}
.CodeMirror {
font-family: 'Menlo','Source Code Pro', monospace;
font-size: .7em;
background-color:#bbb;
color:#000;
font-weight:500;
}
.CodeMirror {
font-family:Menlo, monospace;
font-size:.8em;
background:rgba(46,50,53,1);
color:rgb( 153 ) !important
}
span.cm-comment { color:rgb(121,121,121) !important }
span.cm-property,
span.cm-attribute,
span.cm-variable,
span.cm-variable-2,
.cm-def,
.cm-s-default { color: rgba(173,173,173,1) !important }
span.cm-keyword,
span.cm-number, span.cm-atom { color:rgba(89, 151, 198, 1) !important }
span.cm-string {color: rgb(225, 225, 225) !important }
.CodeMirror-cursor {
background: rgba(255,255,255,.5);
border: none !important;
width: .5em !important;
display: block;
}
.CodeMirror-selected {
background:rgba(84,84,84,.5) !important;
}
.CodeMirror-highlight {
background:rgba(255,255,255,.5)
}
/*
*#console .CodeMirror { background-color:#444 }
*#editor .CodeMirror {
* background-color:#bbb;
* color:#4a4a4a;
*}
*/
.CodeMirror-matchingbracket{ color: #b00 !important }
.annotation {
/*padding:0px 1px;*/
border:1px solid transparent;
padding:0px;
box-sizing:border-box !important;
}
.annotation-full {
border-color: #999;
}
.annotation-highlight { background-color: #ffffff }
.annotation-border {
/* border-color:#999 !important; */
border-color:#999;
border-width:1px;
border-style:solid
}
.annotation-right-border { border-right-color:#999 }
.annotation-left-border { border-left-color:#999 }
.annotation-top-border { border-top-color:#999 }
.annotation-bottom-border { border-bottom-color:#999 }
.annotation-right-border-cycle { border-right-color:#ddd !important }
.annotation-left-border-cycle { border-left-color:#ddd !important }
.annotation-top-border-cycle { border-top-color:#ddd !important }
.annotation-bottom-border-cycle { border-bottom-color:#ddd !important }
.annotation-no-left-border { border-left-color:transparent !important }
.annotation-no-right-border { border-right-color:transparent !important }
.annotation-border-left {
border-left-color:#999;
}
.annotation-border-right {
border-right-color: #999;
}
.annotation-no-horizontal-border {
/* padding-left:1; */
/* padding-right:1; */
}
.annotation-binop-border {
/*border-color:transparent;*/
border-left-color:transparent !important;
border-right-color:transparent !important;
}
.annotation-array {
border-top-color:#999;
border-bottom-color:#999;
}
.annotation-binop {
border-left-color: transparent !important;
border-right-color: transparent !important;
border-style: solid;
}
.scoreCurrentIndex {
/*border: #700 1px solid */
/*font-weight:bold !important*/
background: rgba(66,70,73,1)
}
.euclid1 {
background:#ddd !important;
color:rgba(46,50,53,1) !important;
}
.euclid0 { background:rgba(96,100,103,1) }
.pattern-update-range-outside { color:#888; }
.pattern-update-range-inside {
/*color:#0f0 !important; */
text-decoration:underline;
}
.vtree-leaf-label {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Chrome/Safari/Opera */
-khtml-user-select: none; /* Konqueror */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
not supported by any browser */
}
.vtree {
font-family:sans-serif;
font-size:.8em;
}
#console {
width:100%;
overflow:scroll;
height: calc( 100% - 4.5em );
color:rgb( 153,153,153 ) !important;
}
#sidebar {
color:rgb( 173,173,173 ) !important;
}
#lomView ul { padding: 0 }
#liveDemosView ul, #maxDemosView ul, #midiDemosView ul { margin:0; padding: 0; list-style:none; cursor:pointer }
#liveDemosView ul li, #maxDemosView ul li, #midiDemosView ul li { margin-bottom: 5px }
#liveDemosView ul li:hover, #maxDemosView ul li:hover, #midiDemosView ul li:hover { background: rgba( 255,255,255, .15) }
#splitbar {
display:inline-block;
top:0;
position:absolute;
height:100%;
width:5px;
background:#666;
cursor: ew-resize
}
#tabs {
display:inline-block;
top:0;
position:relative;
left:5px;
font-size: .8em;
padding-top:0;
box-sizing:border
}
#console_list {
width: 100%;
height:100%;
margin:0;
display: block;
font-family: 'Menlo', 'Source Code Pro', monospace;
list-style: none;
box-sizing:border;
padding:0;
}
#console_list li {
font-size: 1em;
}
.console_error {
color:red;
}
.microlib_tabs_tab {
padding:1em;
padding-top:1.5em;
}
.microlib_tabs_nav_item {
height:26px;
padding:.5em 5px 0px 5px;
line-height:26px;
color:white;
background:black
}
.microlib_tabs_nav_item.microlib_active {
background:rgba(89, 151, 198, .6) !important
}
.vtree{ padding-left: 0 }
.demos .microlib_tabs_nav_item, .demos .microlib_tabs_nav_item.microlib_active {
background:transparent !important;
color:#ccc;
text-decoration:underline;
border:none;
}
.demos .microlib_tabs_nav_item.microlib_active {
color:rgba(109, 171, 238, 1) !important;
}
.schemas .microlib_tabs_nav_item, .schemas .microlib_tabs_nav_item.microlib_active {
background:transparent !important;
color:#ccc;
text-decoration:underline;
border:none;
}
.schemas .microlib_tabs_nav_item.microlib_active {
color:rgba(109, 171, 238, 1) !important;
}
#sidebar select, #sidebar input {
background:#aaa;
margin-bottom:10px;
}
label { margin-bottom:5px; }
#help a {
color: #ddd
}
#help p { max-width: 24em; margin-top:0 }
.demos { padding-left:0 }
</style>
<!-- css_insert_end -->
</head>
<body>
<div id='editor'></div>
<div id='sidebar'>
<div id='splitbar'></div>
<div id='tabs' class='microlib_tabs'>
<div class="microlib_tabs_tab" data-title="console" >
<div id='console'></div>
</div>
<div class="microlib_tabs_tab schemas" data-title="schemas">
<div id='schemaTabs' class='microlib_tabs'>
<div class="microlib_tabs_tab" data-title="lom">
<div id='lomView'></div>
</div>
<div class="microlib_tabs_tab" data-title="mom">
<div id='momView'></div>
</div>
</div>
</div>
<div class="microlib_tabs_tab demos" data-title="demos">
<div id='demoTabs' class='microlib_tabs'>
<div class="microlib_tabs_tab" data-title="live demos">
<div id='liveDemosView'></div>
</div>
<div class="microlib_tabs_tab" data-title="max demos">
<div id='maxDemosView'></div>
</div>
<div class="microlib_tabs_tab" data-title="midi demos">
<div id='midiDemosView'></div>
</div>
</div>
</div>
<div class="microlib_tabs_tab" data-title="config">
<div id='configView'>
<!--<label>cc modulation output rate (in Hz):</label><br>-->
<!--<input id='modulationRate' value=60></input><br>-->
<h4>Clock sync:</h4>
<input type='radio' id='liveSyncRadio' name='sync' checked>Live</input><br>
<input type='radio' id='maxSyncRadio' name='sync'>Max/MSP</input><br>
<input type='radio' id='clockSyncRadio' name='sync'>MIDI Clock</input><br>
<input type='radio' id='internalSyncRadio' name='sync'>Internal</input>
<h4>MIDI I/O</h4>
<label>MIDI input (clock):</label><br><select id='midiInputSelect'></select><br>
<label>MIDI output:</label><br><select id='midiOutputSelect'></select><br>
</div>
</div>
<div class="microlib_tabs_tab" data-title="help" >
<div id="help">
<p>For a complete description of the gibberwocky API,
see the <a href='http://gibberwocky.cc/reference'>gibberwocky reference</a>. Otherwise
the various tutorial are the best place to get started.
</p>
<p>For questions, answers, and announcements try the <a href="http://lurk.org/groups/gibber/">mailing list</a> or
the <a href="https://livecode.slack.com/messages/gibber/">gibber Slack channel</a> for more informal discussion. If you
aren't already a member of the Live Coding Slack group there's a <a href="http://live-code-slack.herokuapp.com">site that
generates automatic invites</a>.
</p>
</div>
</div>
</div>
<!-- js_insert_start -->
<script>
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
const Queue = require( './priorityqueue.js' )
let Gibber = null
let Scheduler = {
currentTime : performance.now(),
queue: new Queue( ( a, b ) => a.time - b.time ),
visualizationTime: {
init:true,
base:0,
phase:0,
},
init( __Gibber ) {
Gibber = __Gibber
window.requestAnimationFrame( this.onAnimationFrame )
},
clear() {
this.queue.data.length = 0
},
add( func, offset, idx ) {
let time = this.currentTime + offset
this.queue.push({ func, time })
return time
},
runSoon( evt ) {
try{
evt.func()
}catch(e) {
console.log( 'annotation error:', e.toString() )
}
},
run( timestamp, dt ) {
let nextEvent = this.queue.peek()
//if( nextEvent === undefined ) return
if( nextEvent !== undefined && this.queue.length > 0 && nextEvent.time <= timestamp ) {
// remove event
this.queue.pop()
setTimeout( ()=> this.runSoon( nextEvent ) )
//try{
// nextEvent.func()
//}catch( e ) {
// console.log( e )
// Gibber.Environment.error( 'annotation error:', e.toString() )
//}
// call recursively
this.run( timestamp )
}
if( Gibber.Environment.codeMarkup.waveform.widgets.dirty === true ) {
Gibber.Environment.codeMarkup.waveform.drawWidgets()
}
},
onAnimationFrame( timestamp ) {
window.requestAnimationFrame( this.onAnimationFrame )
const diff = timestamp - this.currentTime
this.currentTime = timestamp
this.visualizationTime.phase += diff
this.run( timestamp, diff )
},
updateVisualizationTime( ms ) {
if( this.visualizationTime.init === true ) {
this.visualizationTime.base += ms
this.visualizationTime.phase = 0
}else{
this.visualizationTime.init = true
}
},
}
Scheduler.onAnimationFrame = Scheduler.onAnimationFrame.bind( Scheduler )
module.exports = Scheduler
},{"./priorityqueue.js":42}],2:[function(require,module,exports){
const Utility = require( '../../utility.js' )
const $ = Utility.create
module.exports = function( Marker ) {
'use strict'
const ArrayExpression = function( patternNode, state, seq, patternType, container=null, index=0, isLookup=false ) {
if( patternNode.processed === true ) return
const cm = state.cm
const track = seq.object
const patternObject = seq[ patternType ]
const [ patternName, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index )
const cssName = patternName
patternObject.markers = []
if( track.markup === undefined ) Marker.prepareObject( track )
let count = 0
for( let element of patternNode.elements ) {
let cssClassName = patternName + '_' + count,
elementStart = Object.assign( {}, start ),
elementEnd = Object.assign( {}, end ),
marker
elementStart.ch = element.loc.start.column// + Marker.offset.horizontal
elementEnd.ch = element.loc.end.column // + Marker.offset.horizontal
if( element.type === 'BinaryExpression' ) {
marker = cm.markText( elementStart, elementEnd, {
'className': cssClassName + ' annotation',
startStyle: 'annotation-no-right-border',
endStyle: 'annotation-no-left-border',
//inclusiveLeft:true, inclusiveRight:true
})
// create specific border for operator: top, bottom, no sides
const divStart = Object.assign( {}, elementStart )
const divEnd = Object.assign( {}, elementEnd )
divStart.ch += 1
divEnd.ch -= 1
const marker2 = cm.markText( divStart, divEnd, { className:cssClassName + '_binop annotation-binop' })
patternObject.markers.push( marker, marker2 )
}else if (element.type === 'UnaryExpression' ) {
marker = cm.markText( elementStart, elementEnd, {
'className': cssClassName + ' annotation',
//inclusiveLeft: true,
//inclusiveRight: true
})
let start2 = Object.assign( {}, elementStart )
start2.ch += 1
let marker2 = cm.markText( elementStart, start2, {
'className': cssClassName + ' annotation-no-right-border',
//inclusiveLeft: true,
//inclusiveRight: true
})
let marker3 = cm.markText( start2, elementEnd, {
'className': cssClassName + ' annotation-no-left-border',
//inclusiveLeft: true,
//inclusiveRight: true
})
patternObject.markers.push( marker, marker2, marker3 )
}else if( element.type === 'ArrayExpression' ) {
marker = cm.markText( elementStart, elementEnd, {
'className': cssClassName + ' annotation',
//inclusiveLeft:true, inclusiveRight:true,
startStyle:'annotation-left-border-start',
endStyle: 'annotation-right-border-end',
})
// mark opening array bracket
const arrayStart_start = Object.assign( {}, elementStart )
const arrayStart_end = Object.assign( {}, elementStart )
arrayStart_end.ch += 1
cm.markText( arrayStart_start, arrayStart_end, { className:cssClassName + '_start' })
// mark closing array bracket
const arrayEnd_start = Object.assign( {}, elementEnd )
const arrayEnd_end = Object.assign( {}, elementEnd )
arrayEnd_start.ch -=1
const marker2 = cm.markText( arrayEnd_start, arrayEnd_end, { className:cssClassName + '_end' })
patternObject.markers.push( marker, marker2 )
}else{
marker = cm.markText( elementStart, elementEnd, {
'className': cssClassName + ' annotation',
//inclusiveLeft:true, inclusiveRight:true
})
patternObject.markers.push( marker )
}
if( track.markup.textMarkers[ patternName ] === undefined ) track.markup.textMarkers[ patternName ] = []
track.markup.textMarkers[ patternName ][ count ] = marker
if( track.markup.cssClasses[ patternName ] === undefined ) track.markup.cssClasses[ patternName ] = []
track.markup.cssClasses[ patternName ][ count ] = cssClassName
count++
}
let highlighted = { className:null, isArray:false },
cycle = Marker._createBorderCycleFunction( patternName, patternObject )
patternObject.patternType = patternType
patternObject.patternName = patternName
patternObject.update = () => {
let className = '.' + patternName
className += '_' + patternObject.update.currentIndex
if( highlighted.className !== className ) {
// remove any previous annotations for this pattern
if( highlighted.className !== null ) {
if( highlighted.isArray === false && highlighted.className ) {
$( highlighted.className ).remove( 'annotation-border' )
}else{
$( highlighted.className ).remove( 'annotation-array' )
$( highlighted.className + '_start' ).remove( 'annotation-border-left' )
$( highlighted.className + '_end' ).remove( 'annotation-border-right' )
if( $( highlighted.className + '_binop' ).length > 0 ) {
$( highlighted.className + '_binop' ).remove( 'annotation-binop-border' )
}
}
}
// add annotation for current pattern element
const values = isLookup === false ? patternObject.values : patternObject._values
if( Array.isArray( values[ patternObject.update.currentIndex ] ) ) {
$( className ).add( 'annotation-array' )
$( className + '_start' ).add( 'annotation-border-left' )
$( className + '_end' ).add( 'annotation-border-right' )
highlighted.isArray = true
}else{
$( className ).add( 'annotation-border' )
if( $( className + '_binop' ).length > 0 ) {
$( className + '_binop' ).add( 'annotation-binop-border' )
}
highlighted.isArray = false
}
highlighted.className = className
cycle.clear()
}else{
cycle()
}
}
// check to see if a clear function already exists and save reference
// XXX should clear be saved somewhere else... on the update function?
let __clear = null
if( patternObject.clear !== undefined ) __clear = patternObject.clear
patternObject.clear = () => {
if( highlighted.className !== null ) { $( highlighted.className ).remove( 'annotation-border' ) }
cycle.clear()
patternObject.markers.forEach( marker => marker.clear() )
if( __clear !== null ) __clear()
}
Marker._addPatternFilter( patternObject )
patternObject._onchange = () => { Marker._updatePatternContents( patternObject, patternName, track ) }
}
return ArrayExpression
}
},{"../../utility.js":49}],3:[function(require,module,exports){
module.exports = function( Marker ) {
'use strict'
// 1/4, 1/8 etc.
const BinaryExpression = function( patternNode, state, seq, patternType,container=null, index=0 ) {
if( patternNode.processed === true ) return
const cm = state.cm
const seqTarget = seq.object
const patternObject = seq[ patternType ]
const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index )
const cssName = className
const marker = cm.markText(
start,
end,
{
'className': cssName + ' annotation annotation-border' ,
startStyle: 'annotation-no-right-border',
endStyle: 'annotation-no-left-border',
//inclusiveLeft:true,
//inclusiveRight:true
}
)
if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget )
seqTarget.markup.textMarkers[ className ] = marker
const divStart = Object.assign( {}, start )
const divEnd = Object.assign( {}, end )
divStart.ch += 1
divEnd.ch -= 1
const marker2 = cm.markText( divStart, divEnd, { className:'annotation-binop-border' })
if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = []
seqTarget.markup.cssClasses[ className ][ index ] = cssName
patternObject.marker = marker
Marker.finalizePatternAnnotation( patternObject, className, seqTarget, marker )
}
return BinaryExpression
}
},{}],4:[function(require,module,exports){
module.exports = function( Marker ) {
'use strict'
// CallExpression denotes an array (or other object) that calls a method, like .rnd()
// could also represent an anonymous function call, like Rndi(19,40)
const CallExpression = function( patternNode, state, seq, patternType, index=0 ) {
if( patternNode.processed === true ) return
var args = Array.prototype.slice.call( arguments, 0 )
if( patternNode.callee.type === 'MemberExpression' && patternNode.callee.object.type === 'ArrayExpression' ) {
args[ 0 ] = patternNode.callee.object
args[ 0 ].offset = Marker.offset
Marker.patternMarkupFunctions.ArrayExpression( ...args )
} else if (patternNode.callee.type === 'Identifier' ) {
// function like Euclid or gen~d
Marker.patternMarkupFunctions.Identifier( ...args )
}
}
return CallExpression
}
},{}],5:[function(require,module,exports){
const __Identifier = function( Marker ) {
const mark = function( node, state, patternType, seqNumber ) {
const [ className, start, end ] = Marker._getNamesAndPosition( node, state, patternType, seqNumber )
const cssName = className + '_' + seqNumber
const commentStart = end
// we define the comment range as being one character, this
// only defines the range of characters that will be replaced
// by the eventual longer comment string.
const commentEnd = Object.assign( {}, commentStart )
commentEnd.ch += 1
const line = end.line
const lineTxt = state.cm.getLine( line )
let ch = end.ch
// for whatever reason, sometimes the ch value leads to
// an undefined final character in the string. In that case,
// work back until we find the actual final character.
let lastChar = lineTxt[ ch ]
while( lastChar === undefined ) {
ch--
lastChar = lineTxt[ ch ]
}
// different replacements are used for use in sequencers, when a callexpression
// creating a wavepattern is often followed by a comma, vs when a wavepattern is
// assigned to a variable, when no comma is present
if( lastChar === ',' ) {
state.cm.replaceRange( ' ,', { line, ch:ch }, { line, ch:ch + 1 } )
}else if( lastChar === ')' ){
state.cm.replaceRange( ') ', { line, ch:ch }, { line, ch:ch + 1 } )
}else{
state.cm.replaceRange( lastChar + ' ', { line, ch:ch }, { line, ch:ch + 1 } )
}
const marker = state.cm.markText( commentStart, commentEnd, { className })
return [ marker, className ]
}
// Typically this is used with named functions. For example, if you store an
// Arp in the variable 'a' and pass 'a' into a sequence, 'a' is the Identifier
// and this function will be called to mark up the associated pattern.
const Identifier = function( patternNode, state, seq, patternType, containerNode, seqNumber ) {
if( patternNode.processed === true ) return
const cm = state.cm
const track = seq.object
const patternObject = seq[ patternType ]
const [ marker, className ] = mark( patternNode, state, patternType, seqNumber )
// WavePatterns can also be passed as named functions; make sure we forward
// these to the appropriate markup functions
if( patternObject.type === 'WavePattern' || patternObject.isGen ) { //|| patternObject.type === 'Lookup' ) {
if( patternObject.widget === undefined ) { // if wavepattern is inlined to .seq
Marker.processGen( containerNode, cm, track, patternObject, seq )
}else{
patternObject.update = Marker.patternUpdates.anonymousFunction( patternObject, marker, className, cm, track )
}
}else{
let updateName = typeof patternNode.callee !== 'undefined' ? patternNode.callee.name : patternNode.name
// this doesn't work for variables storing lookups, as there's no array to highlight
// if( patternObject.type === 'Lookup' ) updateName = 'Lookup'
if( Marker.patternUpdates[ updateName ] ) {
if( updateName !== 'Lookup' ) {
patternObject.update = Marker.patternUpdates[ updateName ]( patternObject, marker, className, cm, track, patternNode )
}else{
Marker.patternUpdates[ updateName ]( patternObject, marker, className, cm, track, patternNode, patternType, seqNumber )
}
} else {
patternObject.update = Marker.patternUpdates.anonymousFunction( patternObject, marker, className, cm, track )
}
patternObject.patternName = className
// store value changes in array and then pop them every time the annotation is updated
patternObject.update.value = []
if( updateName !== 'Lookup' )
Marker._addPatternFilter( patternObject )
}
patternObject.marker = marker
}
return Identifier
}
module.exports = __Identifier
},{}],6:[function(require,module,exports){
module.exports = function( Marker ) {
// Marker.patternMarkupFunctions[ valuesNode.type ]( valuesNode, state, seq, 'values', container, seqNumber )
const Literal = function( patternNode, state, seq, patternType, container=null, index=0 ) {
if( patternNode.processed === true ) return
const cm = state.cm
const seqTarget = seq.object
const patternObject = seq[ patternType ]
const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index )
const cssName = className
const marker = cm.markText( start, end, {
'className': cssName + ' annotation-border',
//inclusiveLeft: true,
//inclusiveRight: true
})
if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget )
seqTarget.markup.textMarkers[ className ] = marker
if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = []
seqTarget.markup.cssClasses[ className ][ index ] = cssName
patternObject.marker = marker
Marker.finalizePatternAnnotation( patternObject, className, seqTarget, marker )
}
return Literal
}
},{}],7:[function(require,module,exports){
module.exports = function( Marker ) {
// for negative literals e.g. -10
const UnaryExpression = function( patternNode, state, seq, patternType, container=null, index=0 ) {
if( patternNode.processed === true ) return
const cm = state.cm
const seqTarget = seq.object
const patternObject = seq[ patternType ]
const [ className, start, end ] = Marker._getNamesAndPosition( patternNode, state, patternType, index )
const cssName = className
marker = cm.markText( start, end, {
'className': cssName + ' annotation',
//inclusiveLeft: true,
//inclusiveRight: true
})
if( seqTarget.markup === undefined ) Marker.prepareObject( seqTarget )
seqTarget.markup.textMarkers[ className ] = marker
if( seqTarget.markup.cssClasses[ className ] === undefined ) seqTarget.markup.cssClasses[ className ] = []
seqTarget.markup.cssClasses[ className ][ index ] = cssName
let start2 = Object.assign( {}, start )
start2.ch += 1
let marker2 = cm.markText( start, start2, {
'className': cssName + ' annotation-no-right-border',
//inclusiveLeft: true,
//inclusiveRight: true
})
let marker3 = cm.markText( start2, end, {
'className': cssName + ' annotation-no-left-border',
//inclusiveLeft: true,
//inclusiveRight: true
})
patternObject.marker = marker
Marker.finalizePatternAnnotation( patternObject, className )
}
return UnaryExpression
}
},{}],8:[function(require,module,exports){
const Utility = require( '../../utility.js' )
const $ = Utility.create
const EuclidAnnotation = require( '../update/euclidAnnotation.js' )
module.exports = function( node, cm, track, objectName, state, cb ) {
const Marker = Gibber.Environment.codeMarkup
const steps = node.arguments[ 0 ].properties
const Identifier = Marker.patternMarkupFunctions.Identifier
track.markup.textMarkers[ 'step' ] = []
track.markup.textMarkers[ 'step' ].children = []
const hexSteps = window[ objectName ]
const objectClassName = objectName + '_steps'
let count = 0
for( let key in steps ) {
let step = steps[ key ].value
if( step && step.value ) { // ensure it is a correctly formed step
step.loc.start.line += Marker.offset.vertical - 1
step.loc.end.line += Marker.offset.vertical - 1
step.loc.start.ch = step.loc.end.column - 1
step.loc.end.ch = step.loc.end.column
const pattern = hexSteps.seqs[ steps[ key ].key.value ].timings
// we estimate whether or not a comma was used to separate between
// key / value pairs. If there's more than one pattern and this
// isn't the last time through the for loop, we assume there is a
// comma (otherwise an error would occur).
const useComma = count++ != steps.length - 1 && steps.length > 1
if( useComma === true ) {
// move off of end quote to comma
step.loc.start.ch += 1
step.loc.end.ch += 1
// replace comma with a comma and a space
cm.replaceRange( ", ", step.loc.start, step.loc.end )
step.loc.start.ch += 1
step.loc.end.ch += 1
}else{
// replace end quote with a quote and a space
cm.replaceRange( "' ", step.loc.start, step.loc.end )
step.loc.start.ch += 1
step.loc.end.ch += 1
}
let className = objectClassName + '_' + key
let marker = cm.markText( step.loc.start, step.loc.end, { className } )
pattern.update = EuclidAnnotation( pattern, marker, className, cm, track )
pattern.patternName = className
// store value changes in array and then pop them every time the annotation is updated
pattern.update.value = []
Marker._addPatternFilter( pattern )
pattern.marker = marker
/*
patternObject._onchange = () => {
let delay = Utility.beatsToMs( 1, Gibber.Scheduler.bpm )
Gibber.Environment.animationScheduler.add( () => {
marker.doc.replaceRange( patternObject.values.join(''), step.loc.start, step.loc.end )
mark( step, key, cm, track )
}, delay )
}
*/
}
}
}
},{"../../utility.js":49,"../update/euclidAnnotation.js":13}],9:[function(require,module,exports){
const Utility = require( '../../utility.js' )
const $ = Utility.create
module.exports = function( node, cm, track, objectName, vOffset=0 ) {
let timelineNodes = node.arguments[ 0 ].elements
//console.log( timelineNodes )
track.markup.textMarkers[ 'score' ] = []
for( let i = 0; i < timelineNodes.length; i+=2 ) {
let timeNode = timelineNodes[ i ],
functionNode = timelineNodes[ i + 1 ]
functionNode.loc.start.line += vOffset - 1
functionNode.loc.end.line += vOffset - 1
functionNode.loc.start.ch = functionNode.loc.start.column
functionNode.loc.end.ch = functionNode.loc.end.column
let marker = cm.markText( functionNode.loc.start, functionNode.loc.end, { className:`score${i/2}` } )
track.markup.textMarkers[ 'score' ][ i/2 ] = marker
}
let lastClass = 'score0'
$( '.' + lastClass ).add( 'scoreCurrentIndex' )
// TODO: global object usage is baaaad methinks?
window[ objectName ].onadvance = ( idx ) => {
$( '.' + lastClass ).remove( 'scoreCurrentIndex' )
lastClass = `score${idx}`
$( '.' + lastClass ).add( 'scoreCurrentIndex' )
}
}
},{"../../utility.js":49}],10:[function(require,module,exports){
const Utility = require( '../../utility.js' )
const $ = Utility.create
module.exports = function( node, cm, track, objectName, state, cb ) {
const Marker = Gibber.Environment.codeMarkup // tsk tsk tsk global...
const steps = node.arguments[ 0 ].properties
track.markup.textMarkers[ 'step' ] = []
track.markup.textMarkers[ 'step' ].children = []
const mark = ( _step, _key, _cm, _track ) => {
for( let i = 0; i < _step.value.length; i++ ) {
let pos = { loc:{ start:{}, end:{}} }
Object.assign( pos.loc.start, _step.loc.start )
Object.assign( pos.loc.end , _step.loc.end )
pos.loc.start.ch += i
pos.loc.end.ch = pos.loc.start.ch + 1
let posMark = _cm.markText( pos.loc.start, pos.loc.end, { className:`step_${_key}_${i}` })
_track.markup.textMarkers.step[ _key ].pattern[ i ] = posMark
}
}
for( let key in steps ) {
let step = steps[ key ].value
if( step && step.value ) { // ensure it is a correctly formed step
step.loc.start.line += Marker.offset.vertical - 1
step.loc.end.line += Marker.offset.vertical - 1
step.loc.start.ch = step.loc.start.column + 1
step.loc.end.ch = step.loc.end.column - 1
let marker = cm.markText( step.loc.start, step.loc.end, { className:`step${key}` } )
track.markup.textMarkers.step[ key ] = marker
track.markup.textMarkers.step[ key ].pattern = []
mark( step, key, cm, track )
let count = 0, span, update,
_key = steps[ key ].key.value,
patternObject = window[ objectName ].seqs[ _key ].values
update = () => {
let currentIdx = update.currentIndex // count++ % step.value.length
if( span !== undefined ) {
span.remove( 'euclid0' )
span.remove( 'euclid1' )
}
let spanName = `.step_${key}_${currentIdx}`,
currentValue = patternObject.update.value.pop() //step.value[ currentIdx ]
span = $( spanName )
if( currentValue !== Gibber.Seq.DO_NOT_OUTPUT ) {
span.add( 'euclid1' )
setTimeout( ()=> { span.remove( 'euclid1' ) }, 50 )
}
span.add( 'euclid0' )
}
patternObject._onchange = () => {
let delay = Utility.beatsToMs( 1, Gibber.Scheduler.bpm )
Gibber.Environment.animationScheduler.add( () => {
marker.doc.replaceRange( patternObject.values.join(''), step.loc.start, step.loc.end )
mark( step, key, cm, track )
}, delay )
}
patternObject.update = update
patternObject.update.value = []
Marker._addPatternFilter( patternObject )
}
}
}
},{"../../utility.js":49}],11:[function(require,module,exports){
module.exports = ( patternObject, marker, className, cm ) => {
patternObject.commentMarker = marker
let update = () => {
if( !patternObject.commentMarker ) return
let patternValue = '' + patternObject.update.value.pop()
if( patternValue.length > 8 ) patternValue = patternValue.slice(0,8)
let val ='/* ' + patternValue + ' */',
pos = patternObject.commentMarker.find(),
end = Object.assign( {}, pos.to )
//pos.from.ch += 1
end.ch = pos.from.ch + val.length
//pos.from.ch += 1
cm.replace