music21j-port
Version:
A toolkit for computer-aided musicology, Javascript version
1,073 lines (902 loc) • 29.2 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Music21j Source: music21/duration.js</title>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">
<link type="text/css" rel="stylesheet" href="styles/site.spruce.css">
</head>
<body>
<div class="container-fluid">
<div class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<a class="brand" href="index.html">Music21j</a>
<ul class="nav">
<li class="dropdown">
<a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b
class="caret"></b></a>
<ul class="dropdown-menu ">
<li>
<a href="music21.html">music21</a>
</li>
<li>
<a href="music21.articulations.html">music21.articulations</a>
</li>
<li>
<a href="music21.audioSearch.html">music21.audioSearch</a>
</li>
<li>
<a href="music21.base.html">music21.base</a>
</li>
<li>
<a href="music21.beam.html">music21.beam</a>
</li>
<li>
<a href="music21.chord.html">music21.chord</a>
</li>
<li>
<a href="music21.clef.html">music21.clef</a>
</li>
<li>
<a href="music21.common.html">music21.common</a>
</li>
<li>
<a href="music21.duration.html">music21.duration</a>
</li>
<li>
<a href="music21.dynamics.html">music21.dynamics</a>
</li>
<li>
<a href="music21.expressions.html">music21.expressions</a>
</li>
<li>
<a href="music21.fromPython.html">music21.fromPython</a>
</li>
<li>
<a href="music21.instrument.html">music21.instrument</a>
</li>
<li>
<a href="music21.interval.html">music21.interval</a>
</li>
<li>
<a href="music21.key.html">music21.key</a>
</li>
<li>
<a href="music21.keyboard.html">music21.keyboard</a>
</li>
<li>
<a href="music21.meter.html">music21.meter</a>
</li>
<li>
<a href="music21.miditools.html">music21.miditools</a>
</li>
<li>
<a href="music21.note.html">music21.note</a>
</li>
<li>
<a href="music21.pitch.html">music21.pitch</a>
</li>
<li>
<a href="music21.prebase.html">music21.prebase</a>
</li>
<li>
<a href="music21.renderOptions.html">music21.renderOptions</a>
</li>
<li>
<a href="music21.roman.html">music21.roman</a>
</li>
<li>
<a href="music21.scale.html">music21.scale</a>
</li>
<li>
<a href="music21.sites.html">music21.sites</a>
</li>
<li>
<a href="music21.stream.html">music21.stream</a>
</li>
<li>
<a href="music21.tempo.html">music21.tempo</a>
</li>
<li>
<a href="music21.tie.html">music21.tie</a>
</li>
<li>
<a href="music21.tinyNotation.html">music21.tinyNotation</a>
</li>
<li>
<a href="music21.vfShow.html">music21.vfShow</a>
</li>
<li>
<a href="music21.webmidi.html">music21.webmidi</a>
</li>
</ul>
</li>
<li class="dropdown">
<a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b
class="caret"></b></a>
<ul class="dropdown-menu ">
<li>
<a href="music21.articulations.Accent.html">music21.articulations.Accent</a>
</li>
<li>
<a href="music21.articulations.Articulation.html">music21.articulations.Articulation</a>
</li>
<li>
<a href="music21.articulations.DynamicArticulation.html">music21.articulations.DynamicArticulation</a>
</li>
<li>
<a href="music21.articulations.LengthArticulation.html">music21.articulations.LengthArticulation</a>
</li>
<li>
<a href="music21.articulations.Marcato.html">music21.articulations.Marcato</a>
</li>
<li>
<a href="music21.articulations.PitchArticulation.html">music21.articulations.PitchArticulation</a>
</li>
<li>
<a href="music21.articulations.Spiccato.html">music21.articulations.Spiccato</a>
</li>
<li>
<a href="music21.articulations.Staccatissimo.html">music21.articulations.Staccatissimo</a>
</li>
<li>
<a href="music21.articulations.Staccato.html">music21.articulations.Staccato</a>
</li>
<li>
<a href="music21.articulations.StrongAccent.html">music21.articulations.StrongAccent</a>
</li>
<li>
<a href="music21.articulations.Tenuto.html">music21.articulations.Tenuto</a>
</li>
<li>
<a href="music21.articulations.TimbreArticulation.html">music21.articulations.TimbreArticulation</a>
</li>
<li>
<a href="music21.base.Music21Object.html">music21.base.Music21Object</a>
</li>
<li>
<a href="music21.beam.Beam.html">music21.beam.Beam</a>
</li>
<li>
<a href="music21.beam.Beams.html">music21.beam.Beams</a>
</li>
<li>
<a href="music21.chord.Chord.html">music21.chord.Chord</a>
</li>
<li>
<a href="music21.clef.AltoClef.html">music21.clef.AltoClef</a>
</li>
<li>
<a href="music21.clef.BassClef.html">music21.clef.BassClef</a>
</li>
<li>
<a href="music21.clef.Clef.html">music21.clef.Clef</a>
</li>
<li>
<a href="music21.clef.MezzoSopranoClef.html">music21.clef.MezzoSopranoClef</a>
</li>
<li>
<a href="music21.clef.PercussionClef.html">music21.clef.PercussionClef</a>
</li>
<li>
<a href="music21.clef.SopranoClef.html">music21.clef.SopranoClef</a>
</li>
<li>
<a href="music21.clef.TenorClef.html">music21.clef.TenorClef</a>
</li>
<li>
<a href="music21.clef.Treble8vaClef.html">music21.clef.Treble8vaClef</a>
</li>
<li>
<a href="music21.clef.Treble8vbClef.html">music21.clef.Treble8vbClef</a>
</li>
<li>
<a href="music21.clef.TrebleClef.html">music21.clef.TrebleClef</a>
</li>
<li>
<a href="music21.duration.Duration.html">music21.duration.Duration</a>
</li>
<li>
<a href="music21.duration.Tuplet.html">music21.duration.Tuplet</a>
</li>
<li>
<a href="music21.dynamics.Dynamic.html">music21.dynamics.Dynamic</a>
</li>
<li>
<a href="music21.expressions.Expression.html">music21.expressions.Expression</a>
</li>
<li>
<a href="music21.expressions.Fermata.html">music21.expressions.Fermata</a>
</li>
<li>
<a href="music21.fromPython.Converter.html">music21.fromPython.Converter</a>
</li>
<li>
<a href="music21.instrument.Instrument.html">music21.instrument.Instrument</a>
</li>
<li>
<a href="music21.interval.ChromaticInterval.html">music21.interval.ChromaticInterval</a>
</li>
<li>
<a href="music21.interval.DiatonicInterval.html">music21.interval.DiatonicInterval</a>
</li>
<li>
<a href="music21.interval.GenericInterval.html">music21.interval.GenericInterval</a>
</li>
<li>
<a href="music21.interval.Interval.html">music21.interval.Interval</a>
</li>
<li>
<a href="music21.key.Key.html">music21.key.Key</a>
</li>
<li>
<a href="music21.key.KeySignature.html">music21.key.KeySignature</a>
</li>
<li>
<a href="music21.keyboard.BlackKey.html">music21.keyboard.BlackKey</a>
</li>
<li>
<a href="music21.keyboard.Key.html">music21.keyboard.Key</a>
</li>
<li>
<a href="music21.keyboard.Keyboard.html">music21.keyboard.Keyboard</a>
</li>
<li>
<a href="music21.keyboard.WhiteKey.html">music21.keyboard.WhiteKey</a>
</li>
<li>
<a href="music21.meter.TimeSignature.html">music21.meter.TimeSignature</a>
</li>
<li>
<a href="music21.miditools.Event.html">music21.miditools.Event</a>
</li>
<li>
<a href="music21.miditools.MidiPlayer.html">music21.miditools.MidiPlayer</a>
</li>
<li>
<a href="music21.note.GeneralNote.html">music21.note.GeneralNote</a>
</li>
<li>
<a href="music21.note.Lyric.html">music21.note.Lyric</a>
</li>
<li>
<a href="music21.note.Note.html">music21.note.Note</a>
</li>
<li>
<a href="music21.note.NotRest.html">music21.note.NotRest</a>
</li>
<li>
<a href="music21.note.Rest.html">music21.note.Rest</a>
</li>
<li>
<a href="music21.pitch.Accidental.html">music21.pitch.Accidental</a>
</li>
<li>
<a href="music21.pitch.Pitch.html">music21.pitch.Pitch</a>
</li>
<li>
<a href="music21.prebase.ProtoM21Object.html">music21.prebase.ProtoM21Object</a>
</li>
<li>
<a href="music21.renderOptions.RenderOptions.html">music21.renderOptions.RenderOptions</a>
</li>
<li>
<a href="music21.roman.RomanNumeral.html">music21.roman.RomanNumeral</a>
</li>
<li>
<a href="music21.stream.Measure.html">music21.stream.Measure</a>
</li>
<li>
<a href="music21.stream.Part.html">music21.stream.Part</a>
</li>
<li>
<a href="music21.stream.Score.html">music21.stream.Score</a>
</li>
<li>
<a href="music21.stream.Stream.html">music21.stream.Stream</a>
</li>
<li>
<a href="music21.stream.Voice.html">music21.stream.Voice</a>
</li>
<li>
<a href="music21.tempo.Metronome.html">music21.tempo.Metronome</a>
</li>
<li>
<a href="music21.tie.Tie.html">music21.tie.Tie</a>
</li>
<li>
<a href="music21.vfShow.Renderer.html">music21.vfShow.Renderer</a>
</li>
<li>
<a href="music21.vfShow.RenderStack.html">music21.vfShow.RenderStack</a>
</li>
<li>
<a href="Notation.html">Notation</a>
</li>
<li>
<a href="Page.html">Page</a>
</li>
<li>
<a href="Recorder.html">Recorder</a>
</li>
</ul>
</li>
<li class="dropdown">
<a href="global.html" class="dropdown-toggle" data-toggle="dropdown">Global<b
class="caret"></b></a>
<ul class="dropdown-menu ">
<li>
<a href="global.html#getM21attribute">getM21attribute</a>
</li>
<li>
<a href="global.html#layout">layout</a>
</li>
<li>
<a href="global.html#midiNumDiffFromFrequency">midiNumDiffFromFrequency</a>
</li>
<li>
<a href="global.html#recorderWorkerJs">recorderWorkerJs</a>
</li>
<li>
<a href="global.html#unpickler">unpickler</a>
</li>
<li>
<a href="global.html#warnBanner">warnBanner</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<div id="main">
<h1 class="page-title">Source: music21/duration.js</h1>
<section>
<article>
<pre
class="sunlight-highlight-javascript linenums">/**
* music21j -- Javascript reimplementation of Core music21 features.
* music21/duration -- duration routines
*
* Copyright (c) 2013-16, Michael Scott Cuthbert and cuthbertLab
* Based on music21, Copyright (c) 2006-18, Michael Scott Cuthbert and cuthbertLab
*
*/
import { Music21Exception } from './exceptions21.js';
import { common } from './common.js';
import { debug } from './debug.js';
import { prebase } from './prebase.js';
/**
* Duration module. See {@link music21.duration}
*
* @requires music21/common
* @requires music21/prebase
* @exports music21/duration
*/
/**
* Module that holds **music21** classes and
* tools for dealing with durations, especially
* the {@link music21.duration.Duration} class.
*
* @namespace music21.duration
* @memberof music21
*/
export const duration = {};
/**
* Object mapping int to name, as in `{1: 'whole'}` etc.
*
* @memberof music21.duration
* @type {Object}
*/
duration.typeFromNumDict = {
1: 'whole',
2: 'half',
4: 'quarter',
8: 'eighth',
16: '16th',
32: '32nd',
64: '64th',
128: '128th',
256: '256th',
512: '512th',
1024: '1024th',
0: 'zero',
'0.5': 'breve',
'0.25': 'longa',
'0.125': 'maxima',
'0.0625': 'duplex-maxima',
};
duration.quarterTypeIndex = 6; // where is quarter in the following array.
duration.ordinalTypeFromNum = [
'duplex-maxima',
'maxima',
'longa',
'breve',
'whole',
'half',
'quarter',
'eighth',
'16th',
'32nd',
'64th',
'128th',
'256th',
'512th',
'1024th',
];
duration.vexflowDurationArray = [
undefined,
undefined,
undefined,
undefined,
'w',
'h',
'q',
'8',
'16',
'32',
undefined,
undefined,
undefined,
undefined,
undefined,
];
/**
* Duration object; found as the `.duration` attribute on {@link music21.base.Music21Object} instances
* such as {@link music21.note.Note}
*
* @class Duration
* @memberof music21.duration
* @extends music21.prebase.ProtoM21Object
* @param {(number|undefined)} ql - quarterLength (default 1.0)
*/
export class Duration extends prebase.ProtoM21Object {
constructor(ql) {
super();
this._quarterLength = 0.0;
this._dots = 0;
this._durationNumber = undefined;
this._type = 'zero';
this._tuplets = [];
if (typeof ql === 'string') {
this.type = ql;
} else if (ql !== undefined) {
this.quarterLength = ql;
}
this._cloneCallbacks._tuplets = this.cloneCallbacksTupletFunction;
}
/**
* Read or sets the number of dots on the duration.
*
* Updates the quarterLength
*
* @type Number
* @instance
* @default 0
* @memberof music21.duration.Duration
* @example
* var d = new music21.duration.Duration(2);
* d.dots === 0; // true
* d.dots = 1;
* d.quarterLength == 3; // true;
*/
get dots() {
return this._dots;
}
set dots(numDots) {
this._dots = numDots;
this.updateQlFromFeatures();
}
/**
* Read or sets the quarterLength of the Duration
*
* Updates the type, dots, tuplets(?)
*
* @type Number
* @instance
* @default 1.0
* @memberof music21.duration.Duration
* @example
* var d = new music21.duration.Duration(2);
* d.quarterLength == 2.0; // true;
* d.quarterLength = 1.75;
* d.dots == 2; // true
* d.type == 'quarter'; // true
*/
get quarterLength() {
return this._quarterLength;
}
set quarterLength(ql) {
if (ql === undefined) {
ql = 1.0;
}
this._quarterLength = ql;
this.updateFeaturesFromQl();
}
/**
* Read or sets the type of the duration.
*
* Updates the quarterLength
*
* @type String
* @instance
* @default 'quarter'
* @memberof music21.duration.Duration
* @example
* var d = new music21.duration.Duration(2);
* d.type == 'half; // true
* d.type = 'breve';
* d.quarterLength == 8.0; // true
* d.dots = 1;
* d.type = 'quarter'; // will not change dots
* d.quarterLength == 1.5; // true
*/
get type() {
return this._type;
}
set type(typeIn) {
const typeNumber = duration.ordinalTypeFromNum.indexOf(typeIn);
if (typeNumber === -1) {
console.log('invalid type ' + typeIn);
throw new Music21Exception('invalid type ' + typeIn);
}
this._type = typeIn;
this.updateQlFromFeatures();
}
/**
* Reads the tuplet Array for the duration.
*
* The tuplet array should be considered Read Only.
* Use {@link music21.duration.Duration#appendTuplet} to
* add a tuplet (no way to remove yet)
*
* @type Array<music21.duration.Tuplet>
* @instance
* @default []
* @memberof music21.duration.Duration
*/
get tuplets() {
return this._tuplets;
}
/**
* Read-only: the duration expressed for VexFlow
*
* @type String
* @instance
* @default 'd'
* @memberof music21.duration.Duration
* @example
* var d = new music21.duration.Duration(2);
* d.vexflowDuration == 'h'; // true;
* d.dots = 2;
* d.vexflowDuration == 'hdd'; // true;
*/
get vexflowDuration() {
const typeNumber = duration.ordinalTypeFromNum.indexOf(this.type);
let vd = duration.vexflowDurationArray[typeNumber];
if (this.dots > 0) {
for (let i = 0; i < this.dots; i++) {
vd += 'd'; // vexflow does not handle double dots .. or does it???
}
}
return vd;
}
cloneCallbacksTupletFunction(tupletKey, ret, obj) {
// make sure that tuplets clone properly
const newTuplets = [];
for (let i = 0; i < obj[tupletKey].length; i++) {
const newTuplet = obj[tupletKey][i].clone();
// console.log('cloning tuplets', obj[tupletKey][i], newTuplet);
newTuplets.push(newTuplet);
}
ret[tupletKey] = newTuplets;
}
_findDots(ql) {
if (ql === 0) {
return 0;
} // zero length stream probably;
const typeNumber = duration.ordinalTypeFromNum.indexOf(this._type);
const powerOfTwo = Math.pow(2, duration.quarterTypeIndex - typeNumber);
// alert(undottedQL * 1.5 + " " + ql)
// console.log('find dots called on ql: ', ql, typeNumber, powerOfTwo);
for (let dotsNum = 0; dotsNum <= 4; dotsNum++) {
const dotMultiplier
= (Math.pow(2, dotsNum) - 1.0) / Math.pow(2, dotsNum);
const durationMultiplier = 1 + dotMultiplier;
if (Math.abs(powerOfTwo * durationMultiplier - ql) < 0.0001) {
return dotsNum;
}
}
if (debug) {
console.log('no dots available for ql; probably a tuplet', ql);
}
return 0;
}
updateQlFromFeatures() {
const typeNumber = duration.ordinalTypeFromNum.indexOf(this._type); // must be set property
const undottedQuarterLength = Math.pow(
2,
duration.quarterTypeIndex - typeNumber
);
const dottedMultiplier
= 1 + (Math.pow(2, this._dots) - 1) / Math.pow(2, this._dots);
const unTupletedQl = undottedQuarterLength * dottedMultiplier;
let tupletCorrectedQl = unTupletedQl;
this._tuplets.forEach(tuplet => {
tupletCorrectedQl *= tuplet.tupletMultiplier();
});
this._quarterLength = tupletCorrectedQl;
}
updateFeaturesFromQl() {
const ql = this._quarterLength;
this._tuplets = [];
if (ql === 0) {
this._type = 'zero';
this._dots = 0;
return;
}
const powerOfTwo = Math.floor(Math.log(ql + 0.00001) / Math.log(2));
let typeNumber = duration.quarterTypeIndex - powerOfTwo;
this._type = duration.ordinalTypeFromNum[typeNumber];
// console.log(this._findDots);
this._dots = this._findDots(ql);
const undottedQuarterLength = Math.pow(
2,
duration.quarterTypeIndex - typeNumber
);
const dottedMultiplier
= 1 + (Math.pow(2, this._dots) - 1) / Math.pow(2, this._dots);
let unTupletedQl = undottedQuarterLength * dottedMultiplier;
if (unTupletedQl !== ql && ql !== 0) {
typeNumber -= 1;
this._type = duration.ordinalTypeFromNum[typeNumber]; // increase type: eighth to quarter etc.
unTupletedQl *= 2;
const tupletRatio = ql / unTupletedQl;
const ratioRat = common.rationalize(tupletRatio);
if (ratioRat === undefined) {
// probably a Stream with a length that is inexpressable;
} else {
const t = new duration.Tuplet(
ratioRat.denominator,
ratioRat.numerator,
new duration.Duration(unTupletedQl)
);
this.appendTuplet(t, true); // skipUpdateQl
}
// console.log(ratioRat, ql, unTupletedQl);
}
return;
}
/**
* Add a tuplet to music21j
*
* @memberof music21.duration.Duration
* @param {music21.duration.Tuplet} newTuplet - tuplet to add to `.tuplets`
* @param {boolean} [skipUpdateQl=false] - update the quarterLength afterwards?
*/
appendTuplet(newTuplet, skipUpdateQl) {
newTuplet.frozen = true;
this._tuplets.push(newTuplet);
if (skipUpdateQl !== true) {
this.updateQlFromFeatures();
}
}
}
duration.Duration = Duration;
/**
* Represents a Tuplet; found in {@link music21.duration.Duration#tuplets}
*
* @class Tuplet
* @memberof music21.duration
* @extends music21.prebase.ProtoM21Object
* @param {number} numberNotesActual - numerator of the tuplet, default 3
* @param {number} numberNotesNormal - denominator of the tuplet, default 2
* @param {(music21.duration.Duration|number)} durationActual - duration or quarterLength of duration type, default music21.duration.Duration(0.5)
* @param {(music21.duration.Duration|number)} durationNormal - unused; see music21p for description
*/
export class Tuplet extends prebase.ProtoM21Object {
constructor(
numberNotesActual,
numberNotesNormal,
durationActual,
durationNormal
) {
super();
this.numberNotesActual = numberNotesActual || 3;
this.numberNotesNormal = numberNotesNormal || 2;
this.durationActual = durationActual || new duration.Duration(0.5);
if (typeof this.durationActual === 'number') {
this.durationActual = new duration.Duration(this.durationActual);
}
this.durationNormal = durationNormal || this.durationActual;
this.frozen = false;
this.type = undefined;
/**
* Show a bracket above the tuplet
*
* @memberof music21.duration.Tuplet#
* @member {Boolean} bracket
* @default true
*/
this.bracket = true;
/**
* Bracket placement. Options are `above` or `below`.
*
* @memberof music21.duration.Tuplet#
* @member {String} placement
* @default 'above'
*/
this.placement = 'above';
/**
* What to show above the Tuplet. Options are `number`, `type`, or (string) `none`.
*
* @memberof music21.duration.Tuplet#
* @member {String} tupletActualShow
* @default 'number'
*/
this.tupletActualShow = 'number';
this.tupletNormalShow = undefined; // undefined, 'ratio' for ratios, 'type' for ratioed notes (does not work)
}
/**
* A nice name for the tuplet.
*
* @type String
* @instance
* @readonly
* @memberof music21.duration.Tuplet
*/
get fullName() {
// actual is what is presented to viewer
const numActual = this.numberNotesActual;
const numNormal = this.numberNotesNormal;
if (numActual === 3 && numNormal === 2) {
return 'Triplet';
} else if (numActual === 5 && (numNormal === 4 || numNormal === 2)) {
return 'Quintuplet';
} else if (numActual === 6 && numNormal === 4) {
return 'Sextuplet';
}
const ordStr = common.ordinalAbbreviation(numNormal, true); // plural
return (
'Tuplet of '
+ numActual.toString()
+ '/'
+ numNormal.toString()
+ ordStr
);
}
/**
* Set both durationActual and durationNormal for the tuplet.
*
* @memberof music21.duration.Tuplet
* @param {string} type - a duration type, such as `half`, `quarter`
* @returns {music21.duration.Duration} A converted {@link music21.duration.Duration} matching `type`
*/
setDurationType(type) {
if (this.frozen === true) {
throw new Music21Exception(
'A frozen tuplet (or one attached to a duration) is immutable'
);
}
this.durationActual = new duration.Duration(type);
this.durationNormal = this.durationActual;
return this.durationActual;
}
/**
* Sets the tuplet ratio.
*
* @memberof music21.duration.Tuplet
* @param {Number} actual - number of notes in actual (e.g., 3)
* @param {Number} normal - number of notes in normal (e.g., 2)
* @returns {undefined}
*/
setRatio(actual, normal) {
if (this.frozen === true) {
throw new Music21Exception(
'A frozen tuplet (or one attached to a duration) is immutable'
);
}
this.numberNotesActual = actual || 3;
this.numberNotesNormal = normal || 2;
}
/**
* Get the quarterLength corresponding to the total length that
* the completed tuplet (i.e., 3 notes in a triplet) would occupy.
*
* @memberof music21.duration.Tuplet
* @returns {Number} A quarter length.
*/
totalTupletLength() {
return this.numberNotesNormal * this.durationNormal.quarterLength;
}
/**
* The amount by which each quarter length is multiplied to get
* the tuplet. For instance, in a normal triplet, this is 0.666
*
* @memberof music21.duration.Tuplet
* @returns {Number} A float of the multiplier
*/
tupletMultiplier() {
const lengthActual = this.durationActual.quarterLength;
return (
this.totalTupletLength() / (this.numberNotesActual * lengthActual)
);
}
}
duration.Tuplet = Tuplet;
</pre>
</article>
</section>
</div>
<div class="clearfix"></div>
<footer>
<span class="copyright">
Music21j, Copyright © 2013-2018 Michael Scott Cuthbert and cuthbertLab.
</span>
<br />
<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
on Wed Jul 4th 2018 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
</div>
<br clear="both">
</div>
</div>
<!--<script src="scripts/sunlight.js"></script>-->
<script src="scripts/docstrap.lib.js"></script>
<script src="scripts/bootstrap-dropdown.js"></script>
<script src="scripts/toc.js"></script>
<script>
$( function () {
$( "[id*='$']" ).each( function () {
var $this = $( this );
$this.attr( "id", $this.attr( "id" ).replace( "$", "__" ) );
} );
$( "#toc" ).toc( {
anchorName : function ( i, heading, prefix ) {
return $( heading ).attr( "id" ) || ( prefix + i );
},
selectors : "h1,h2,h3,h4",
showAndHide : false,
scrollTo : "100px"
} );
$( "#toc>ul" ).addClass( "nav nav-pills nav-stacked" );
$( "#main span[id^='toc']" ).addClass( "toc-shim" );
$( '.dropdown-toggle' ).dropdown();
// $( ".tutorial-section pre, .readme-section pre" ).addClass( "sunlight-highlight-javascript" ).addClass( "linenums" );
$( ".tutorial-section pre, .readme-section pre" ).each( function () {
var $this = $( this );
var example = $this.find( "code" );
exampleText = example.html();
var lang = /{@lang (.*?)}/.exec( exampleText );
if ( lang && lang[1] ) {
exampleText = exampleText.replace( lang[0], "" );
example.html( exampleText );
lang = lang[1];
} else {
lang = "javascript";
}
if ( lang ) {
$this
.addClass( "sunlight-highlight-" + lang )
.addClass( "linenums" )
.html( example.html() );
}
} );
Sunlight.highlightAll( {
lineNumbers : true,
showMenu : true,
enableDoclinks : true
} );
} );
</script>
<!--Navigation and Symbol Display-->
<!--Google Analytics-->
</body>
</html>