├── .gitignore ├── _config.yml ├── test ├── lib │ └── jasmine-2.0.1 │ │ ├── jasmine_favicon.png │ │ ├── console.js │ │ ├── boot.js │ │ ├── jasmine-html.js │ │ ├── jasmine.css │ │ └── jasmine.js ├── index.html └── conway_spec.js ├── readme.md ├── package.json ├── LICENSE ├── index.html ├── js ├── game.js └── p5.dom.js ├── css └── docs.css └── docs ├── docs.css └── game.html /.gitignore: -------------------------------------------------------------------------------- 1 | _site/ 2 | _ref/ 3 | .DS_Store 4 | .sass-cache/ 5 | docs/public/ -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | exclude: ["deploy.sh","node_modules/","package.json","readme.md", "docs/public/","css/","test/"] -------------------------------------------------------------------------------- /test/lib/jasmine-2.0.1/jasmine_favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sklise/conways-game-of-life/HEAD/test/lib/jasmine-2.0.1/jasmine_favicon.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Conway's Game of Life 2 | 3 | *Conway's Game of Life simulation in [p5.js](https://github.com/processing/p5.js)* 4 | 5 | [view simulation](https://sklise.github.io/conways-game-of-life/) 6 | 7 | ### Thanks 8 | Thanks to [Dan Shiffman](https://github.com/shiffman) and his class _Nature of 9 | Code_. 10 | 11 | MIT Licensed 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "conwaysgameoflife", 3 | "version": "1.0.0", 4 | "description": "*Conway's Game of Life simulation in [p5.js](https://github.com/lmccart/p5.js)*", 5 | "scripts": { 6 | "build-docs": "docco js/game.js --css css/docs.css" 7 | }, 8 | "license": "MIT", 9 | "repository": "sklise/conways-game-of-life", 10 | "devDependencies": { 11 | "docco": "^0.7.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Jasmine Spec Runner v2.0.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Steve Klise 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | conway's game of life 6 | 7 | 8 | 9 | 13 | 14 | 15 |

Conway's Game of Life in p5.js

16 |

Read more about cellular automata in Nature of Code. Written in p5.js. Code on Github Annotated source code

17 | 18 | 19 | -------------------------------------------------------------------------------- /test/conway_spec.js: -------------------------------------------------------------------------------- 1 | no = false 2 | yes = true 3 | 4 | describe("Conway", function () { 5 | describe("outOfBounds", function () { 6 | it("should return true if a value is less than 0", function () { 7 | expect(outOfBounds([-1,0],3,3)).toBe(true) 8 | expect(outOfBounds([0,-1],3,3)).toBe(true) 9 | expect(outOfBounds([-2,-4],3,3)).toBe(true) 10 | }) 11 | 12 | it("should return false if a value is in bounds", function () { 13 | expect(outOfBounds([2,0],3,3)).toBe(false) 14 | expect(outOfBounds([1,1],3,3)).toBe(false) 15 | expect(outOfBounds([0,2],3,3)).toBe(false) 16 | }) 17 | 18 | it("should return true if a value is above bounds", function () { 19 | expect(outOfBounds([3,0],3,3)).toBe(true) 20 | expect(outOfBounds([3,3],3,3)).toBe(true) 21 | expect(outOfBounds([0,3],3,3)).toBe(true) 22 | }) 23 | }) 24 | 25 | describe("nextFromDead()", function () {}) 26 | describe("nextFromLiving()",function () {}) 27 | 28 | describe("checkNeighbors", function () { 29 | it("should yield the correct answer", function () { 30 | world = [ 31 | [no, no, no], 32 | [no, yes, no], 33 | [yes, yes, yes] 34 | ] 35 | 36 | expect(checkNeighbors(1,1, world, world.length, world[0].length)).toBe(3) 37 | expect(checkNeighbors(1,0, world, world.length, world[0].length)).toBe(1) 38 | expect(checkNeighbors(0,2, world, world.length, world[0].length)).toBe(2) 39 | }) 40 | }) 41 | 42 | describe("nextGeneration()", function () { 43 | describe("cell is alive", function () { 44 | it("should stay alive if neighbors are between 2 and 3", function () { 45 | worlds = [ 46 | [ 47 | [no, no, no], 48 | [no, yes, no], 49 | [yes, yes, yes] 50 | ], 51 | [ 52 | [yes, yes, yes], 53 | [no, yes, no], 54 | [no, no, no] 55 | ], 56 | [ 57 | [yes, yes, no], 58 | [yes, yes, no], 59 | [no, no, no] 60 | ], 61 | // 2 62 | [ 63 | [yes, no, no], 64 | [no, yes, no], 65 | [no, no, yes] 66 | ], 67 | [ 68 | [yes, no, no], 69 | [yes, yes, no], 70 | [no, no, no] 71 | ] 72 | ] 73 | 74 | worlds.forEach(function (world ) { 75 | expect(nextGeneration(1,1, world)).toBe(true) 76 | }) 77 | }) 78 | 79 | it("should die if neighbors are less than 2 or greater than 3", function() { 80 | 81 | world = [ 82 | [no, no, yes], 83 | [no, yes, yes], 84 | [yes, yes, yes] 85 | ] 86 | 87 | expect(nextGeneration(1,1, world)).toBe(false) 88 | }) 89 | }) 90 | 91 | describe("cell is dead", function () { 92 | it("should spawn a cell if neighbors are 3", function () { 93 | worlds = [ 94 | [ 95 | [yes, no, no], 96 | [no, no, yes], 97 | [no, no, yes] 98 | ], 99 | [ 100 | [yes, no, no], 101 | [no, no, no], 102 | [no, yes, yes] 103 | ] 104 | ] 105 | 106 | worlds.forEach(function (world) { 107 | expect(nextGeneration(1,1,world)).toBe(true) 108 | }) 109 | }) 110 | 111 | it("should not spawn a cell if neighbors are not 3", function () { 112 | worlds = [ 113 | [ 114 | [no, no, no], 115 | [no, no, yes], 116 | [no, no, yes] 117 | ], 118 | [ 119 | [yes, no, no], 120 | [yes, no, no], 121 | [yes, yes, yes] 122 | ] 123 | ] 124 | expect(nextGeneration(1,1, world)).toBe(false) 125 | }) 126 | 127 | }) 128 | }) 129 | }) -------------------------------------------------------------------------------- /test/lib/jasmine-2.0.1/console.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008-2014 Pivotal Labs 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | function getJasmineRequireObj() { 24 | if (typeof module !== 'undefined' && module.exports) { 25 | return exports; 26 | } else { 27 | window.jasmineRequire = window.jasmineRequire || {}; 28 | return window.jasmineRequire; 29 | } 30 | } 31 | 32 | getJasmineRequireObj().console = function(jRequire, j$) { 33 | j$.ConsoleReporter = jRequire.ConsoleReporter(); 34 | }; 35 | 36 | getJasmineRequireObj().ConsoleReporter = function() { 37 | 38 | var noopTimer = { 39 | start: function(){}, 40 | elapsed: function(){ return 0; } 41 | }; 42 | 43 | function ConsoleReporter(options) { 44 | var print = options.print, 45 | showColors = options.showColors || false, 46 | onComplete = options.onComplete || function() {}, 47 | timer = options.timer || noopTimer, 48 | specCount, 49 | failureCount, 50 | failedSpecs = [], 51 | pendingCount, 52 | ansi = { 53 | green: '\x1B[32m', 54 | red: '\x1B[31m', 55 | yellow: '\x1B[33m', 56 | none: '\x1B[0m' 57 | }; 58 | 59 | this.jasmineStarted = function() { 60 | specCount = 0; 61 | failureCount = 0; 62 | pendingCount = 0; 63 | print('Started'); 64 | printNewline(); 65 | timer.start(); 66 | }; 67 | 68 | this.jasmineDone = function() { 69 | printNewline(); 70 | for (var i = 0; i < failedSpecs.length; i++) { 71 | specFailureDetails(failedSpecs[i]); 72 | } 73 | 74 | if(specCount > 0) { 75 | printNewline(); 76 | 77 | var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' + 78 | failureCount + ' ' + plural('failure', failureCount); 79 | 80 | if (pendingCount) { 81 | specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount); 82 | } 83 | 84 | print(specCounts); 85 | } else { 86 | print('No specs found'); 87 | } 88 | 89 | printNewline(); 90 | var seconds = timer.elapsed() / 1000; 91 | print('Finished in ' + seconds + ' ' + plural('second', seconds)); 92 | 93 | printNewline(); 94 | 95 | onComplete(failureCount === 0); 96 | }; 97 | 98 | this.specDone = function(result) { 99 | specCount++; 100 | 101 | if (result.status == 'pending') { 102 | pendingCount++; 103 | print(colored('yellow', '*')); 104 | return; 105 | } 106 | 107 | if (result.status == 'passed') { 108 | print(colored('green', '.')); 109 | return; 110 | } 111 | 112 | if (result.status == 'failed') { 113 | failureCount++; 114 | failedSpecs.push(result); 115 | print(colored('red', 'F')); 116 | } 117 | }; 118 | 119 | return this; 120 | 121 | function printNewline() { 122 | print('\n'); 123 | } 124 | 125 | function colored(color, str) { 126 | return showColors ? (ansi[color] + str + ansi.none) : str; 127 | } 128 | 129 | function plural(str, count) { 130 | return count == 1 ? str : str + 's'; 131 | } 132 | 133 | function repeat(thing, times) { 134 | var arr = []; 135 | for (var i = 0; i < times; i++) { 136 | arr.push(thing); 137 | } 138 | return arr; 139 | } 140 | 141 | function indent(str, spaces) { 142 | var lines = (str || '').split('\n'); 143 | var newArr = []; 144 | for (var i = 0; i < lines.length; i++) { 145 | newArr.push(repeat(' ', spaces).join('') + lines[i]); 146 | } 147 | return newArr.join('\n'); 148 | } 149 | 150 | function specFailureDetails(result) { 151 | printNewline(); 152 | print(result.fullName); 153 | 154 | for (var i = 0; i < result.failedExpectations.length; i++) { 155 | var failedExpectation = result.failedExpectations[i]; 156 | printNewline(); 157 | print(indent(failedExpectation.stack, 2)); 158 | } 159 | 160 | printNewline(); 161 | } 162 | } 163 | 164 | return ConsoleReporter; 165 | }; 166 | -------------------------------------------------------------------------------- /test/lib/jasmine-2.0.1/boot.js: -------------------------------------------------------------------------------- 1 | /** 2 | Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. 3 | 4 | If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. 5 | 6 | The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. 7 | 8 | [jasmine-gem]: http://github.com/pivotal/jasmine-gem 9 | */ 10 | 11 | (function() { 12 | 13 | /** 14 | * ## Require & Instantiate 15 | * 16 | * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. 17 | */ 18 | window.jasmine = jasmineRequire.core(jasmineRequire); 19 | 20 | /** 21 | * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. 22 | */ 23 | jasmineRequire.html(jasmine); 24 | 25 | /** 26 | * Create the Jasmine environment. This is used to run all specs in a project. 27 | */ 28 | var env = jasmine.getEnv(); 29 | 30 | /** 31 | * ## The Global Interface 32 | * 33 | * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. 34 | */ 35 | var jasmineInterface = { 36 | describe: function(description, specDefinitions) { 37 | return env.describe(description, specDefinitions); 38 | }, 39 | 40 | xdescribe: function(description, specDefinitions) { 41 | return env.xdescribe(description, specDefinitions); 42 | }, 43 | 44 | it: function(desc, func) { 45 | return env.it(desc, func); 46 | }, 47 | 48 | xit: function(desc, func) { 49 | return env.xit(desc, func); 50 | }, 51 | 52 | beforeEach: function(beforeEachFunction) { 53 | return env.beforeEach(beforeEachFunction); 54 | }, 55 | 56 | afterEach: function(afterEachFunction) { 57 | return env.afterEach(afterEachFunction); 58 | }, 59 | 60 | expect: function(actual) { 61 | return env.expect(actual); 62 | }, 63 | 64 | pending: function() { 65 | return env.pending(); 66 | }, 67 | 68 | spyOn: function(obj, methodName) { 69 | return env.spyOn(obj, methodName); 70 | }, 71 | 72 | jsApiReporter: new jasmine.JsApiReporter({ 73 | timer: new jasmine.Timer() 74 | }) 75 | }; 76 | 77 | /** 78 | * Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. 79 | */ 80 | if (typeof window == "undefined" && typeof exports == "object") { 81 | extend(exports, jasmineInterface); 82 | } else { 83 | extend(window, jasmineInterface); 84 | } 85 | 86 | /** 87 | * Expose the interface for adding custom equality testers. 88 | */ 89 | jasmine.addCustomEqualityTester = function(tester) { 90 | env.addCustomEqualityTester(tester); 91 | }; 92 | 93 | /** 94 | * Expose the interface for adding custom expectation matchers 95 | */ 96 | jasmine.addMatchers = function(matchers) { 97 | return env.addMatchers(matchers); 98 | }; 99 | 100 | /** 101 | * Expose the mock interface for the JavaScript timeout functions 102 | */ 103 | jasmine.clock = function() { 104 | return env.clock; 105 | }; 106 | 107 | /** 108 | * ## Runner Parameters 109 | * 110 | * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. 111 | */ 112 | 113 | var queryString = new jasmine.QueryString({ 114 | getWindowLocation: function() { return window.location; } 115 | }); 116 | 117 | var catchingExceptions = queryString.getParam("catch"); 118 | env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); 119 | 120 | /** 121 | * ## Reporters 122 | * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). 123 | */ 124 | var htmlReporter = new jasmine.HtmlReporter({ 125 | env: env, 126 | onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); }, 127 | getContainer: function() { return document.body; }, 128 | createElement: function() { return document.createElement.apply(document, arguments); }, 129 | createTextNode: function() { return document.createTextNode.apply(document, arguments); }, 130 | timer: new jasmine.Timer() 131 | }); 132 | 133 | /** 134 | * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. 135 | */ 136 | env.addReporter(jasmineInterface.jsApiReporter); 137 | env.addReporter(htmlReporter); 138 | 139 | /** 140 | * Filter which specs will be run by matching the start of the full name against the `spec` query param. 141 | */ 142 | var specFilter = new jasmine.HtmlSpecFilter({ 143 | filterString: function() { return queryString.getParam("spec"); } 144 | }); 145 | 146 | env.specFilter = function(spec) { 147 | return specFilter.matches(spec.getFullName()); 148 | }; 149 | 150 | /** 151 | * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. 152 | */ 153 | window.setTimeout = window.setTimeout; 154 | window.setInterval = window.setInterval; 155 | window.clearTimeout = window.clearTimeout; 156 | window.clearInterval = window.clearInterval; 157 | 158 | /** 159 | * ## Execution 160 | * 161 | * Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded. 162 | */ 163 | var currentWindowOnload = window.onload; 164 | 165 | window.onload = function() { 166 | if (currentWindowOnload) { 167 | currentWindowOnload(); 168 | } 169 | htmlReporter.initialize(); 170 | env.execute(); 171 | }; 172 | 173 | /** 174 | * Helper function for readability above. 175 | */ 176 | function extend(destination, source) { 177 | for (var property in source) destination[property] = source[property]; 178 | return destination; 179 | } 180 | 181 | }()); 182 | -------------------------------------------------------------------------------- /js/game.js: -------------------------------------------------------------------------------- 1 | // TODO: 2 | // - Document all functions 3 | // - Experiment with the size of the rendered world 4 | // - Detect screen size and draw accordingly 5 | // - Render entire size, and have overlays 6 | // - Minify/uglify/gzip? 7 | // - Perlin noise 8 | // - Fix frame rate thing 9 | 10 | //## p5 11 | 12 | //### World 13 | 14 | // This is the object that holds all of the state for the simulation. When something 15 | // changes in the simulation we change it here. We initialize this object first and at 16 | // the beginning of the file so that `setup` and `draw` can access it. 17 | 18 | // - width: An integer of the number of cells across 19 | // - height: An integer of the number of cells from top to bottom 20 | // - renderedCellSize: An integer for how large to draw the cells 21 | // - paused: A boolean value for whether the simulation is paused or not 22 | // - cells: A two dimensional array of integers with values 1 or 0 for cell states 23 | // - initiallyClickedCellState: An integer for what state to switch clicked cells to, usage for this property is explained in the `changeCellState` function 24 | 25 | var world = { 26 | width: 160, 27 | height: 90, 28 | renderedCellSize: 7, 29 | paused: false, 30 | cells: [], 31 | initiallyClickedCellState: 0 32 | }; 33 | 34 | //## Setup 35 | function setup() { 36 | noStroke(); 37 | 38 | // TODO: Run at 60fps but change the speed with which the world advances, keeping in 39 | // mind that frames can be dropped, so just using "frameCount" will not produce a 40 | // smooth simulation 41 | frameRate(20); 42 | 43 | // Populate the world with a default percentage filled 44 | world = populateWorld(world, 0.35); 45 | 46 | //### Interface buttons 47 | 48 | // Add a pause button that when clicked flips the value of `world.pause` 49 | var pauseButton = createButton('Pause'); 50 | pauseButton.mousePressed(function () { 51 | world.paused = !world.paused; 52 | }); 53 | 54 | // Add a button to clear set all cells to 0 55 | var clearButton = createButton('Clear'); 56 | clearButton.mousePressed(function () { 57 | world = clearWorld(world); 58 | }); 59 | 60 | // Add a button to wipe and reset the world randomly 61 | var generateButton = createButton('Regenerate'); 62 | generateButton.mousePressed(function () { 63 | world = populateWorld(world, sl.value()/ 100); 64 | }); 65 | 66 | // Add a slider to adjust the percentage of the grid to fill with live cells when 67 | // regenerating. This value is between 0 and 100, however values closer to 100 tend to 68 | // lead to a very quick die off. 69 | var sl = createSlider(0,100,35); 70 | 71 | // With all of the buttons and interface created, create the canvas with the world 72 | // width and height 73 | createCanvas(world.width * world.renderedCellSize, world.height * world.renderedCellSize); 74 | } 75 | 76 | //## Draw 77 | function draw() { 78 | fill(255,255,255); 79 | background(); 80 | drawWorld(world); 81 | // Update the world only if the world is not paused. 82 | if (!world.paused) { 83 | var neighborCounts = census(world); 84 | world = nextGeneration(world, neighborCounts); 85 | } 86 | 87 | if (isMouseInBounds(world)) { 88 | var xx = posToCellCoords(world.renderedCellSize,mouseX); 89 | var yy = posToCellCoords(world.renderedCellSize,mouseY); 90 | drawHoveredCell(xx, yy, world.renderedCellSize); 91 | 92 | if (mouseIsPressed) { 93 | changeCellState(world, xx / world.renderedCellSize, yy / world.renderedCellSize); 94 | } 95 | } 96 | 97 | } 98 | 99 | //## P5 Interactions 100 | function mousePressed() { 101 | if (isMouseInBounds(world)) { 102 | var xx = posToCellCoords(world.renderedCellSize,mouseX); 103 | var yy = posToCellCoords(world.renderedCellSize,mouseY); 104 | world.initiallyClickedCellState = world.cells[yy / world.renderedCellSize][xx / world.renderedCellSize] ? 0 : 1; 105 | } 106 | } 107 | 108 | function keyPressed(e) { 109 | if (key === ' ') { 110 | e.preventDefault(); 111 | world.paused = !world.paused; 112 | } 113 | } 114 | 115 | //## Drawing helper methods 116 | 117 | //### drawHoveredCell 118 | 119 | // Use this function to draw a highlighted cell at a given `x` and `y` coordinate in the 120 | // p5 sketch. The function sets its own fill color to a semi-transulecent blue. 121 | 122 | //##### Arguments: 123 | // - x : An integer of the x coordinate to draw the `rect` at 124 | // - y : An integer of the y coordinate to draw the `rect` at 125 | // - side : An integer for the width and height of the `rect` 126 | function drawHoveredCell(x, y, side) { 127 | fill(0, 0, 255, 128); 128 | rect(x, y, side, side); 129 | } 130 | 131 | //### drawWorld 132 | 133 | // Draws black squares for all cells in `world` that have a value of 1. 134 | 135 | //##### Arguments: 136 | // - world : A world object, as defined above 137 | function drawWorld(world) { 138 | fill(0,0,0); 139 | // Loop through the `world.cells` to get each row and then each cell, setting 140 | // variables for the yIndex and xIndex which are used to position the rectangle. 141 | world.cells.forEach(function(rowArray, yIndex) { 142 | rowArray.forEach(function(cellState, xIndex) { 143 | // If the cell is alive, draw a rectangle. Set the x position to be the number of 144 | // cells from the left times the width of each cell and the y position as the 145 | // number of cells from the top times the width of each cell. 146 | if (cellState === 1) { 147 | rect(xIndex * world.renderedCellSize, yIndex * world.renderedCellSize, world.renderedCellSize, world.renderedCellSize); 148 | } 149 | }); 150 | }); 151 | } 152 | 153 | //## Misc. Helper Functions 154 | 155 | //### actualModulo 156 | // Javascript doesn't have a proper "modulo" operator see [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Remainder) 157 | // When % is passed a negative number for the divisor, the result is negative. For 158 | // looping around arrays we always need positive values. 159 | 160 | // example: 161 | 162 | // -1 % 15 === -1; // Desired result is 14 163 | // actualModulo(-1, 15) === 14 164 | function actualModulo(divisor, dividend) { 165 | var fakeMod = divisor % dividend; 166 | 167 | if (fakeMod < 0) { 168 | return dividend + fakeMod; 169 | } else { 170 | return fakeMod; 171 | } 172 | } 173 | 174 | //### isMouseInBounds 175 | // Passed a world object, returns a boolean of whether or not the mouse is inside the 176 | // edges of the simulation or not. 177 | var isMouseInBounds = function(world) { 178 | var w = world.width * world.renderedCellSize; 179 | var h = world.height * world.renderedCellSize; 180 | 181 | if (mouseX > 0 && mouseY > 0 && mouseX < w && mouseY < h) { 182 | return true; 183 | } else { 184 | return false; 185 | } 186 | } 187 | 188 | //### posToCellCoords 189 | var posToCellCoords = function (cellSize, n) { 190 | return n - n % cellSize; 191 | } 192 | 193 | //## Game of Life 194 | 195 | //### buildArray 196 | // Create a two dimensional array given two dimensions and a function to fill the array 197 | // the predicate function is passed the x and y coordinates of the array position. 198 | function buildArray(w, h, pred) { 199 | var arr = Array(h); 200 | for (var i = 0; i < h; i += 1) { 201 | var arrRow = Array(w); 202 | for (var j = 0; j < w; j += 1) { 203 | arrRow[j] = pred(j,i); 204 | } 205 | arr[i] = arrRow; 206 | } 207 | return arr; 208 | } 209 | 210 | //### populate 211 | // Random (and soon hopefully something like a Perlin Noise thing) make cells. Give it a 212 | // coefficient for likelihood that the cell is alive, between 0 and 1. A value closer to 213 | // 1 means more living cells. 214 | // TODO: Switch to 2d Perlin noise when I'm back on the internet. 215 | // 216 | // Returns a closure that generates 1s and 0s. 217 | function populate(coefficient) { 218 | return function (x, y) { 219 | if (Math.random() < coefficient) { 220 | return 1; 221 | } else { 222 | return 0; 223 | } 224 | } 225 | } 226 | 227 | //### sumNeighbors 228 | // Get the sum of the neighbors of a cell. Given the entire world array, width and 229 | // height precomputed to save on lenght lookups and the x and y coordinate of the cell. 230 | // Loops around the edges. 231 | function sumNeighbors(cells, w, h, x, y) { 232 | return cells[y][actualModulo(x - 1, w)] + cells[y][actualModulo(x + 1, w)] + cells[actualModulo(y - 1, h)][x] + cells[actualModulo(y + 1, h)][x] + cells[actualModulo(y - 1, h)][actualModulo(x - 1, w)] + cells[actualModulo(y - 1, h)][actualModulo(x + 1, w)] + cells[actualModulo(y + 1, h)][actualModulo(x - 1, w)] + cells[actualModulo(y + 1, h)][actualModulo(x + 1, w)]; 233 | } 234 | 235 | //### census 236 | // Count up neighbors; 237 | function census(world) { 238 | var newNeighborCounts = buildArray(world.width, world.height, function() { return 0; }); 239 | world.cells.forEach(function(rowArray, yIndex) { 240 | rowArray.forEach(function(cellState, xIndex) { 241 | newNeighborCounts[yIndex][xIndex] = sumNeighbors(world.cells, world.width, world.height, xIndex, yIndex); 242 | }); 243 | }); 244 | 245 | return newNeighborCounts; 246 | } 247 | 248 | //### nextGeneration 249 | function nextGeneration(world, neighborCounts) { 250 | world.cells.forEach(function(rowArray, yIndex) { 251 | rowArray.forEach(function(cellState, xIndex) { 252 | var count = neighborCounts[yIndex][xIndex]; 253 | var cellState = world.cells[yIndex][xIndex]; 254 | // If the cell has the proper number of neighbors to turn from dead to alive set 255 | // the cell to alive. Else, if the cell is currently alive and meets the 256 | // requirements to die, set the cell to dead. In all other cases do not update the 257 | // state of the cell. 258 | if (count == 3) { 259 | world.cells[yIndex][xIndex] = 1; 260 | } else if (cellState === 1 && (count < 2 || count > 3)) { 261 | world.cells[yIndex][xIndex] = 0; 262 | } 263 | }); 264 | }); 265 | 266 | return world; 267 | } 268 | 269 | //### changeCellState 270 | function changeCellState(world, x, y) { 271 | world.cells[y][x] = world.initiallyClickedCellState; 272 | } 273 | 274 | //### populateWorld 275 | // resets a world's cells with the provided density and returns the world. 276 | function populateWorld(world, density) { 277 | world.cells = buildArray(world.width, world.height, populate(density)); 278 | return world; 279 | } 280 | 281 | //### clearWorld 282 | // Replaces `world.cells` with a two dimensional array filled only with 0's 283 | function clearWorld(world) { 284 | world.cells = buildArray(world.width, world.height, function () { return 0; }); 285 | return world; 286 | } 287 | -------------------------------------------------------------------------------- /css/docs.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Layout ----------------------------*/ 2 | html { height: 100%; } 3 | body { 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 5 | font-size: 14px; 6 | line-height: 18px; 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | #container { min-height: 100%; } 12 | 13 | p { 14 | margin: 15px 0 0px; 15 | } 16 | .annotation ul, .annotation ol { 17 | margin: 25px 0; 18 | } 19 | .annotation ul li, .annotation ol li { 20 | font-size: 14px; 21 | line-height: 18px; 22 | margin: 10px 0; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | line-height: 1em; 27 | margin: 30px 0 15px 0; 28 | } 29 | 30 | h1 { 31 | margin-top: 40px; 32 | } 33 | 34 | h2 { 35 | font-size: 1.26em; 36 | } 37 | 38 | hr { 39 | border: 0; 40 | background: 1px #ddd; 41 | height: 1px; 42 | margin: 20px 0; 43 | } 44 | 45 | pre, tt, code { 46 | font-size: 12px; line-height: 16px; 47 | font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; 48 | margin: 0; padding: 0; 49 | } 50 | .annotation pre { 51 | display: block; 52 | margin: 0; 53 | padding: 7px 10px; 54 | background: #fcfcfc; 55 | -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 56 | -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 57 | box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 58 | overflow-x: auto; 59 | } 60 | .annotation pre code { 61 | border: 0; 62 | padding: 0; 63 | background: transparent; 64 | } 65 | 66 | 67 | blockquote { 68 | border-left: 5px solid #ccc; 69 | margin: 0; 70 | padding: 1px 0 1px 1em; 71 | } 72 | .sections blockquote p { 73 | font-family: Menlo, Consolas, Monaco, monospace; 74 | font-size: 12px; line-height: 16px; 75 | color: #999; 76 | margin: 10px 0 0; 77 | white-space: pre-wrap; 78 | } 79 | 80 | ul.sections { 81 | list-style: none; 82 | padding:0 0 5px 0;; 83 | margin:0; 84 | } 85 | 86 | /* 87 | Force border-box so that % widths fit the parent 88 | container without overlap because of margin/padding. 89 | 90 | More Info : http://www.quirksmode.org/css/box.html 91 | */ 92 | ul.sections > li > div { 93 | -moz-box-sizing: border-box; /* firefox */ 94 | -ms-box-sizing: border-box; /* ie */ 95 | -webkit-box-sizing: border-box; /* webkit */ 96 | -khtml-box-sizing: border-box; /* konqueror */ 97 | box-sizing: border-box; /* css3 */ 98 | } 99 | 100 | 101 | /*---------------------- Jump Page -----------------------------*/ 102 | #jump_to, #jump_page { 103 | margin: 0; 104 | background: white; 105 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 106 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 107 | font: 16px Arial; 108 | cursor: pointer; 109 | text-align: right; 110 | list-style: none; 111 | } 112 | 113 | #jump_to a { 114 | text-decoration: none; 115 | } 116 | 117 | #jump_to a.large { 118 | display: none; 119 | } 120 | #jump_to a.small { 121 | font-size: 22px; 122 | font-weight: bold; 123 | color: #676767; 124 | } 125 | 126 | #jump_to, #jump_wrapper { 127 | position: fixed; 128 | right: 0; top: 0; 129 | padding: 10px 15px; 130 | margin:0; 131 | } 132 | 133 | #jump_wrapper { 134 | display: none; 135 | padding:0; 136 | } 137 | 138 | #jump_to:hover #jump_wrapper { 139 | display: block; 140 | } 141 | 142 | #jump_page_wrapper{ 143 | position: fixed; 144 | right: 0; 145 | top: 0; 146 | bottom: 0; 147 | } 148 | 149 | #jump_page { 150 | padding: 5px 0 3px; 151 | margin: 0 0 25px 25px; 152 | max-height: 100%; 153 | overflow: auto; 154 | } 155 | 156 | #jump_page .source { 157 | display: block; 158 | padding: 15px; 159 | text-decoration: none; 160 | border-top: 1px solid #eee; 161 | } 162 | 163 | #jump_page .source:hover { 164 | background: #f5f5ff; 165 | } 166 | 167 | #jump_page .source:first-child { 168 | } 169 | 170 | /*---------------------- Low resolutions (> 320px) ---------------------*/ 171 | @media only screen and (min-width: 320px) { 172 | .pilwrap { display: none; } 173 | 174 | ul.sections > li > div { 175 | display: block; 176 | padding:5px 10px 0 10px; 177 | } 178 | 179 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 180 | padding-left: 30px; 181 | } 182 | 183 | ul.sections > li > div.content { 184 | overflow-x:auto; 185 | -webkit-box-shadow: inset 0 0 5px #e5e5ee; 186 | box-shadow: inset 0 0 5px #e5e5ee; 187 | border: 1px solid #dedede; 188 | margin:5px 10px 5px 10px; 189 | padding-bottom: 5px; 190 | } 191 | 192 | ul.sections > li > div.annotation pre { 193 | margin: 7px 0 7px; 194 | padding-left: 15px; 195 | } 196 | 197 | ul.sections > li > div.annotation p tt, .annotation code { 198 | background: #f8f8ff; 199 | border: 1px solid #dedede; 200 | font-size: 12px; 201 | padding: 0 0.2em; 202 | } 203 | } 204 | 205 | /*---------------------- (> 481px) ---------------------*/ 206 | @media only screen and (min-width: 481px) { 207 | #container { 208 | position: relative; 209 | } 210 | body { 211 | background-color: #F5F5FF; 212 | font-size: 15px; 213 | line-height: 21px; 214 | } 215 | pre, tt, code { 216 | line-height: 18px; 217 | } 218 | p, ul, ol { 219 | margin: 0 0 15px; 220 | } 221 | 222 | 223 | #jump_to { 224 | padding: 5px 10px; 225 | } 226 | #jump_wrapper { 227 | padding: 0; 228 | } 229 | #jump_to, #jump_page { 230 | font: 10px Arial; 231 | text-transform: uppercase; 232 | } 233 | #jump_page .source { 234 | padding: 5px 10px; 235 | } 236 | #jump_to a.large { 237 | display: inline-block; 238 | } 239 | #jump_to a.small { 240 | display: none; 241 | } 242 | 243 | #background { 244 | position: absolute; 245 | top: 0; bottom: 0; 246 | width: 350px; 247 | background: #fff; 248 | border-right: 1px solid #e5e5ee; 249 | z-index: -1; 250 | } 251 | 252 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 253 | padding-left: 40px; 254 | } 255 | 256 | ul.sections > li { 257 | white-space: nowrap; 258 | } 259 | 260 | ul.sections > li > div { 261 | display: inline-block; 262 | } 263 | 264 | ul.sections > li > div.annotation { 265 | max-width: 350px; 266 | min-width: 350px; 267 | min-height: 5px; 268 | padding: 13px; 269 | overflow-x: hidden; 270 | white-space: normal; 271 | vertical-align: top; 272 | text-align: left; 273 | } 274 | ul.sections > li > div.annotation pre { 275 | margin: 15px 0 15px; 276 | padding-left: 15px; 277 | } 278 | 279 | ul.sections > li > div.content { 280 | padding: 13px; 281 | vertical-align: top; 282 | border: none; 283 | -webkit-box-shadow: none; 284 | box-shadow: none; 285 | } 286 | 287 | .pilwrap { 288 | position: relative; 289 | display: inline; 290 | } 291 | 292 | .pilcrow { 293 | font: 12px Arial; 294 | text-decoration: none; 295 | color: #454545; 296 | position: absolute; 297 | top: 3px; left: -20px; 298 | padding: 1px 2px; 299 | opacity: 0; 300 | -webkit-transition: opacity 0.2s linear; 301 | } 302 | .for-h1 .pilcrow { 303 | top: 47px; 304 | } 305 | .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { 306 | top: 35px; 307 | } 308 | 309 | ul.sections > li > div.annotation:hover .pilcrow { 310 | opacity: 1; 311 | } 312 | } 313 | 314 | /*---------------------- (> 1025px) ---------------------*/ 315 | @media only screen and (min-width: 1025px) { 316 | 317 | body { 318 | font-size: 16px; 319 | line-height: 24px; 320 | } 321 | 322 | #background { 323 | width: 525px; 324 | } 325 | ul.sections > li > div.annotation { 326 | max-width: 525px; 327 | min-width: 525px; 328 | padding: 10px 25px 1px 50px; 329 | } 330 | ul.sections > li > div.content { 331 | padding: 9px 15px 16px 25px; 332 | } 333 | } 334 | 335 | /*---------------------- Syntax Highlighting -----------------------------*/ 336 | 337 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 338 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 339 | /* 340 | 341 | github.com style (c) Vasily Polovnyov 342 | 343 | */ 344 | 345 | pre code { 346 | display: block; padding: 0.5em; 347 | color: #000; 348 | background: #f8f8ff 349 | } 350 | 351 | pre .hljs-comment, 352 | pre .hljs-template_comment, 353 | pre .hljs-diff .hljs-header, 354 | pre .hljs-javadoc { 355 | color: #408080; 356 | font-style: italic 357 | } 358 | 359 | pre .hljs-keyword, 360 | pre .hljs-assignment, 361 | pre .hljs-literal, 362 | pre .hljs-css .hljs-rule .hljs-keyword, 363 | pre .hljs-winutils, 364 | pre .hljs-javascript .hljs-title, 365 | pre .hljs-lisp .hljs-title, 366 | pre .hljs-subst { 367 | color: #954121; 368 | /*font-weight: bold*/ 369 | } 370 | 371 | pre .hljs-number, 372 | pre .hljs-hexcolor { 373 | color: #40a070 374 | } 375 | 376 | pre .hljs-string, 377 | pre .hljs-tag .hljs-value, 378 | pre .hljs-phpdoc, 379 | pre .hljs-tex .hljs-formula { 380 | color: #219161; 381 | } 382 | 383 | pre .hljs-title, 384 | pre .hljs-id { 385 | color: #19469D; 386 | } 387 | pre .hljs-params { 388 | color: #00F; 389 | } 390 | 391 | pre .hljs-javascript .hljs-title, 392 | pre .hljs-lisp .hljs-title, 393 | pre .hljs-subst { 394 | font-weight: normal 395 | } 396 | 397 | pre .hljs-class .hljs-title, 398 | pre .hljs-haskell .hljs-label, 399 | pre .hljs-tex .hljs-command { 400 | color: #458; 401 | font-weight: bold 402 | } 403 | 404 | pre .hljs-tag, 405 | pre .hljs-tag .hljs-title, 406 | pre .hljs-rules .hljs-property, 407 | pre .hljs-django .hljs-tag .hljs-keyword { 408 | color: #000080; 409 | font-weight: normal 410 | } 411 | 412 | pre .hljs-attribute, 413 | pre .hljs-variable, 414 | pre .hljs-instancevar, 415 | pre .hljs-lisp .hljs-body { 416 | color: #008080 417 | } 418 | 419 | pre .hljs-regexp { 420 | color: #B68 421 | } 422 | 423 | pre .hljs-class { 424 | color: #458; 425 | font-weight: bold 426 | } 427 | 428 | pre .hljs-symbol, 429 | pre .hljs-ruby .hljs-symbol .hljs-string, 430 | pre .hljs-ruby .hljs-symbol .hljs-keyword, 431 | pre .hljs-ruby .hljs-symbol .hljs-keymethods, 432 | pre .hljs-lisp .hljs-keyword, 433 | pre .hljs-tex .hljs-special, 434 | pre .hljs-input_number { 435 | color: #990073 436 | } 437 | 438 | pre .hljs-builtin, 439 | pre .hljs-constructor, 440 | pre .hljs-built_in, 441 | pre .hljs-lisp .hljs-title { 442 | color: #0086b3 443 | } 444 | 445 | pre .hljs-preprocessor, 446 | pre .hljs-pi, 447 | pre .hljs-doctype, 448 | pre .hljs-shebang, 449 | pre .hljs-cdata { 450 | color: #999; 451 | font-weight: bold 452 | } 453 | 454 | pre .hljs-deletion { 455 | background: #fdd 456 | } 457 | 458 | pre .hljs-addition { 459 | background: #dfd 460 | } 461 | 462 | pre .hljs-diff .hljs-change { 463 | background: #0086b3 464 | } 465 | 466 | pre .hljs-chunk { 467 | color: #aaa 468 | } 469 | 470 | pre .hljs-tex .hljs-formula { 471 | opacity: 0.5; 472 | } 473 | -------------------------------------------------------------------------------- /docs/docs.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Layout ----------------------------*/ 2 | html { height: 100%; } 3 | body { 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 5 | font-size: 14px; 6 | line-height: 18px; 7 | margin: 0; 8 | padding: 0; 9 | } 10 | 11 | #container { min-height: 100%; } 12 | 13 | p { 14 | margin: 15px 0 0px; 15 | } 16 | .annotation ul, .annotation ol { 17 | margin: 25px 0; 18 | } 19 | .annotation ul li, .annotation ol li { 20 | font-size: 14px; 21 | line-height: 18px; 22 | margin: 10px 0; 23 | } 24 | 25 | h1, h2, h3, h4, h5, h6 { 26 | line-height: 1em; 27 | margin: 30px 0 15px 0; 28 | } 29 | 30 | h1 { 31 | margin-top: 40px; 32 | } 33 | 34 | h2 { 35 | font-size: 1.26em; 36 | } 37 | 38 | hr { 39 | border: 0; 40 | background: 1px #ddd; 41 | height: 1px; 42 | margin: 20px 0; 43 | } 44 | 45 | pre, tt, code { 46 | font-size: 12px; line-height: 16px; 47 | font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; 48 | margin: 0; padding: 0; 49 | } 50 | .annotation pre { 51 | display: block; 52 | margin: 0; 53 | padding: 7px 10px; 54 | background: #fcfcfc; 55 | -moz-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 56 | -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 57 | box-shadow: inset 0 0 10px rgba(0,0,0,0.1); 58 | overflow-x: auto; 59 | } 60 | .annotation pre code { 61 | border: 0; 62 | padding: 0; 63 | background: transparent; 64 | } 65 | 66 | 67 | blockquote { 68 | border-left: 5px solid #ccc; 69 | margin: 0; 70 | padding: 1px 0 1px 1em; 71 | } 72 | .sections blockquote p { 73 | font-family: Menlo, Consolas, Monaco, monospace; 74 | font-size: 12px; line-height: 16px; 75 | color: #999; 76 | margin: 10px 0 0; 77 | white-space: pre-wrap; 78 | } 79 | 80 | ul.sections { 81 | list-style: none; 82 | padding:0 0 5px 0;; 83 | margin:0; 84 | } 85 | 86 | /* 87 | Force border-box so that % widths fit the parent 88 | container without overlap because of margin/padding. 89 | 90 | More Info : http://www.quirksmode.org/css/box.html 91 | */ 92 | ul.sections > li > div { 93 | -moz-box-sizing: border-box; /* firefox */ 94 | -ms-box-sizing: border-box; /* ie */ 95 | -webkit-box-sizing: border-box; /* webkit */ 96 | -khtml-box-sizing: border-box; /* konqueror */ 97 | box-sizing: border-box; /* css3 */ 98 | } 99 | 100 | 101 | /*---------------------- Jump Page -----------------------------*/ 102 | #jump_to, #jump_page { 103 | margin: 0; 104 | background: white; 105 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 106 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 107 | font: 16px Arial; 108 | cursor: pointer; 109 | text-align: right; 110 | list-style: none; 111 | } 112 | 113 | #jump_to a { 114 | text-decoration: none; 115 | } 116 | 117 | #jump_to a.large { 118 | display: none; 119 | } 120 | #jump_to a.small { 121 | font-size: 22px; 122 | font-weight: bold; 123 | color: #676767; 124 | } 125 | 126 | #jump_to, #jump_wrapper { 127 | position: fixed; 128 | right: 0; top: 0; 129 | padding: 10px 15px; 130 | margin:0; 131 | } 132 | 133 | #jump_wrapper { 134 | display: none; 135 | padding:0; 136 | } 137 | 138 | #jump_to:hover #jump_wrapper { 139 | display: block; 140 | } 141 | 142 | #jump_page_wrapper{ 143 | position: fixed; 144 | right: 0; 145 | top: 0; 146 | bottom: 0; 147 | } 148 | 149 | #jump_page { 150 | padding: 5px 0 3px; 151 | margin: 0 0 25px 25px; 152 | max-height: 100%; 153 | overflow: auto; 154 | } 155 | 156 | #jump_page .source { 157 | display: block; 158 | padding: 15px; 159 | text-decoration: none; 160 | border-top: 1px solid #eee; 161 | } 162 | 163 | #jump_page .source:hover { 164 | background: #f5f5ff; 165 | } 166 | 167 | #jump_page .source:first-child { 168 | } 169 | 170 | /*---------------------- Low resolutions (> 320px) ---------------------*/ 171 | @media only screen and (min-width: 320px) { 172 | .pilwrap { display: none; } 173 | 174 | ul.sections > li > div { 175 | display: block; 176 | padding:5px 10px 0 10px; 177 | } 178 | 179 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 180 | padding-left: 30px; 181 | } 182 | 183 | ul.sections > li > div.content { 184 | overflow-x:auto; 185 | -webkit-box-shadow: inset 0 0 5px #e5e5ee; 186 | box-shadow: inset 0 0 5px #e5e5ee; 187 | border: 1px solid #dedede; 188 | margin:5px 10px 5px 10px; 189 | padding-bottom: 5px; 190 | } 191 | 192 | ul.sections > li > div.annotation pre { 193 | margin: 7px 0 7px; 194 | padding-left: 15px; 195 | } 196 | 197 | ul.sections > li > div.annotation p tt, .annotation code { 198 | background: #f8f8ff; 199 | border: 1px solid #dedede; 200 | font-size: 12px; 201 | padding: 0 0.2em; 202 | } 203 | } 204 | 205 | /*---------------------- (> 481px) ---------------------*/ 206 | @media only screen and (min-width: 481px) { 207 | #container { 208 | position: relative; 209 | } 210 | body { 211 | background-color: #F5F5FF; 212 | font-size: 15px; 213 | line-height: 21px; 214 | } 215 | pre, tt, code { 216 | line-height: 18px; 217 | } 218 | p, ul, ol { 219 | margin: 0 0 15px; 220 | } 221 | 222 | 223 | #jump_to { 224 | padding: 5px 10px; 225 | } 226 | #jump_wrapper { 227 | padding: 0; 228 | } 229 | #jump_to, #jump_page { 230 | font: 10px Arial; 231 | text-transform: uppercase; 232 | } 233 | #jump_page .source { 234 | padding: 5px 10px; 235 | } 236 | #jump_to a.large { 237 | display: inline-block; 238 | } 239 | #jump_to a.small { 240 | display: none; 241 | } 242 | 243 | #background { 244 | position: absolute; 245 | top: 0; bottom: 0; 246 | width: 350px; 247 | background: #fff; 248 | border-right: 1px solid #e5e5ee; 249 | z-index: -1; 250 | } 251 | 252 | ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol { 253 | padding-left: 40px; 254 | } 255 | 256 | ul.sections > li { 257 | white-space: nowrap; 258 | } 259 | 260 | ul.sections > li > div { 261 | display: inline-block; 262 | } 263 | 264 | ul.sections > li > div.annotation { 265 | max-width: 350px; 266 | min-width: 350px; 267 | min-height: 5px; 268 | padding: 13px; 269 | overflow-x: hidden; 270 | white-space: normal; 271 | vertical-align: top; 272 | text-align: left; 273 | } 274 | ul.sections > li > div.annotation pre { 275 | margin: 15px 0 15px; 276 | padding-left: 15px; 277 | } 278 | 279 | ul.sections > li > div.content { 280 | padding: 13px; 281 | vertical-align: top; 282 | border: none; 283 | -webkit-box-shadow: none; 284 | box-shadow: none; 285 | } 286 | 287 | .pilwrap { 288 | position: relative; 289 | display: inline; 290 | } 291 | 292 | .pilcrow { 293 | font: 12px Arial; 294 | text-decoration: none; 295 | color: #454545; 296 | position: absolute; 297 | top: 3px; left: -20px; 298 | padding: 1px 2px; 299 | opacity: 0; 300 | -webkit-transition: opacity 0.2s linear; 301 | } 302 | .for-h1 .pilcrow { 303 | top: 47px; 304 | } 305 | .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow { 306 | top: 35px; 307 | } 308 | 309 | ul.sections > li > div.annotation:hover .pilcrow { 310 | opacity: 1; 311 | } 312 | } 313 | 314 | /*---------------------- (> 1025px) ---------------------*/ 315 | @media only screen and (min-width: 1025px) { 316 | 317 | body { 318 | font-size: 16px; 319 | line-height: 24px; 320 | } 321 | 322 | #background { 323 | width: 525px; 324 | } 325 | ul.sections > li > div.annotation { 326 | max-width: 525px; 327 | min-width: 525px; 328 | padding: 10px 25px 1px 50px; 329 | } 330 | ul.sections > li > div.content { 331 | padding: 9px 15px 16px 25px; 332 | } 333 | } 334 | 335 | /*---------------------- Syntax Highlighting -----------------------------*/ 336 | 337 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 338 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 339 | /* 340 | 341 | github.com style (c) Vasily Polovnyov 342 | 343 | */ 344 | 345 | pre code { 346 | display: block; padding: 0.5em; 347 | color: #000; 348 | background: #f8f8ff 349 | } 350 | 351 | pre .hljs-comment, 352 | pre .hljs-template_comment, 353 | pre .hljs-diff .hljs-header, 354 | pre .hljs-javadoc { 355 | color: #408080; 356 | font-style: italic 357 | } 358 | 359 | pre .hljs-keyword, 360 | pre .hljs-assignment, 361 | pre .hljs-literal, 362 | pre .hljs-css .hljs-rule .hljs-keyword, 363 | pre .hljs-winutils, 364 | pre .hljs-javascript .hljs-title, 365 | pre .hljs-lisp .hljs-title, 366 | pre .hljs-subst { 367 | color: #954121; 368 | /*font-weight: bold*/ 369 | } 370 | 371 | pre .hljs-number, 372 | pre .hljs-hexcolor { 373 | color: #40a070 374 | } 375 | 376 | pre .hljs-string, 377 | pre .hljs-tag .hljs-value, 378 | pre .hljs-phpdoc, 379 | pre .hljs-tex .hljs-formula { 380 | color: #219161; 381 | } 382 | 383 | pre .hljs-title, 384 | pre .hljs-id { 385 | color: #19469D; 386 | } 387 | pre .hljs-params { 388 | color: #00F; 389 | } 390 | 391 | pre .hljs-javascript .hljs-title, 392 | pre .hljs-lisp .hljs-title, 393 | pre .hljs-subst { 394 | font-weight: normal 395 | } 396 | 397 | pre .hljs-class .hljs-title, 398 | pre .hljs-haskell .hljs-label, 399 | pre .hljs-tex .hljs-command { 400 | color: #458; 401 | font-weight: bold 402 | } 403 | 404 | pre .hljs-tag, 405 | pre .hljs-tag .hljs-title, 406 | pre .hljs-rules .hljs-property, 407 | pre .hljs-django .hljs-tag .hljs-keyword { 408 | color: #000080; 409 | font-weight: normal 410 | } 411 | 412 | pre .hljs-attribute, 413 | pre .hljs-variable, 414 | pre .hljs-instancevar, 415 | pre .hljs-lisp .hljs-body { 416 | color: #008080 417 | } 418 | 419 | pre .hljs-regexp { 420 | color: #B68 421 | } 422 | 423 | pre .hljs-class { 424 | color: #458; 425 | font-weight: bold 426 | } 427 | 428 | pre .hljs-symbol, 429 | pre .hljs-ruby .hljs-symbol .hljs-string, 430 | pre .hljs-ruby .hljs-symbol .hljs-keyword, 431 | pre .hljs-ruby .hljs-symbol .hljs-keymethods, 432 | pre .hljs-lisp .hljs-keyword, 433 | pre .hljs-tex .hljs-special, 434 | pre .hljs-input_number { 435 | color: #990073 436 | } 437 | 438 | pre .hljs-builtin, 439 | pre .hljs-constructor, 440 | pre .hljs-built_in, 441 | pre .hljs-lisp .hljs-title { 442 | color: #0086b3 443 | } 444 | 445 | pre .hljs-preprocessor, 446 | pre .hljs-pi, 447 | pre .hljs-doctype, 448 | pre .hljs-shebang, 449 | pre .hljs-cdata { 450 | color: #999; 451 | font-weight: bold 452 | } 453 | 454 | pre .hljs-deletion { 455 | background: #fdd 456 | } 457 | 458 | pre .hljs-addition { 459 | background: #dfd 460 | } 461 | 462 | pre .hljs-diff .hljs-change { 463 | background: #0086b3 464 | } 465 | 466 | pre .hljs-chunk { 467 | color: #aaa 468 | } 469 | 470 | pre .hljs-tex .hljs-formula { 471 | opacity: 0.5; 472 | } 473 | -------------------------------------------------------------------------------- /test/lib/jasmine-2.0.1/jasmine-html.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2008-2014 Pivotal Labs 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | jasmineRequire.html = function(j$) { 24 | j$.ResultsNode = jasmineRequire.ResultsNode(); 25 | j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); 26 | j$.QueryString = jasmineRequire.QueryString(); 27 | j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); 28 | }; 29 | 30 | jasmineRequire.HtmlReporter = function(j$) { 31 | 32 | var noopTimer = { 33 | start: function() {}, 34 | elapsed: function() { return 0; } 35 | }; 36 | 37 | function HtmlReporter(options) { 38 | var env = options.env || {}, 39 | getContainer = options.getContainer, 40 | createElement = options.createElement, 41 | createTextNode = options.createTextNode, 42 | onRaiseExceptionsClick = options.onRaiseExceptionsClick || function() {}, 43 | timer = options.timer || noopTimer, 44 | results = [], 45 | specsExecuted = 0, 46 | failureCount = 0, 47 | pendingSpecCount = 0, 48 | htmlReporterMain, 49 | symbols; 50 | 51 | this.initialize = function() { 52 | clearPrior(); 53 | htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'}, 54 | createDom('div', {className: 'banner'}, 55 | createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}), 56 | createDom('span', {className: 'version'}, j$.version) 57 | ), 58 | createDom('ul', {className: 'symbol-summary'}), 59 | createDom('div', {className: 'alert'}), 60 | createDom('div', {className: 'results'}, 61 | createDom('div', {className: 'failures'}) 62 | ) 63 | ); 64 | getContainer().appendChild(htmlReporterMain); 65 | 66 | symbols = find('.symbol-summary'); 67 | }; 68 | 69 | var totalSpecsDefined; 70 | this.jasmineStarted = function(options) { 71 | totalSpecsDefined = options.totalSpecsDefined || 0; 72 | timer.start(); 73 | }; 74 | 75 | var summary = createDom('div', {className: 'summary'}); 76 | 77 | var topResults = new j$.ResultsNode({}, '', null), 78 | currentParent = topResults; 79 | 80 | this.suiteStarted = function(result) { 81 | currentParent.addChild(result, 'suite'); 82 | currentParent = currentParent.last(); 83 | }; 84 | 85 | this.suiteDone = function(result) { 86 | if (currentParent == topResults) { 87 | return; 88 | } 89 | 90 | currentParent = currentParent.parent; 91 | }; 92 | 93 | this.specStarted = function(result) { 94 | currentParent.addChild(result, 'spec'); 95 | }; 96 | 97 | var failures = []; 98 | this.specDone = function(result) { 99 | if(noExpectations(result) && console && console.error) { 100 | console.error('Spec \'' + result.fullName + '\' has no expectations.'); 101 | } 102 | 103 | if (result.status != 'disabled') { 104 | specsExecuted++; 105 | } 106 | 107 | symbols.appendChild(createDom('li', { 108 | className: noExpectations(result) ? 'empty' : result.status, 109 | id: 'spec_' + result.id, 110 | title: result.fullName 111 | } 112 | )); 113 | 114 | if (result.status == 'failed') { 115 | failureCount++; 116 | 117 | var failure = 118 | createDom('div', {className: 'spec-detail failed'}, 119 | createDom('div', {className: 'description'}, 120 | createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName) 121 | ), 122 | createDom('div', {className: 'messages'}) 123 | ); 124 | var messages = failure.childNodes[1]; 125 | 126 | for (var i = 0; i < result.failedExpectations.length; i++) { 127 | var expectation = result.failedExpectations[i]; 128 | messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message)); 129 | messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack)); 130 | } 131 | 132 | failures.push(failure); 133 | } 134 | 135 | if (result.status == 'pending') { 136 | pendingSpecCount++; 137 | } 138 | }; 139 | 140 | this.jasmineDone = function() { 141 | var banner = find('.banner'); 142 | banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's')); 143 | 144 | var alert = find('.alert'); 145 | 146 | alert.appendChild(createDom('span', { className: 'exceptions' }, 147 | createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'), 148 | createDom('input', { 149 | className: 'raise', 150 | id: 'raise-exceptions', 151 | type: 'checkbox' 152 | }) 153 | )); 154 | var checkbox = find('#raise-exceptions'); 155 | 156 | checkbox.checked = !env.catchingExceptions(); 157 | checkbox.onclick = onRaiseExceptionsClick; 158 | 159 | if (specsExecuted < totalSpecsDefined) { 160 | var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all'; 161 | alert.appendChild( 162 | createDom('span', {className: 'bar skipped'}, 163 | createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage) 164 | ) 165 | ); 166 | } 167 | var statusBarMessage = ''; 168 | var statusBarClassName = 'bar '; 169 | 170 | if (totalSpecsDefined > 0) { 171 | statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount); 172 | if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); } 173 | statusBarClassName += (failureCount > 0) ? 'failed' : 'passed'; 174 | } else { 175 | statusBarClassName += 'skipped'; 176 | statusBarMessage += 'No specs found'; 177 | } 178 | 179 | alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage)); 180 | 181 | var results = find('.results'); 182 | results.appendChild(summary); 183 | 184 | summaryList(topResults, summary); 185 | 186 | function summaryList(resultsTree, domParent) { 187 | var specListNode; 188 | for (var i = 0; i < resultsTree.children.length; i++) { 189 | var resultNode = resultsTree.children[i]; 190 | if (resultNode.type == 'suite') { 191 | var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id}, 192 | createDom('li', {className: 'suite-detail'}, 193 | createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description) 194 | ) 195 | ); 196 | 197 | summaryList(resultNode, suiteListNode); 198 | domParent.appendChild(suiteListNode); 199 | } 200 | if (resultNode.type == 'spec') { 201 | if (domParent.getAttribute('class') != 'specs') { 202 | specListNode = createDom('ul', {className: 'specs'}); 203 | domParent.appendChild(specListNode); 204 | } 205 | var specDescription = resultNode.result.description; 206 | if(noExpectations(resultNode.result)) { 207 | specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription; 208 | } 209 | specListNode.appendChild( 210 | createDom('li', { 211 | className: resultNode.result.status, 212 | id: 'spec-' + resultNode.result.id 213 | }, 214 | createDom('a', {href: specHref(resultNode.result)}, specDescription) 215 | ) 216 | ); 217 | } 218 | } 219 | } 220 | 221 | if (failures.length) { 222 | alert.appendChild( 223 | createDom('span', {className: 'menu bar spec-list'}, 224 | createDom('span', {}, 'Spec List | '), 225 | createDom('a', {className: 'failures-menu', href: '#'}, 'Failures'))); 226 | alert.appendChild( 227 | createDom('span', {className: 'menu bar failure-list'}, 228 | createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'), 229 | createDom('span', {}, ' | Failures '))); 230 | 231 | find('.failures-menu').onclick = function() { 232 | setMenuModeTo('failure-list'); 233 | }; 234 | find('.spec-list-menu').onclick = function() { 235 | setMenuModeTo('spec-list'); 236 | }; 237 | 238 | setMenuModeTo('failure-list'); 239 | 240 | var failureNode = find('.failures'); 241 | for (var i = 0; i < failures.length; i++) { 242 | failureNode.appendChild(failures[i]); 243 | } 244 | } 245 | }; 246 | 247 | return this; 248 | 249 | function find(selector) { 250 | return getContainer().querySelector('.jasmine_html-reporter ' + selector); 251 | } 252 | 253 | function clearPrior() { 254 | // return the reporter 255 | var oldReporter = find(''); 256 | 257 | if(oldReporter) { 258 | getContainer().removeChild(oldReporter); 259 | } 260 | } 261 | 262 | function createDom(type, attrs, childrenVarArgs) { 263 | var el = createElement(type); 264 | 265 | for (var i = 2; i < arguments.length; i++) { 266 | var child = arguments[i]; 267 | 268 | if (typeof child === 'string') { 269 | el.appendChild(createTextNode(child)); 270 | } else { 271 | if (child) { 272 | el.appendChild(child); 273 | } 274 | } 275 | } 276 | 277 | for (var attr in attrs) { 278 | if (attr == 'className') { 279 | el[attr] = attrs[attr]; 280 | } else { 281 | el.setAttribute(attr, attrs[attr]); 282 | } 283 | } 284 | 285 | return el; 286 | } 287 | 288 | function pluralize(singular, count) { 289 | var word = (count == 1 ? singular : singular + 's'); 290 | 291 | return '' + count + ' ' + word; 292 | } 293 | 294 | function specHref(result) { 295 | return '?spec=' + encodeURIComponent(result.fullName); 296 | } 297 | 298 | function setMenuModeTo(mode) { 299 | htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode); 300 | } 301 | 302 | function noExpectations(result) { 303 | return (result.failedExpectations.length + result.passedExpectations.length) === 0 && 304 | result.status === 'passed'; 305 | } 306 | } 307 | 308 | return HtmlReporter; 309 | }; 310 | 311 | jasmineRequire.HtmlSpecFilter = function() { 312 | function HtmlSpecFilter(options) { 313 | var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); 314 | var filterPattern = new RegExp(filterString); 315 | 316 | this.matches = function(specName) { 317 | return filterPattern.test(specName); 318 | }; 319 | } 320 | 321 | return HtmlSpecFilter; 322 | }; 323 | 324 | jasmineRequire.ResultsNode = function() { 325 | function ResultsNode(result, type, parent) { 326 | this.result = result; 327 | this.type = type; 328 | this.parent = parent; 329 | 330 | this.children = []; 331 | 332 | this.addChild = function(result, type) { 333 | this.children.push(new ResultsNode(result, type, this)); 334 | }; 335 | 336 | this.last = function() { 337 | return this.children[this.children.length - 1]; 338 | }; 339 | } 340 | 341 | return ResultsNode; 342 | }; 343 | 344 | jasmineRequire.QueryString = function() { 345 | function QueryString(options) { 346 | 347 | this.setParam = function(key, value) { 348 | var paramMap = queryStringToParamMap(); 349 | paramMap[key] = value; 350 | options.getWindowLocation().search = toQueryString(paramMap); 351 | }; 352 | 353 | this.getParam = function(key) { 354 | return queryStringToParamMap()[key]; 355 | }; 356 | 357 | return this; 358 | 359 | function toQueryString(paramMap) { 360 | var qStrPairs = []; 361 | for (var prop in paramMap) { 362 | qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])); 363 | } 364 | return '?' + qStrPairs.join('&'); 365 | } 366 | 367 | function queryStringToParamMap() { 368 | var paramStr = options.getWindowLocation().search.substring(1), 369 | params = [], 370 | paramMap = {}; 371 | 372 | if (paramStr.length > 0) { 373 | params = paramStr.split('&'); 374 | for (var i = 0; i < params.length; i++) { 375 | var p = params[i].split('='); 376 | var value = decodeURIComponent(p[1]); 377 | if (value === 'true' || value === 'false') { 378 | value = JSON.parse(value); 379 | } 380 | paramMap[decodeURIComponent(p[0])] = value; 381 | } 382 | } 383 | 384 | return paramMap; 385 | } 386 | 387 | } 388 | 389 | return QueryString; 390 | }; 391 | -------------------------------------------------------------------------------- /test/lib/jasmine-2.0.1/jasmine.css: -------------------------------------------------------------------------------- 1 | body { overflow-y: scroll; } 2 | 3 | .jasmine_html-reporter { background-color: #eeeeee; padding: 5px; margin: -8px; font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; } 4 | .jasmine_html-reporter a { text-decoration: none; } 5 | .jasmine_html-reporter a:hover { text-decoration: underline; } 6 | .jasmine_html-reporter p, .jasmine_html-reporter h1, .jasmine_html-reporter h2, .jasmine_html-reporter h3, .jasmine_html-reporter h4, .jasmine_html-reporter h5, .jasmine_html-reporter h6 { margin: 0; line-height: 14px; } 7 | .jasmine_html-reporter .banner, .jasmine_html-reporter .symbol-summary, .jasmine_html-reporter .summary, .jasmine_html-reporter .result-message, .jasmine_html-reporter .spec .description, .jasmine_html-reporter .spec-detail .description, .jasmine_html-reporter .alert .bar, .jasmine_html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; } 8 | .jasmine_html-reporter .banner { position: relative; } 9 | .jasmine_html-reporter .banner .title { background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAAZCAMAAACGusnyAAACdlBMVEX/////AP+AgICqVaqAQICZM5mAVYCSSZKAQICOOY6ATYCLRouAQICJO4mSSYCIRIiPQICHPIeOR4CGQ4aMQICGPYaLRoCFQ4WKQICPPYWJRYCOQoSJQICNPoSIRICMQoSHQICHRICKQoOHQICKPoOJO4OJQYOMQICMQ4CIQYKLQICIPoKLQ4CKQICNPoKJQISMQ4KJQoSLQYKJQISLQ4KIQoSKQYKIQICIQISMQoSKQYKLQIOLQoOJQYGLQIOKQIOMQoGKQYOLQYGKQIOLQoGJQYOJQIOKQYGJQIOKQoGKQIGLQIKLQ4KKQoGLQYKJQIGKQYKJQIGKQIKJQoGKQYKLQIGKQYKLQIOJQoKKQoOJQYKKQIOJQoKKQoOKQIOLQoKKQYOLQYKJQIOKQoKKQYKKQoKJQYOKQYKLQIOKQoKLQYOKQYKLQIOJQoGKQYKJQYGJQoGKQYKLQoGLQYGKQoGJQYKKQYGJQIKKQoGJQYKLQIKKQYGLQYKKQYGKQYGKQYKJQYOKQoKJQYOKQYKLQYOLQYOKQYKLQYOKQoKKQYKKQYOKQYOJQYKKQYKLQYKKQIKKQoKKQYKKQYKKQoKJQIKKQYKLQYKKQYKKQIKKQYKKQYKKQYKKQIKKQYKJQYGLQYGKQYKKQYKKQYGKQIKKQYGKQYOJQoKKQYOLQYKKQYOKQoKKQYKKQoKKQYKKQYKJQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKJQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKLQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKKQYKmIDpEAAAA0XRSTlMAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAiIyQlJycoKissLS4wMTQ1Njc4OTo7PDw+P0BCQ0RISUpLTE1OUFNUVVdYWFlaW15fYGFiY2ZnaGlqa2xtb3BxcnN0dnh5ent8fX5/gIGChIWIioyNjo+QkZOUlZaYmZqbnJ2eoKGio6WmqKmsra6vsLGztre4ubq7vL2+wMHDxMjJysvNzs/Q0dLU1tfY2dvc3t/g4eLj5ebn6Onq6+zt7u/w8vP09fb3+Pn6+/z9/vkVQXAAAAMaSURBVHhe5dXxV1N1GMfxz2ABbDgIAm5VDJOyVDIJLUMaVpBWUZUaGbmqoGpZRSiGiRWp6KoZ5AB0ZY50RImZQIlahKkMYXv/R90dBvET/rJfOr3Ouc8v99zPec59zvf56j+vYKlViSf7250X4Mr3O29Tgq08BdGB4DhcekEJ5YkQKFsgWZdtj9JpV+I8xPjLFqkrsEIqO8PHSpis36jWazcqjEsfJjkvRssVU37SdIOu4XCf5vEJPsnwJpnRNU9JmxhMk8l1gehIrq7hTFjzOD+Vf88629qKMJVNltInFeRexRQyJlNeqd1iGDlSzrIUIyXbyFfm3RYprcQRe7lqtWyGYbfc6dT0R2vmdOOkX3u55C1rP37ftiH+tDby4r/RBT0w8TyEkr+epB9XgPDmSYYWbrhCuFYaIyw3fDQAXTnSkh+ANofiHmWf9l+FY1I90FdQTetstO00o23novzVsJ7uB3/C5TkbjRwZ5JerwV4iRWq9HFbFMaK/d0TYqayRiQPuIxxS3Bu8JWU90/60tKi7vkhaznez0a/TbVOKj5CaOZh6fWG6/Lyv9B/ZLR1gw/S/fpbeVD3MCW1li6SvWDOn65tr99/uvWtBS0XDm4s1t+sOHpG0kpBKx/l77wOSnxLpcx6TXmXLTPQOKYOf9Q1dfr8/SJ2mFdCvl1Yl93DiHUZvXeLJbGSzYu5gVJ2slbSakOR8dxCq5adQ2oFLqsE9Ex3L4qQO0eOPeU5x56bypXp4onSEb5OkICX6lDat55TeoztNKQcJaakrz9KCb95oD69IKq+yKW4XPjknaS52V0TZqE2cTtXjcHSCRmUO88e+85hj3EP74i9p8pylw7lxgMDyyl6OV7ZejnjNMfatu87LxRbH0IS35gt2a4ZjmGpVBdKK3Wr6INk8jWWSGqbA55CKgjBRC6E9w78ydTg3ABS3AFV1QN0Y4Aa2pgEjWnQURj9L0ayK6R2ysEqxHUKzYnLvvyU+i9KM2JHJzE4vyZOyDcOwOsySajeLPc8sNvPJkFlyJd20wpqAzZeAfZ3oWybxd+P/3j+SG3uSBdf2VQAAAABJRU5ErkJggg==') no-repeat; background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmVyc2lvbj0iMS4xIgogICB3aWR0aD0iNjgxLjk2MjUyIgogICBoZWlnaHQ9IjE4Ny41IgogICBpZD0ic3ZnMiIKICAgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhOCI+PHJkZjpSREY+PGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMKICAgICBpZD0iZGVmczYiPjxjbGlwUGF0aAogICAgICAgaWQ9ImNsaXBQYXRoMTgiPjxwYXRoCiAgICAgICAgIGQ9Ik0gMCwxNTAwIDAsMCBsIDU0NTUuNzQsMCAwLDE1MDAgTCAwLDE1MDAgeiIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgaWQ9InBhdGgyMCIgLz48L2NsaXBQYXRoPjwvZGVmcz48ZwogICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUsMCwwLC0xLjI1LDAsMTg3LjUpIgogICAgIGlkPSJnMTAiPjxnCiAgICAgICB0cmFuc2Zvcm09InNjYWxlKDAuMSwwLjEpIgogICAgICAgaWQ9ImcxMiI+PGcKICAgICAgICAgaWQ9ImcxNCI+PGcKICAgICAgICAgICBjbGlwLXBhdGg9InVybCgjY2xpcFBhdGgxOCkiCiAgICAgICAgICAgaWQ9ImcxNiI+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTU0NCw1OTkuNDM0IGMgMC45MiwtNDAuMzUyIDI1LjY4LC04MS42MDIgNzEuNTMsLTgxLjYwMiAyNy41MSwwIDQ3LjY4LDEyLjgzMiA2MS40NCwzNS43NTQgMTIuODMsMjIuOTMgMTIuODMsNTYuODUyIDEyLjgzLDgyLjUyNyBsIDAsMzI5LjE4NCAtNzEuNTIsMCAwLDEwNC41NDMgMjY2LjgzLDAgMCwtMTA0LjU0MyAtNzAuNiwwIDAsLTM0NC43NyBjIDAsLTU4LjY5MSAtMy42OCwtMTA0LjUzMSAtNDQuOTMsLTE1Mi4yMTggLTM2LjY4LC00Mi4xOCAtOTYuMjgsLTY2LjAyIC0xNTMuMTQsLTY2LjAyIC0xMTcuMzcsMCAtMjA3LjI0LDc3Ljk0MSAtMjAyLjY0LDE5Ny4xNDUgbCAxMzAuMiwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMjIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDIzMDEuNCw2NjIuNjk1IGMgMCw4MC43MDMgLTY2Ljk0LDE0NS44MTMgLTE0Ny42MywxNDUuODEzIC04My40NCwwIC0xNDcuNjMsLTY4Ljc4MSAtMTQ3LjYzLC0xNTEuMzAxIDAsLTc5Ljc4NSA2Ni45NCwtMTQ1LjgwMSAxNDUuOCwtMTQ1LjgwMSA4NC4zNSwwIDE0OS40Niw2Ny44NTIgMTQ5LjQ2LDE1MS4yODkgeiBtIC0xLjgzLC0xODEuNTQ3IGMgLTM1Ljc3LC01NC4wOTcgLTkzLjUzLC03OC44NTkgLTE1Ny43MiwtNzguODU5IC0xNDAuMywwIC0yNTEuMjQsMTE2LjQ0OSAtMjUxLjI0LDI1NC45MTggMCwxNDIuMTI5IDExMy43LDI2MC40MSAyNTYuNzQsMjYwLjQxIDYzLjI3LDAgMTE4LjI5LC0yOS4zMzYgMTUyLjIyLC04Mi41MjMgbCAwLDY5LjY4NyAxNzUuMTQsMCAwLC0xMDQuNTI3IC02MS40NCwwIDAsLTI4MC41OTggNjEuNDQsMCAwLC0xMDQuNTI3IC0xNzUuMTQsMCAwLDY2LjAxOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAyNjIyLjMzLDU1Ny4yNTggYyAzLjY3LC00NC4wMTYgMzMuMDEsLTczLjM0OCA3OC44NiwtNzMuMzQ4IDMzLjkzLDAgNjYuOTMsMjMuODI0IDY2LjkzLDYwLjUwNCAwLDQ4LjYwNiAtNDUuODQsNTYuODU2IC04My40NCw2Ni45NDEgLTg1LjI4LDIyLjAwNCAtMTc4LjgxLDQ4LjYwNiAtMTc4LjgxLDE1NS44NzkgMCw5My41MzYgNzguODYsMTQ3LjYzMyAxNjUuOTgsMTQ3LjYzMyA0NCwwIDgzLjQzLC05LjE3NiAxMTAuOTQsLTQ0LjAwOCBsIDAsMzMuOTIyIDgyLjUzLDAgMCwtMTMyLjk2NSAtMTA4LjIxLDAgYyAtMS44MywzNC44NTYgLTI4LjQyLDU3Ljc3NCAtNjMuMjYsNTcuNzc0IC0zMC4yNiwwIC02Mi4zNSwtMTcuNDIyIC02Mi4zNSwtNTEuMzQ4IDAsLTQ1Ljg0NyA0NC45MywtNTUuOTMgODAuNjksLTY0LjE4IDg4LjAyLC0yMC4xNzUgMTgyLjQ3LC00Ny42OTUgMTgyLjQ3LC0xNTcuNzM0IDAsLTk5LjAyNyAtODMuNDQsLTE1NC4wMzkgLTE3NS4xMywtMTU0LjAzOSAtNDkuNTMsMCAtOTQuNDYsMTUuNTgyIC0xMjYuNTUsNTMuMTggbCAwLC00MC4zNCAtODUuMjcsMCAwLDE0Mi4xMjkgMTE0LjYyLDAiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGgyNiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMjk4OC4xOCw4MDAuMjU0IC02My4yNiwwIDAsMTA0LjUyNyAxNjUuMDUsMCAwLC03My4zNTUgYyAzMS4xOCw1MS4zNDcgNzguODYsODUuMjc3IDE0MS4yMSw4NS4yNzcgNjcuODUsMCAxMjQuNzEsLTQxLjI1OCAxNTIuMjEsLTEwMi42OTkgMjYuNiw2Mi4zNTEgOTIuNjIsMTAyLjY5OSAxNjAuNDcsMTAyLjY5OSA1My4xOSwwIDEwNS40NiwtMjIgMTQxLjIxLC02Mi4zNTEgMzguNTIsLTQ0LjkzOCAzOC41MiwtOTMuNTMyIDM4LjUyLC0xNDkuNDU3IGwgMCwtMTg1LjIzOSA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40MiwwIDAsMTA0LjUyNyA2My4yOCwwIDAsMTU3LjcxNSBjIDAsMzIuMTAyIDAsNjAuNTI3IC0xNC42Nyw4OC45NTcgLTE4LjM0LDI2LjU4MiAtNDguNjEsNDAuMzQ0IC03OS43Nyw0MC4zNDQgLTMwLjI2LDAgLTYzLjI4LC0xMi44NDQgLTgyLjUzLC0zNi42NzIgLTIyLjkzLC0yOS4zNTUgLTIyLjkzLC01Ni44NjMgLTIyLjkzLC05Mi42MjkgbCAwLC0xNTcuNzE1IDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM4LjQxLDAgMCwxMDQuNTI3IDYzLjI4LDAgMCwxNTAuMzgzIGMgMCwyOS4zNDggMCw2Ni4wMjMgLTE0LjY3LDkxLjY5OSAtMTUuNTksMjkuMzM2IC00Ny42OSw0NC45MzQgLTgwLjcsNDQuOTM0IC0zMS4xOCwwIC01Ny43NywtMTEuMDA4IC03Ny45NCwtMzUuNzc0IC0yNC43NywtMzAuMjUzIC0yNi42LC02Mi4zNDMgLTI2LjYsLTk5Ljk0MSBsIDAsLTE1MS4zMDEgNjMuMjcsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNiwwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDI4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSAzOTk4LjY2LDk1MS41NDcgLTExMS44NywwIDAsMTE4LjI5MyAxMTEuODcsMCAwLC0xMTguMjkzIHogbSAwLC00MzEuODkxIDYzLjI3LDAgMCwtMTA0LjUyNyAtMjM5LjMzLDAgMCwxMDQuNTI3IDY0LjE5LDAgMCwyODAuNTk4IC02My4yNywwIDAsMTA0LjUyNyAxNzUuMTQsMCAwLC0zODUuMTI1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzAiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDQxNTkuMTIsODAwLjI1NCAtNjMuMjcsMCAwLDEwNC41MjcgMTc1LjE0LDAgMCwtNjkuNjg3IGMgMjkuMzUsNTQuMTAxIDg0LjM2LDgwLjY5OSAxNDQuODcsODAuNjk5IDUzLjE5LDAgMTA1LjQ1LC0yMi4wMTYgMTQxLjIyLC02MC41MjcgNDAuMzQsLTQ0LjkzNCA0MS4yNiwtODguMDMyIDQxLjI2LC0xNDMuOTU3IGwgMCwtMTkxLjY1MyA2My4yNywwIDAsLTEwNC41MjcgLTIzOC40LDAgMCwxMDQuNTI3IDYzLjI2LDAgMCwxNTguNjM3IGMgMCwzMC4yNjIgMCw2MS40MzQgLTE5LjI2LDg4LjAzNSAtMjAuMTcsMjYuNTgyIC01My4xOCwzOS40MTQgLTg2LjE5LDM5LjQxNCAtMzMuOTMsMCAtNjguNzcsLTEzLjc1IC04OC45NCwtNDEuMjUgLTIxLjA5LC0yNy41IC0yMS4wOSwtNjkuNjg3IC0yMS4wOSwtMTAyLjcwNyBsIDAsLTE0Mi4xMjkgNjMuMjYsMCAwLC0xMDQuNTI3IC0yMzguNCwwIDAsMTA0LjUyNyA2My4yNywwIDAsMjgwLjU5OCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDMyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA1MDgyLjQ4LDcwMy45NjUgYyAtMTkuMjQsNzAuNjA1IC04MS42LDExNS41NDcgLTE1NC4wNCwxMTUuNTQ3IC02Ni4wNCwwIC0xMjkuMywtNTEuMzQ4IC0xNDMuMDUsLTExNS41NDcgbCAyOTcuMDksMCB6IG0gODUuMjcsLTE0NC44ODMgYyAtMzguNTEsLTkzLjUyMyAtMTI5LjI3LC0xNTYuNzkzIC0yMzEuMDUsLTE1Ni43OTMgLTE0My4wNywwIC0yNTcuNjgsMTExLjg3MSAtMjU3LjY4LDI1NS44MzYgMCwxNDQuODgzIDEwOS4xMiwyNjEuMzI4IDI1NC45MSwyNjEuMzI4IDY3Ljg3LDAgMTM1LjcyLC0zMC4yNTggMTgzLjM5LC03OC44NjMgNDguNjIsLTUxLjM0NCA2OC43OSwtMTEzLjY5NSA2OC43OSwtMTgzLjM4MyBsIC0zLjY3LC0zOS40MzQgLTM5Ni4xMywwIGMgMTQuNjcsLTY3Ljg2MyA3Ny4wMywtMTE3LjM2MyAxNDYuNzIsLTExNy4zNjMgNDguNTksMCA5MC43NiwxOC4zMjggMTE4LjI4LDU4LjY3MiBsIDExNi40NCwwIgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDY5MC44OTUsODUwLjcwMyA5MC43NSwwIDIyLjU0MywzMS4wMzUgMCwyNDMuMTIyIC0xMzUuODI5LDAgMCwtMjQzLjE0MSAyMi41MzYsLTMxLjAxNiIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA2MzIuMzk1LDc0Mi4yNTggMjguMDM5LDg2LjMwNCAtMjIuNTUxLDMxLjA0IC0yMzEuMjIzLDc1LjEyOCAtNDEuOTc2LC0xMjkuMTgzIDIzMS4yNTcsLTc1LjEzNyAzNi40NTQsMTEuODQ4IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoMzgiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDcxNy40NDksNjUzLjEwNSAtNzMuNDEsNTMuMzYgLTM2LjQ4OCwtMTEuODc1IC0xNDIuOTAzLC0xOTYuNjkyIDEwOS44ODMsLTc5LjgyOCAxNDIuOTE4LDE5Ni43MDMgMCwzOC4zMzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0MCIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gODI4LjUyLDcwNi40NjUgLTczLjQyNiwtNTMuMzQgMC4wMTEsLTM4LjM1OSBMIDg5OC4wMDQsNDE4LjA3IDEwMDcuOSw0OTcuODk4IDg2NC45NzMsNjk0LjYwOSA4MjguNTIsNzA2LjQ2NSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQyIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA4MTIuMDg2LDgyOC41ODYgMjguMDU1LC04Ni4zMiAzNi40ODQsLTExLjgzNiAyMzEuMjI1LDc1LjExNyAtNDEuOTcsMTI5LjE4MyAtMjMxLjIzOSwtNzUuMTQgLTIyLjU1NSwtMzEuMDA0IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNDQiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDczNi4zMDEsMTMzNS44OCBjIC0zMjMuMDQ3LDAgLTU4NS44NzUsLTI2Mi43OCAtNTg1Ljg3NSwtNTg1Ljc4MiAwLC0zMjMuMTE4IDI2Mi44MjgsLTU4NS45NzcgNTg1Ljg3NSwtNTg1Ljk3NyAzMjMuMDE5LDAgNTg1LjgwOSwyNjIuODU5IDU4NS44MDksNTg1Ljk3NyAwLDMyMy4wMDIgLTI2Mi43OSw1ODUuNzgyIC01ODUuODA5LDU4NS43ODIgbCAwLDAgeiBtIDAsLTExOC42MSBjIDI1Ny45NzIsMCA0NjcuMTg5LC0yMDkuMTMgNDY3LjE4OSwtNDY3LjE3MiAwLC0yNTguMTI5IC0yMDkuMjE3LC00NjcuMzQ4IC00NjcuMTg5LC00NjcuMzQ4IC0yNTguMDc0LDAgLTQ2Ny4yNTQsMjA5LjIxOSAtNDY3LjI1NCw0NjcuMzQ4IDAsMjU4LjA0MiAyMDkuMTgsNDY3LjE3MiA0NjcuMjU0LDQ2Ny4xNzIiCiAgICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICAgICAgICAgICAgaWQ9InBhdGg0NiIKICAgICAgICAgICAgIHN0eWxlPSJmaWxsOiM4YTQxODI7ZmlsbC1vcGFjaXR5OjE7ZmlsbC1ydWxlOm5vbnplcm87c3Ryb2tlOm5vbmUiIC8+PHBhdGgKICAgICAgICAgICAgIGQ9Im0gMTA5MS4xMyw2MTkuODgzIC0xNzUuNzcxLDU3LjEyMSAxMS42MjksMzUuODA4IDE3NS43NjIsLTU3LjEyMSAtMTEuNjIsLTM1LjgwOCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDQ4IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA4NjYuOTU3LDkwMi4wNzQgODM2LjUsOTI0LjE5OSA5NDUuMTIxLDEwNzMuNzMgOTc1LjU4NiwxMDUxLjYxIDg2Ni45NTcsOTAyLjA3NCIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDUwIgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0iTSA2MDcuNDY1LDkwMy40NDUgNDk4Ljg1NSwxMDUyLjk3IDUyOS4zMiwxMDc1LjEgNjM3LjkzLDkyNS41NjYgNjA3LjQ2NSw5MDMuNDQ1IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTIiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjxwYXRoCiAgICAgICAgICAgICBkPSJtIDM4MC42ODgsNjIyLjEyOSAtMTEuNjI2LDM1LjgwMSAxNzUuNzU4LDU3LjA5IDExLjYyMSwtMzUuODAxIC0xNzUuNzUzLC01Ny4wOSIKICAgICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiCiAgICAgICAgICAgICBpZD0icGF0aDU0IgogICAgICAgICAgICAgc3R5bGU9ImZpbGw6IzhhNDE4MjtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6bm9uemVybztzdHJva2U6bm9uZSIgLz48cGF0aAogICAgICAgICAgICAgZD0ibSA3MTYuMjg5LDM3Ni41OSAzNy42NDA2LDAgMCwxODQuODE2IC0zNy42NDA2LDAgMCwtMTg0LjgxNiB6IgogICAgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIKICAgICAgICAgICAgIGlkPSJwYXRoNTYiCiAgICAgICAgICAgICBzdHlsZT0iZmlsbDojOGE0MTgyO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpub256ZXJvO3N0cm9rZTpub25lIiAvPjwvZz48L2c+PC9nPjwvZz48L3N2Zz4=') no-repeat, none; -webkit-background-size: 100%; -moz-background-size: 100%; -o-background-size: 100%; background-size: 100%; display: block; float: left; width: 90px; height: 25px; } 10 | .jasmine_html-reporter .banner .version { margin-left: 14px; position: relative; top: 6px; } 11 | .jasmine_html-reporter .banner .duration { position: absolute; right: 14px; top: 6px; } 12 | .jasmine_html-reporter #jasmine_content { position: fixed; right: 100%; } 13 | .jasmine_html-reporter .version { color: #aaaaaa; } 14 | .jasmine_html-reporter .banner { margin-top: 14px; } 15 | .jasmine_html-reporter .duration { color: #aaaaaa; float: right; } 16 | .jasmine_html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; } 17 | .jasmine_html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; } 18 | .jasmine_html-reporter .symbol-summary li.passed { font-size: 14px; } 19 | .jasmine_html-reporter .symbol-summary li.passed:before { color: #007069; content: "\02022"; } 20 | .jasmine_html-reporter .symbol-summary li.failed { line-height: 9px; } 21 | .jasmine_html-reporter .symbol-summary li.failed:before { color: #ca3a11; content: "\d7"; font-weight: bold; margin-left: -1px; } 22 | .jasmine_html-reporter .symbol-summary li.disabled { font-size: 14px; } 23 | .jasmine_html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; } 24 | .jasmine_html-reporter .symbol-summary li.pending { line-height: 17px; } 25 | .jasmine_html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; } 26 | .jasmine_html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; } 27 | .jasmine_html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; } 28 | .jasmine_html-reporter .bar.failed { background-color: #ca3a11; } 29 | .jasmine_html-reporter .bar.passed { background-color: #007069; } 30 | .jasmine_html-reporter .bar.skipped { background-color: #bababa; } 31 | .jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; } 32 | .jasmine_html-reporter .bar.menu a { color: #333333; } 33 | .jasmine_html-reporter .bar a { color: white; } 34 | .jasmine_html-reporter.spec-list .bar.menu.failure-list, .jasmine_html-reporter.spec-list .results .failures { display: none; } 35 | .jasmine_html-reporter.failure-list .bar.menu.spec-list, .jasmine_html-reporter.failure-list .summary { display: none; } 36 | .jasmine_html-reporter .running-alert { background-color: #666666; } 37 | .jasmine_html-reporter .results { margin-top: 14px; } 38 | .jasmine_html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; } 39 | .jasmine_html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; } 40 | .jasmine_html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; } 41 | .jasmine_html-reporter.showDetails .summary { display: none; } 42 | .jasmine_html-reporter.showDetails #details { display: block; } 43 | .jasmine_html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; } 44 | .jasmine_html-reporter .summary { margin-top: 14px; } 45 | .jasmine_html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; } 46 | .jasmine_html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; } 47 | .jasmine_html-reporter .summary li.passed a { color: #007069; } 48 | .jasmine_html-reporter .summary li.failed a { color: #ca3a11; } 49 | .jasmine_html-reporter .summary li.empty a { color: #ba9d37; } 50 | .jasmine_html-reporter .summary li.pending a { color: #ba9d37; } 51 | .jasmine_html-reporter .description + .suite { margin-top: 0; } 52 | .jasmine_html-reporter .suite { margin-top: 14px; } 53 | .jasmine_html-reporter .suite a { color: #333333; } 54 | .jasmine_html-reporter .failures .spec-detail { margin-bottom: 28px; } 55 | .jasmine_html-reporter .failures .spec-detail .description { background-color: #ca3a11; } 56 | .jasmine_html-reporter .failures .spec-detail .description a { color: white; } 57 | .jasmine_html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; } 58 | .jasmine_html-reporter .result-message span.result { display: block; } 59 | .jasmine_html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; } 60 | -------------------------------------------------------------------------------- /js/p5.dom.js: -------------------------------------------------------------------------------- 1 | /*! p5.dom.js v0.1.0 August 6, 2014 */ 2 | /** 3 | *

The web is much more than just canvas and p5.dom makes it easy to interact 4 | * with other HTML5 objects, including text, hyperlink, image, input, video, 5 | * audio, and webcam.

6 | *

There are a set of creation methods, and some other stuff... @TODO.

7 | * 8 | *

Methods and properties shown in black are part of the p5.js core, items in 9 | * blue are part of the p5.dom library. See the 10 | * using a library 11 | * section for information on how to include this library. p5.dom comes with 12 | * p5 complete or you can download the single file 13 | * 14 | * here.

15 | * 16 | * 17 | * @module p5.dom 18 | * @submodule p5.dom 19 | * @for p5.dom 20 | * @main 21 | */ 22 | 23 | var p5DOM = (function(){ 24 | 25 | // ============================================================================= 26 | // p5 additions 27 | // ============================================================================= 28 | 29 | /** 30 | * Searches the page for an element with given ID and returns it as 31 | * a p5.Element. The DOM node itself can be accessed with .elt. 32 | * Returns null if none found. 33 | * 34 | * @method getElement 35 | * @param {String} id id of element to search for 36 | * @return {Object/p5.Element|Null} p5.Element containing node found 37 | */ 38 | p5.prototype.getElement = function (e) { 39 | var res = document.getElementById(e); 40 | if (res) { 41 | return new p5.Element(res); 42 | } else { 43 | return null; 44 | } 45 | }; 46 | 47 | /** 48 | * Searches the page for elements with given class and returns an 49 | * array of p5.Elements. The DOM nodes themselves can be accessed 50 | * with .elt. Returns an empty array if none found. 51 | * 52 | * @method getElements 53 | * @param {String} class class name of elements to search for 54 | * @return {Array} array of p5.Element wrapped nodes found 55 | */ 56 | p5.prototype.getElements = function (e) { 57 | var arr = []; 58 | var res = document.getElementsByClassName(e); 59 | if (res) { 60 | for (var j = 0; j < res.length; j++) { 61 | var obj = new p5.Element(res[j]); 62 | arr.push(obj); 63 | } 64 | } 65 | return arr; 66 | }; 67 | 68 | /** 69 | * Removes all elements created by p5, except any canvas / graphics 70 | * elements created by createCanvas or createGraphics. 71 | * Event handlers are removed, and element is removed from the DOM. 72 | * 73 | * @method removeElements 74 | */ 75 | p5.prototype.removeElements = function (e) { 76 | for (var i=0; i