Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DTL (Test > Levelbuilder): 42348a9b #20026

Merged
merged 164 commits into from
Jan 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
164 commits
Select commit Hold shift + click to select a range
b4d161b
Created block for colorLeds[i].pulse
MeyAyre Jan 3, 2018
5082410
Adding pulse to shared constants
MeyAyre Jan 3, 2018
938ae0e
Log inline hint video clicks to firehose
Jan 3, 2018
9fed9b2
Add userId to pageConstants
Jan 8, 2018
f54124d
Add scriptId to progress store
Jan 8, 2018
9fcc0c8
Log level info and optionally userId to firehose
Jan 8, 2018
52a067c
Update payload to match events schema
Jan 8, 2018
ab3d80f
Allow AP CS Offerings from 2016
Jan 9, 2018
1b2f826
Add seed tasks for ap_school_codes and ap_cs_offerings
Jan 9, 2018
4f1a42c
Progress Tab react
Bjvanminnen Jan 9, 2018
8ca8100
extract component
Bjvanminnen Jan 9, 2018
da47a8a
Merge branch 'staging' into census-ap-data-import
Jan 9, 2018
f16e575
Don't add new values if no redux state available
Jan 9, 2018
e916e7f
Add script selector. Correct links for students
Bjvanminnen Jan 9, 2018
52dee36
get script_structure data
Bjvanminnen Jan 9, 2018
d5cadf6
Add Netflix Data Video
mrjoshida Jan 9, 2018
bcbf9bb
Add Netflix data video
mrjoshida Jan 9, 2018
2e8bce6
student progress (with messy code)
Bjvanminnen Jan 9, 2018
1e23ab0
Revert "Hide debug flags in gamelab"
cpirich Jan 10, 2018
11b477b
Better PropType validation
Bjvanminnen Jan 10, 2018
cc20610
React control for summer workshop assignment
mehalshah Jan 10, 2018
7b6d462
move files
Bjvanminnen Jan 10, 2018
02fd62d
add buttons to teacher and facilitator app signed out pages
Jan 10, 2018
9399e1f
selectCurrentCode while stepping at full speed
cpirich Jan 10, 2018
b27c0f0
extract component
Bjvanminnen Jan 10, 2018
2b6ef79
remove redundant prop
Bjvanminnen Jan 10, 2018
b53e295
improve stepping fix, enable GameLab breakpoints/debugButtons only fo…
cpirich Jan 10, 2018
3fc101b
Move seeding in AP data models, add stub data
Jan 10, 2018
97eb31c
extract getLevelResult
Bjvanminnen Jan 10, 2018
00429f9
Basic createButton() function
islemaster Jan 10, 2018
bd43089
Fix xs screen (phone) detail view layout
Jan 10, 2018
1b00355
cleanup
Bjvanminnen Jan 10, 2018
960a742
storybook
Bjvanminnen Jan 11, 2018
03e48e4
small cleanup
Bjvanminnen Jan 11, 2018
50d218d
Add seeded_s3_objects table and model
Jan 11, 2018
196eaa7
Include the SummerWorkshopAssignment in the detail view, and call fil…
mehalshah Jan 11, 2018
672b163
Don't reseed AP data from S3 if file was already processed
Jan 11, 2018
70c091a
fix block highlighting while stepping through for loops
cpirich Jan 11, 2018
af85d7a
Add stub data for AP CS offerings
Jan 11, 2018
5b56b6b
Merge branch 'staging' into census-ap-data-import
drewsamnick Jan 11, 2018
236b706
debugSprites, 2 phase setup epilogue
cpirich Jan 11, 2018
53de3ac
Get manage students tab showing data with new table under experiment
caleybrock Jan 11, 2018
0fe7dc8
Reconfigure the control to use a grid
mehalshah Jan 11, 2018
5e7cbf3
Ignore non-numeric scores so unscored total is null (displayed as emp…
Jan 11, 2018
ee04514
return debugger to running state upon exiting from callback/event
cpirich Jan 11, 2018
9c02b7e
Actually save the updated workshop ID
mehalshah Jan 11, 2018
9aab6cd
Tweak one style, rename one thing
mehalshah Jan 11, 2018
af43043
Merge branch 'staging' into get_workshops_information_in_detail_view
mehalshah Jan 11, 2018
909c791
Fix more tests
mehalshah Jan 11, 2018
2940c8a
Fix broken tests
mehalshah Jan 11, 2018
065bcb8
Merge branch 'get_workshops_information_in_detail_view' of github.com…
mehalshah Jan 11, 2018
278a010
Hide map for views from outside the US
Jan 11, 2018
0bbdbcb
unhide canvases each time _setupEpiloguePhase1() is called
cpirich Jan 11, 2018
859ff1c
added the sensor.threshold blocks to levelbuilder and the sandbox
MeyAyre Jan 11, 2018
85f0588
code review feedback
Bjvanminnen Jan 11, 2018
843f88f
Fix spacing
mehalshah Jan 11, 2018
625ec1f
include 'other' explanation fields from principal approval form in ap…
Hamms Jan 11, 2018
63b2f8a
Merge pull request #19915 from code-dot-org/teacher-app-signed-out
Jan 11, 2018
0aa5c4a
Merge pull request #19928 from code-dot-org/quick-view-default-score-…
aoby Jan 11, 2018
dd5e6b6
Button is a pullup on touch pins
islemaster Jan 11, 2018
9149dee
Merge pull request #19923 from code-dot-org/detail-view-reflow-fix
aoby Jan 11, 2018
6886826
Update what and how we are logging json data
Jan 11, 2018
5ae32b5
Remove Hour of Code option from Taught in past list
Hamms Jan 11, 2018
3daba74
Change student shape
caleybrock Jan 11, 2018
861f4b4
link scoring rubric in detail view header
Hamms Jan 11, 2018
e31c657
Use exists? instead of count > 0
Jan 11, 2018
9ab6b62
Merge pull request #19934 from code-dot-org/sensor_threshold_blocks
MeyAyre Jan 11, 2018
6ad4d65
Merge branch 'staging' into census-ap-data-import
drewsamnick Jan 11, 2018
f4f0e0a
Merge pull request #19933 from code-dot-org/census-hide-map-outside-us
drewsamnick Jan 11, 2018
b70a718
Merge pull request #19881 from code-dot-org/progressTab
Bjvanminnen Jan 11, 2018
3334223
Merge remote-tracking branch 'origin/staging' into edit-button-action
caleybrock Jan 11, 2018
49157b6
Bump hardcoded callout test script ids so they don't conflict, and ho…
Jan 11, 2018
c11c495
Refactor custom button behavior into a wrapper component
islemaster Jan 11, 2018
c624391
debounce school search
Hamms Jan 11, 2018
c074b7e
Add Grades 6-8 to "What grades will you be teaching this course to" f…
Hamms Jan 11, 2018
46e74ca
Only save source cache once a day
Jan 11, 2018
af911b0
Merge remote-tracking branch 'origin/staging' into colorleds-pulse
islemaster Jan 11, 2018
7e17ab2
Update johnny-five to 0.11.1-cdo.2
islemaster Jan 11, 2018
c3181dc
update tests to reflect new option set
Hamms Jan 11, 2018
3284ecc
Bold text in teacher application that indicates that there is no part…
Hamms Jan 11, 2018
72d92fe
dispatch fewer actions
Bjvanminnen Jan 11, 2018
760c12e
Code review feedback
caleybrock Jan 11, 2018
d931477
PR feedback
mehalshah Jan 11, 2018
2d2c654
Merge pull request #19943 from code-dot-org/include-principal-approva…
Hamms Jan 11, 2018
0bfd241
Switch scored AP-related question and fix auto-score
Jan 11, 2018
5afef92
Map only required data
caleybrock Jan 11, 2018
9107f2c
include 'can pay fee' from principal approval in detail view
Hamms Jan 11, 2018
b9840e6
Merge pull request #19945 from code-dot-org/include-can-pay
Hamms Jan 12, 2018
ba8b9cb
stub debounce in tests
Hamms Jan 12, 2018
d3ecbfa
Merge pull request #19864 from code-dot-org/census-ap-data-import
drewsamnick Jan 12, 2018
a90f396
Update schema cache dump after schema changes.
deploy-code-org Jan 12, 2018
c610c58
Update tests
Jan 12, 2018
901fbf8
Merge pull request #19946 from code-dot-org/resources-tab-add-firehouse
Jan 12, 2018
1d589f4
Merge pull request #19952 from code-dot-org/add-6-8-to-cdp
Hamms Jan 12, 2018
f01aef7
Advocacy map: show new map behind URL parameter
breville Jan 12, 2018
72fb13d
Merge pull request #19947 from code-dot-org/remove-hoc-from-taught-in…
Hamms Jan 12, 2018
6245364
better names and comments
Bjvanminnen Jan 12, 2018
e986a39
ProjectHeader ES6 syntax
Erin007 Jan 12, 2018
f736344
set up connection to metrics sql table
Erin007 Jan 10, 2018
2bd3540
Merge pull request #19958 from code-dot-org/cache-git-less
balderdash Jan 12, 2018
2dad4d9
Merge pull request #19949 from code-dot-org/link-rubric-in-detail-view
Hamms Jan 12, 2018
d95713b
Merge pull request #19920 from code-dot-org/maker-createbutton
islemaster Jan 12, 2018
1d93c1c
Merge pull request #19950 from code-dot-org/bump-callout-script-ids
aoby Jan 12, 2018
deeaca2
Merge pull request #19737 from code-dot-org/colorleds-pulse
islemaster Jan 12, 2018
e9bdee6
Add 'not teaching' option for 2018-19 on teacher app
Jan 11, 2018
5702a78
Add 'other' field to currently teaching and teaching next year questions
Jan 12, 2018
6b845b6
Merge pull request #19956 from code-dot-org/bold-no-partner
Hamms Jan 12, 2018
dc6cabf
Merge pull request #19951 from code-dot-org/debounce-school-search
Hamms Jan 12, 2018
bf09337
Merge branch 'staging' into csp-ap-question-fix
Jan 12, 2018
dc84f14
Fix bug where unmounting and remounting the school autocomplete would…
Jan 12, 2018
c53503f
Merge pull request #19964 from code-dot-org/projectheader-es6
Erin007 Jan 12, 2018
b67ad31
Merge pull request #19929 from code-dot-org/get_workshops_information…
mehalshah Jan 12, 2018
9ffd3be
Fix test
Jan 12, 2018
74a45af
Add final How Computers Work videos
mrjoshida Jan 12, 2018
e348c9d
Merge remote-tracking branch 'origin/staging' into edit-button-action
caleybrock Jan 12, 2018
e6a4beb
Merge branch 'staging' into metrics-sql-write
Erin007 Jan 12, 2018
88c8627
Merge pull request #19955 from code-dot-org/hiddenStagesPerf
Bjvanminnen Jan 12, 2018
abb6c8a
pass isEnglish to TeacherHomepage
Erin007 Jan 12, 2018
40fca8e
Merge pull request #19959 from code-dot-org/csp-ap-question-fix
aoby Jan 12, 2018
4f48e75
make the parts of state being using more explicit
Bjvanminnen Jan 12, 2018
815e572
Merge pull request #19957 from code-dot-org/teacher-app-not-teaching
Jan 12, 2018
5b29e0b
Merge pull request #19969 from code-dot-org/staging
deploy-code-org Jan 12, 2018
8c7dd11
address TODOs
Bjvanminnen Jan 12, 2018
774db2b
Merge pull request #19966 from code-dot-org/school-autocomplete-fix-r…
aoby Jan 12, 2018
141a22e
Add how computers work series
mrjoshida Jan 12, 2018
34e9d0a
Remove accidentally commited temp stuff
mrjoshida Jan 12, 2018
98a585a
Revert "Merge pull request #19893 from code-dot-org/revert-19879-upda…
breville Jan 12, 2018
f4d9811
Rename billg intro video
mrjoshida Jan 12, 2018
40be089
Pass missing required prop, and instantiate the control in before() i…
Jan 12, 2018
aa48fb8
stop printing truncated log and error backtrace snippets on ci build …
davidsbailey Jan 12, 2018
8c155b2
sound gets its own file
Bjvanminnen Jan 12, 2018
03e17fb
Merge pull request #19973 from code-dot-org/update-eyes-gem-3
breville Jan 12, 2018
d2e9b55
Merge remote-tracking branch 'origin/staging' into netflix-data-video
caleybrock Jan 12, 2018
294f28e
Merge pull request #19972 from code-dot-org/silence-backtrace-snippets
davidsbailey Jan 12, 2018
1b8bcb9
Merge pull request #19918 from code-dot-org/fix_debugger_code_highlig…
cpirich Jan 12, 2018
bb0df28
Merge branch 'netflix-data-video' of https://github.com/code-dot-org/…
caleybrock Jan 12, 2018
40afa81
Merge pull request #19975 from code-dot-org/staging
deploy-code-org Jan 12, 2018
c5db8e5
Merge pull request #19962 from code-dot-org/advocacy-map-hidden
breville Jan 12, 2018
b844226
Merge pull request #19976 from code-dot-org/staging
deploy-code-org Jan 12, 2018
6757b3e
Merge pull request #19948 from code-dot-org/edit-button-action
caleybrock Jan 12, 2018
000ee0c
Merge pull request #19898 from code-dot-org/metrics-sql-write
Erin007 Jan 12, 2018
0d54b4a
staging content changes (-robo-commit)
deploy-code-org Jan 12, 2018
d367b33
Merge branch 'staging' of github.com:code-dot-org/code-dot-org into s…
deploy-code-org Jan 12, 2018
15ac0bf
Merge pull request #19978 from code-dot-org/levelbuilder
deploy-code-org Jan 12, 2018
7d67a2e
ExporterTest regression tests clean up body.innerHTML
islemaster Jan 12, 2018
aaea01c
Extract to helper function
islemaster Jan 12, 2018
c2c2681
Fix capitalization
mehalshah Jan 12, 2018
3e54d8a
Merge pull request #19854 from code-dot-org/log-video-clicks
balderdash Jan 12, 2018
6e43e63
Revert "Upgrade eyes gem 3.5.4 -> 3.14.2 (again)"
breville Jan 12, 2018
12d836c
Merge pull request #19981 from code-dot-org/revert-19973-update-eyes-…
breville Jan 12, 2018
f4505bf
Merge pull request #19982 from code-dot-org/staging
deploy-code-org Jan 12, 2018
077501a
Merge pull request #19971 from code-dot-org/fix-regionalPartnerPanel-…
aoby Jan 12, 2018
735e408
Merge pull request #19980 from code-dot-org/fix_please_explain
mehalshah Jan 12, 2018
f5dd622
Merge pull request #19967 from code-dot-org/isEnglish-teacher-homepage
Erin007 Jan 12, 2018
1befb9b
Netflix data video and How Computers Work series
mrjoshida Jan 12, 2018
5c212ba
Merge pull request #19974 from code-dot-org/extractSound
Bjvanminnen Jan 12, 2018
6c2081d
Merge pull request #19968 from code-dot-org/progressTabCleanup
Bjvanminnen Jan 12, 2018
50c5a98
Merge pull request #19984 from code-dot-org/staging
deploy-code-org Jan 12, 2018
bc044b9
Merge pull request #19970 from code-dot-org/brentTodos
Bjvanminnen Jan 12, 2018
bd2236c
Comment on sandboxDocumentBody [ci skip]
islemaster Jan 12, 2018
5cb74a6
Merge pull request #19979 from code-dot-org/unit-test-cleanup
islemaster Jan 12, 2018
4e71855
Manual scoop of video thumbnails (Brendan)
deploy-code-org Jan 12, 2018
9644709
Merge branch 'staging' of github.com:code-dot-org/code-dot-org into s…
deploy-code-org Jan 12, 2018
42348a9
Merge pull request #19993 from code-dot-org/staging
deploy-code-org Jan 12, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 12 additions & 8 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,26 @@ jobs:
resource_class: xlarge

steps:
- run:
name: Create source cache key
command: "date +%D > /home/circleci/today.date"

# cache source
- restore_cache:
key: code-dot-org-source-v6-{{ .Branch }}-{{ .Revision }}
keys:
- code-dot-org-source-v6-{{ .Branch }}-
- code-dot-org-source-v6-
- code-dot-org-source-v7-{{ checksum "/home/circleci/today.date" }}
- code-dot-org-source-v7-

- checkout
- run:
name: merge staging
command: bin/circle/merge-base

- save_cache:
key: code-dot-org-source-v7-{{ checksum "/home/circleci/today.date" }}
paths:
- ".git"

- run:
name: setup tests/artifacts dirs
command: |
Expand All @@ -48,11 +57,6 @@ jobs:
sudo apt-get install -y libicu-dev enscript moreutils pdftk libmysqlclient-dev libsqlite3-dev
sudo mv /usr/bin/gnu_parallel /usr/bin/parallel

- save_cache:
key: code-dot-org-source-v6-{{ .Branch }}-{{ .Revision }}
paths:
- ".git"

# restore gems cache
- restore_cache:
key: code-dot-org-bundle-v6-{{ checksum "Gemfile.lock" }}
Expand Down
2 changes: 1 addition & 1 deletion apps/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@code-dot-org/blockly": "1.7.0",
"@code-dot-org/bramble": "0.1.25",
"@code-dot-org/craft": "github:code-dot-org/craft#ea9da01f6512bcd2c8ea562d6a4ff4d2c0549e4f",
"@code-dot-org/johnny-five": "0.11.1-cdo.1",
"@code-dot-org/johnny-five": "0.11.1-cdo.2",
"@code-dot-org/js-interpreter-tyrant": "0.2.2",
"@code-dot-org/js-numbers": "0.1.0-cdo.0",
"@code-dot-org/p5.play": "1.1.9-cdo",
Expand Down
308 changes: 308 additions & 0 deletions apps/src/Sound.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
function isMobile() {
return ('ontouchstart' in document.documentElement);
}

function isIE9() {
/** @type {number} */
var version = -1;

if (/MSIE\s([\d.]+)/.test(navigator.userAgent)) {
version = parseInt(RegExp.$1);
}

return version === 9;
}

/**
* Initialize an individual sound
* @param config available sound files for this audio
* @param audioContext context this sound can be played on, or null if none
* @constructor
*/
export default function Sound(config, audioContext) {
this.config = config;
this.audioContext = audioContext;
this.audioElement = null; // if HTML5 Audio
this.reusableBuffer = null; // if Web Audio
this.playableBuffer = null; // if Web Audio

/**
* @private {boolean} Whether the sound is currently playing - sadly, neither
* audio system tracks this for us particularly well so we have to
* do it ourselves.
*/
this.isPlaying_ = false;
}

/**
* @param {Object} [options]
* @param {number} [options.volume] default 1.0, which is "no change"
* @param {boolean} [options.loop] default false
* @param {function} [options.onEnded]
*/
Sound.prototype.play = function (options) {
options = options || {};
if (!this.audioElement && !this.reusableBuffer) {
return;
}

if (this.reusableBuffer) {
this.playableBuffer = this.newPlayableBufferSource(this.reusableBuffer, options);

// Hook up on-ended callback, although browser support may be limited.
this.playableBuffer.onended = function () {
this.isPlaying_ = false;
if (options.onEnded) {
options.onEnded();
}
}.bind(this);

// Play sound, supporting older versions of the Web Audio API which used noteOn(Off).
if (this.playableBuffer.start) {
this.playableBuffer.start(0);
} else {
this.playableBuffer.noteOn(0);
}
this.isPlaying_ = true;
return;
}

if (!this.config.allowHTML5Mobile && isMobile()) {
// Don't play HTML 5 audio on mobile
return;
}

var volume = (typeof options.volume === "undefined") ? 1 :
Math.max(0, Math.min(1, options.volume));
this.audioElement.volume = volume;
this.audioElement.loop = !!options.loop;
var unregisterAndCallback = function () {
this.audioElement.removeEventListener('abort', unregisterAndCallback);
this.audioElement.removeEventListener('ended', unregisterAndCallback);
this.audioElement.removeEventListener('pause', unregisterAndCallback);
this.isPlaying_ = false;
if (options.onEnded) {
options.onEnded();
}
}.bind(this);
this.audioElement.addEventListener('abort', unregisterAndCallback);
this.audioElement.addEventListener('ended', unregisterAndCallback);
this.audioElement.addEventListener('pause', unregisterAndCallback);
this.audioElement.play();
this.isPlaying_ = true;
};

Sound.prototype.stop = function () {
try {
if (this.playableBuffer) {
if (this.playableBuffer.stop) { // Newest web audio pseudo-standard.
this.playableBuffer.stop(0);
} else if (this.playableBuffer.noteOff) { // Older web audio.
this.playableBuffer.noteOff(0);
}
} else if (this.audioElement) {
// html 5 audio.
this.audioElement.pause();
}
} catch (e) {
if (e.name === 'InvalidStateError') {
// Stopping a sound that hasn't been played.
} else {
throw e;
}
}
this.isPlaying_ = false;
};

/**
* @returns {boolean} whether the sound is currently playing.
*/
Sound.prototype.isPlaying = function () {
return this.isPlaying_;
};

Sound.prototype.newPlayableBufferSource = function (buffer, options) {
var newSound = this.audioContext.createBufferSource();

// Older versions of chrome call this createGainNode instead of createGain
if (this.audioContext.createGain) {
this.gainNode = this.audioContext.createGain();
} else if (this.audioContext.createGainNode) {
this.gainNode = this.audioContext.createGainNode();
} else {
return null;
}

newSound.buffer = buffer;
newSound.loop = !!options.loop;
newSound.connect(this.gainNode);
this.gainNode.connect(this.audioContext.destination);
var startingVolume = typeof options.volume === "undefined" ? 1 : options.volume;
this.gainNode.gain.value = startingVolume;
return newSound;
};

/**
* Do an exponential fade from the current gain to a new given value, over the
* given number of seconds.
* @param {number} gain - desired final gain value
* @param {number} durationSeconds
*/
Sound.prototype.fadeToGain = function (gain, durationSeconds) {
if (this.gainNode) {
this.fadeToGainWebAudio_(gain, durationSeconds);
} else if (this.audioElement) {
this.fadeToGainHtml5Audio_(gain, durationSeconds);
}
};

/**
* Do an exponential fade from the current gain to a new given value, over the
* given number of seconds.
* Using Web Audio (preferred, but not supported in IE)
* @param {number} gain - desired final gain value
* @param {number} durationSeconds
* @private
*/
Sound.prototype.fadeToGainWebAudio_ = function (gain, durationSeconds) {
if (!this.gainNode) {
return;
}

// Can't exponential ramp to zero, simulate by getting close.
if (gain === 0) {
gain = 0.01;
}

var currTime = this.audioContext.currentTime;
this.gainNode.gain.setValueAtTime(this.gainNode.gain.value, currTime);
this.gainNode.gain.exponentialRampToValueAtTime(gain, currTime + durationSeconds);
};

/**
* Do an exponential fade from the current gain to a new given value, over the
* given number of seconds.
* Using HTML5 Audio (fallback player)
* @param {number} gain - desired final gain value
* @param {number} durationSeconds
* @private
*/
Sound.prototype.fadeToGainHtml5Audio_ = function (gain, durationSeconds) {
if (!this.audioElement) {
return;
}

var startVolume = this.audioElement.volume || 1;
var finalVolume = Math.max(0, Math.min(1, gain));
var deltaVolume = finalVolume - startVolume;
var durationMillis = durationSeconds * 1000;
var t0 = new Date().getTime();
var fadeInterval = setInterval(function () {
var t = new Date().getTime() - t0;

// Base condition - after duration has elapsed, snap volume to final and
// clear interval
if (t >= durationMillis) {
this.audioElement.volume = finalVolume;
clearInterval(fadeInterval);
return;
}

// TODO: Probably ought to use ease out quad if delta is positive,
// TODO: so that cross-fades automatically work as expected.
// Ease in quad - the ear hears this as a "linear" fade
// y = c * (t/d)^2 + b
// b: initial value
// c: final delta
// d: duration
// t: time
var newVolume = deltaVolume * Math.pow(t / durationMillis, 2) + startVolume;
this.audioElement.volume = Math.max(0, Math.min(1, newVolume));
}.bind(this), 100);
};

Sound.prototype.getPlayableFile = function () {
// IE9 Running on Windows Server SKU can throw an exception on window.Audio
try {
if (!window.Audio) {
return false;
}

var audioTest = new window.Audio();

if (this.config.hasOwnProperty('mp3') && audioTest.canPlayType('audio/mp3')) {
return this.config.mp3;
}
if (this.config.hasOwnProperty('ogg') && audioTest.canPlayType('audio/ogg')) {
return this.config.ogg;
}
if (this.config.hasOwnProperty('wav') && audioTest.canPlayType('audio/wav')) {
return this.config.wav;
}
} catch (e) {

}

return false;
};

Sound.prototype.preload = function () {
var file = this.getPlayableFile();
if (!file) {
return;
}

if (!this.config.forceHTML5 && window.AudioContext && this.audioContext) {
var self = this;
this.preloadViaWebAudio(file, function (buffer) {
self.reusableBuffer = buffer;
});
return;
}

if (window.Audio) {
var audioElement = new window.Audio(file);
if (!audioElement || !audioElement.play) {
return;
}

if (!isIE9()) {
// Pre-cache audio
audioElement.play();
audioElement.pause();
}
this.audioElement = audioElement;

// Fire onLoad as soon as enough of the sound is loaded to play it
// all the way through.
var loadEventName = 'canplaythrough';
var eventListener = function () {
this.onSoundLoaded();
audioElement.removeEventListener(loadEventName, eventListener);
}.bind(this);
audioElement.addEventListener(loadEventName, eventListener);
}
};

Sound.prototype.onSoundLoaded = function () {
if (this.config.playAfterLoad) {
this.play(this.config.playAfterLoadOptions);
}
if (this.onLoad) {
this.onLoad();
}
};

Sound.prototype.preloadViaWebAudio = function (filename, onPreloadedCallback) {
var request = new XMLHttpRequest();
request.open('GET', filename, true);
request.responseType = 'arraybuffer';
var self = this;
request.onload = function () {
self.audioContext.decodeAudioData(request.response, function (buffer) {
onPreloadedCallback(buffer);
self.onSoundLoaded();
});
};
request.send();
};