├── .gitattributes ├── .gitignore ├── Life.js ├── LifeUI.js ├── README ├── Worker.js ├── bootstrap ├── css │ ├── bootstrap-responsive.css │ ├── bootstrap.css │ └── docs.css ├── ico │ ├── apple-touch-icon-114-precomposed.png │ ├── apple-touch-icon-144-precomposed.png │ ├── apple-touch-icon-57-precomposed.png │ ├── apple-touch-icon-72-precomposed.png │ └── favicon.ico ├── img │ ├── bird.png │ ├── bootstrap-mdo-sfmoma-01.jpg │ ├── bootstrap-mdo-sfmoma-02.jpg │ ├── bootstrap-mdo-sfmoma-03.jpg │ ├── browsers.png │ ├── example-sites │ │ ├── fleetio.png │ │ ├── jshint.png │ │ ├── kippt.png │ │ └── soundready.png │ ├── examples │ │ ├── bootstrap-example-fluid.jpg │ │ ├── bootstrap-example-hero.jpg │ │ └── bootstrap-example-starter.jpg │ ├── github-16px.png │ ├── glyphicons-halflings-white.png │ ├── glyphicons-halflings.png │ ├── glyphicons │ │ ├── glyphicons_009_magic.png │ │ ├── glyphicons_042_group.png │ │ ├── glyphicons_079_podium.png │ │ ├── glyphicons_082_roundabout.png │ │ ├── glyphicons_155_show_thumbnails.png │ │ ├── glyphicons_163_iphone.png │ │ ├── glyphicons_214_resize_small.png │ │ └── glyphicons_266_book_open.png │ ├── grid-18px-masked.png │ ├── icon-css3.png │ ├── icon-github.png │ ├── icon-html5.png │ ├── icon-twitter.png │ ├── less-logo-large.png │ ├── less-small.png │ └── responsive-illustrations.png └── js │ ├── README.md │ ├── application.js │ ├── bootstrap-alert.js │ ├── bootstrap-button.js │ ├── bootstrap-carousel.js │ ├── bootstrap-collapse.js │ ├── bootstrap-dropdown.js │ ├── bootstrap-modal.js │ ├── bootstrap-popover.js │ ├── bootstrap-scrollspy.js │ ├── bootstrap-tab.js │ ├── bootstrap-tooltip.js │ ├── bootstrap-transition.js │ ├── bootstrap-typeahead.js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── google-code-prettify │ ├── prettify.css │ └── prettify.js │ └── jquery.js ├── index.html └── jit.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.doc diff=astextplain 2 | *.DOC diff=astextplain 3 | *.docx diff=astextplain 4 | *.DOCX diff=astextplain 5 | *.dot diff=astextplain 6 | *.DOT diff=astextplain 7 | *.pdf diff=astextplain 8 | *.PDF diff=astextplain 9 | *.rtf diff=astextplain 10 | *.RTF diff=astextplain 11 | 12 | *.jpg binary 13 | *.png binary 14 | *.gif binary 15 | 16 | *.cs text=auto diff=csharp 17 | *.vb text=auto 18 | *.c text=auto 19 | *.cpp text=auto 20 | *.cxx text=auto 21 | *.h text=auto 22 | *.hxx text=auto 23 | *.py text=auto 24 | *.rb text=auto 25 | *.java text=auto 26 | *.html text=auto 27 | *.htm text=auto 28 | *.css text=auto 29 | *.scss text=auto 30 | *.sass text=auto 31 | *.less text=auto 32 | *.js text=auto 33 | *.lisp text=auto 34 | *.clj text=auto 35 | *.sql text=auto 36 | *.php text=auto 37 | *.lua text=auto 38 | *.m text=auto 39 | *.asm text=auto 40 | *.erl text=auto 41 | *.fs text=auto 42 | *.fsx text=auto 43 | *.hs text=auto 44 | 45 | *.csproj text=auto merge=union 46 | *.vbproj text=auto merge=union 47 | *.fsproj text=auto merge=union 48 | *.dbproj text=auto merge=union 49 | *.sln text=auto eol=crlf merge=union 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bak/** 2 | .idea/** 3 | css/** 4 | sylvester.js 5 | *.iml 6 | client 7 | node 8 | node_modules 9 | 10 | ############ 11 | ## Windows 12 | ############ 13 | 14 | # Windows image file caches 15 | Thumbs.db 16 | 17 | # Folder config file 18 | Desktop.ini 19 | -------------------------------------------------------------------------------- /Life.js: -------------------------------------------------------------------------------- 1 | var Life = Life || {}; 2 | 3 | Life.Simulation = function(parameters){ 4 | 5 | //Default parameters 6 | var _params = { 7 | tickDuration:20, 8 | 9 | //World 10 | width: window.innerWidth, 11 | height: window.innerHeight, 12 | cellSize:64, 13 | 14 | //Vegetation distribution 15 | maxFood:0.5, 16 | foodAddFrequency:30, 17 | 18 | minAgents:25, 19 | maxAgents:50, 20 | 21 | 22 | agent:{ 23 | radius:10, 24 | speed:0.3, 25 | sprintMultiplier:2, 26 | 27 | //Vision 28 | numberEyes:4, 29 | viewDistance:150, 30 | 31 | //Weapon 32 | spikeStrength:1, 33 | spikeSpeed: 0.005, 34 | 35 | //Eating + sharing food 36 | foodIntake:0.002, 37 | foodWasted:0.001, 38 | foodTraded:0.001, 39 | foodTradeDistance:50, 40 | 41 | //Reproduction 42 | babies:2, 43 | reproductionRate:{ 44 | carnivore:7, 45 | herbivore:7 46 | }, 47 | mutationRate:[ 48 | 0.002, 49 | 0.05 50 | ], 51 | 52 | //Pain 53 | temperatureDiscomfortDamage:0, 54 | 55 | //Death 56 | bodyDecayRadius:64, 57 | bodyFertilityBonus:5 58 | }, 59 | 60 | brain:{ 61 | inputSize:25, 62 | outputSize:9, 63 | connections:4, 64 | size:200 65 | } 66 | }; 67 | 68 | //Recursively copies any options supplied as parameters onto a default parameters object 69 | function copyOptions(from, to){ 70 | for(var i in from){ 71 | if(typeof from[i] == "object"){ 72 | copyOptions(from[i], to[i]); 73 | }else if(typeof from[i] != "undefined"){ 74 | console.log(to); 75 | to[i] = from[i]; 76 | } 77 | } 78 | } 79 | 80 | copyOptions(parameters, _params); 81 | 82 | //Ensure that the width and height are a multiple of the cell size 83 | _params.width = Math.floor(_params.width / _params.cellSize) * _params.cellSize; 84 | _params.height = Math.floor(_params.height / _params.cellSize) * _params.cellSize; 85 | 86 | var _this = this, 87 | _world = null, 88 | _selectedAgent = null, 89 | _callback = function(x){}, 90 | _renderer = null, 91 | _worker = null, 92 | _socket = null; 93 | 94 | this.parameters = _params; 95 | 96 | 97 | 98 | this.sendCommand = function(command, options){ 99 | if(_socket !== null){ 100 | _socket.emit(command, options); 101 | }else{ 102 | _worker.postMessage({action:command, parameters:options}); 103 | } 104 | }; 105 | 106 | 107 | /** 108 | * Allows a callback to be attached to handle advanced rendering of data, e.g. for graphing 109 | * @param callback Function to call when new simulation data is available 110 | */ 111 | this.onUpdate = function (callback) { 112 | _callback = callback; 113 | }; 114 | 115 | /** 116 | * Attaches a renderer to the simulation 117 | */ 118 | this.setRenderer = function(renderer){ 119 | _renderer = renderer; 120 | this.renderer = _renderer; 121 | }; 122 | 123 | /** 124 | * 125 | */ 126 | this.init = function(options){ 127 | //Whether to run the simulation locally, or as a node.js process 128 | if(options && options.type == "node"){ 129 | var server = options.server || "http://localhost"; 130 | 131 | _socket = io.connect(server); 132 | _socket.on('update', function (data) { 133 | _world = data.world; 134 | _selectedAgent = data.agent; 135 | _callback(data); 136 | _renderer.update(_world, _selectedAgent); 137 | }); 138 | _socket.on('save', function (data) { 139 | _this.saved = data.world; 140 | }); 141 | 142 | _socket.on('connected', function (data) { 143 | _params = data.world.parameters; 144 | _world = data.world; 145 | _selectedAgent = data.agent; 146 | _renderer.init(_params); 147 | }); 148 | 149 | }else{ 150 | //Running the simulation locally, in JS. Use a Web Worker 151 | _worker = new Worker('Worker.js'); 152 | _worker.onmessage = function (event) { 153 | data = JSON.parse(event.data); 154 | if(data.action == "update"){ 155 | _world = data.world; 156 | _selectedAgent = data.agent; 157 | _callback(data); 158 | _renderer.update(_world, _selectedAgent); 159 | }else if(data.action == "save"){ 160 | _this.saved = data.world; 161 | } 162 | }; 163 | 164 | _renderer.init(_params); 165 | } 166 | if(options && options.slave){ 167 | _this.sendCommand("listen"); 168 | }else{ 169 | _this.sendCommand("init", _this.parameters); 170 | } 171 | 172 | } 173 | 174 | }; 175 | 176 | 177 | /** 178 | * Renders data from a simulation to a canvas element 179 | * @param parameters A list of parameters, see a list of defaults here. 180 | * @constructor 181 | */ 182 | Life.Renderer = function (simulation) { 183 | 184 | var _this = this, 185 | _canvas = document.createElement('canvas'), 186 | _context = _canvas.getContext('2d'), 187 | _world = null, 188 | _selectedAgent = null, 189 | _simulation = simulation; 190 | 191 | _simulation.setRenderer(_this); 192 | 193 | 194 | this.canvas = _canvas; 195 | this.parameters = simulation.parameters; 196 | this.shouldRender = { 197 | viewCones: false, 198 | eyes:true, 199 | indicators:true, 200 | stats:false, 201 | health:true, 202 | food: true 203 | } 204 | 205 | /** 206 | * Animates the simulation, using requestAnimationFrame to allow browser to control framerate 207 | */ 208 | this.animate = function () { 209 | requestAnimationFrame(_this.animate); 210 | _this.render(); 211 | }; 212 | 213 | /** 214 | * Renders the current world 215 | */ 216 | this.render = function () { 217 | if (_world) { 218 | _context.clearRect(0, 0, _this.parameters.width, _this.parameters.height); 219 | 220 | //Draw food levels in cells 221 | if(_this.shouldRender.food){ 222 | for (var x = 0; x < Math.floor(_this.parameters.width / _this.parameters.cellSize); x++) { 223 | for (var y = 0; y < Math.floor(_this.parameters.height / _this.parameters.cellSize); y++) { 224 | var f = 0.5 * _world.food[x][y] / _this.parameters.maxFood; 225 | _this.drawFood(x, y, f); 226 | } 227 | } 228 | } 229 | 230 | //Render each agent 231 | for (var id in _world.agents) { 232 | _this.renderAgent(_world.agents[id]); 233 | } 234 | } 235 | }; 236 | 237 | /** 238 | * Renders an agent 239 | * @param agent Agent to render 240 | */ 241 | this.renderAgent = function (agent) { 242 | //Indicator 243 | if(_this.shouldRender.indicators){ 244 | _context.beginPath(); 245 | _context.fillStyle = Life.Utils.rgbaToCss(agent.indicator.red, agent.indicator.green, agent.indicator.blue, 0.5); 246 | _context.arc(agent.pos.x, agent.pos.y, _this.parameters.agent.radius + Math.floor(agent.indicator.size), 0, 2 * Math.PI, false); 247 | _context.fill(); 248 | } 249 | 250 | 251 | //Selected 252 | if (agent.selectFlag) { 253 | _context.beginPath(); 254 | _context.fillStyle = Life.Utils.rgbaToCss(255, 0, 255, 0.3); 255 | _context.arc(agent.pos.x, agent.pos.y, _this.parameters.agent.radius + 20, 0, 2 * Math.PI, false); 256 | _context.fill(); 257 | } 258 | 259 | //Eyes 260 | _context.strokeStyle = "rgba(60,60,60,1)"; 261 | for (var i in agent.eyes) { 262 | var eye = agent.eyes[i]; 263 | var angle = agent.angle + eye.direction; 264 | 265 | if(_this.shouldRender.eyes){ 266 | _context.beginPath(); 267 | _context.moveTo(agent.pos.x, agent.pos.y); 268 | _context.lineTo(agent.pos.x + (_this.parameters.agent.radius * 2) * Math.cos(angle), agent.pos.y + (_this.parameters.agent.radius * 2) * Math.sin(angle)); 269 | _context.strokeStyle = "rgba(0,0,0,0.3)" 270 | _context.stroke(); 271 | } 272 | 273 | if(_this.shouldRender.viewCones){ 274 | _context.beginPath(); 275 | _context.moveTo(agent.pos.x, agent.pos.y); 276 | _context.arc(agent.pos.x, agent.pos.y,_this.parameters.agent.viewDistance * eye.proximity + _this.parameters.agent.radius, angle - (eye.fov / 2), angle + ( eye.fov / 2), false); 277 | _context.fillStyle = Life.Utils.rgbaToCss(eye.red, eye.green, eye.blue, 0.5); 278 | _context.closePath(); 279 | _context.fill(); 280 | } 281 | } 282 | 283 | //Body 284 | _context.beginPath(); 285 | _context.fillStyle = Life.Utils.rgbaToCss(agent.red, agent.green, agent.blue, 1); 286 | _context.arc(agent.pos.x, agent.pos.y, _this.parameters.agent.radius, 0, 2 * Math.PI, false); 287 | _context.fill(); 288 | 289 | //Sprinting 290 | if (agent.sprinting) { 291 | _context.strokeStyle = "rgba(0,200,0,1)"; 292 | } else { 293 | _context.strokeStyle = "rgba(0,0,0,0)"; 294 | } 295 | _context.stroke(); 296 | 297 | 298 | //Spike 299 | _context.strokeStyle = "rgba(125,0,0,1)"; 300 | _context.beginPath(); 301 | _context.moveTo(agent.pos.x, agent.pos.y); 302 | _context.lineTo(agent.pos.x + (_this.parameters.agent.radius * 3 * agent.spikeLength) * Math.cos(agent.angle), agent.pos.y + (_this.parameters.agent.radius * 3 * agent.spikeLength) * Math.sin(agent.angle)); 303 | _context.stroke(); 304 | 305 | 306 | //Stats offsets 307 | var xo = 18; 308 | var yo = -15; 309 | 310 | //Health 311 | if(_this.shouldRender.health){ 312 | _context.fillStyle = "black"; 313 | _context.fillRect(agent.pos.x + xo, agent.pos.y + yo, 5, 40); 314 | _context.fillStyle = "rgba(0,200,0,1)"; 315 | _context.fillRect(agent.pos.x + xo, agent.pos.y + yo + 20 * (2 - agent.health), 5, 40 - (20 * (2 - agent.health))); 316 | } 317 | 318 | if(_this.shouldRender.stats){ 319 | //Hybrid 320 | if (agent.hybrid) { 321 | _context.fillStyle = Life.Utils.rgbaToCss(0, 0.8, 0, 1); 322 | _context.fillRect(agent.pos.x + xo + 6, agent.pos.y + yo, 5, 10); 323 | } 324 | 325 | //Herbivore-ness 326 | _context.fillStyle = Life.Utils.rgbaToCss(1 - agent.herbivore, agent.herbivore, 0, 1); 327 | _context.fillRect(agent.pos.x + xo + 6, agent.pos.y + yo + 12, 5, 10); 328 | 329 | //Sound 330 | _context.fillStyle = Life.Utils.rgbaToCss(agent.soundMultiplier, agent.soundMultiplier, agent.soundMultiplier, 1); 331 | _context.fillRect(agent.pos.x + xo + 6, agent.pos.y + yo + 24, 5, 10); 332 | 333 | 334 | //Text 335 | _context.fillStyle = "black"; 336 | _context.fillText(agent.generationCount, agent.pos.x - _this.parameters.agent.radius, agent.pos.y + _this.parameters.agent.radius * 2); 337 | _context.fillText(agent.age, agent.pos.x - _this.parameters.agent.radius, agent.pos.y + _this.parameters.agent.radius * 2 + 10); 338 | _context.fillText(agent.health.toFixed(2), agent.pos.x - _this.parameters.agent.radius, agent.pos.y + _this.parameters.agent.radius * 2 + 20); 339 | _context.fillText(agent.repCounter.toFixed(2), agent.pos.x - _this.parameters.agent.radius, agent.pos.y + _this.parameters.agent.radius * 2 + 30); 340 | } 341 | }; 342 | 343 | /** 344 | * Renders a cell of food 345 | * @param x X coordinate of cell 346 | * @param y Y coordinate of cell 347 | * @param quantity Quantity of food in cell 348 | */ 349 | this.drawFood = function (x, y, quantity) { 350 | _context.fillStyle = Life.Utils.rgbaToCss(0.8, 1, 0.8, quantity); 351 | _context.fillRect(x * _this.parameters.cellSize, y * _this.parameters.cellSize, _this.parameters.cellSize, _this.parameters.cellSize); 352 | }; 353 | 354 | 355 | 356 | /** 357 | * Initialises a simulation and begins rendering 358 | */ 359 | this.init = function () { 360 | _canvas.width = _simulation.parameters.width; 361 | _canvas.height = _simulation.parameters.height; 362 | 363 | //Pass click events to simulation to select agent 364 | _canvas.addEventListener("mousedown", function (event) { 365 | _simulation.sendCommand("select", {x:event.clientX, y:event.clientY}); 366 | }, false); 367 | 368 | //requestAnimationFrame shim, lets unsupported browsers render, with poorer performance 369 | var lastTime = 0; 370 | var vendors = [ 'ms', 'moz', 'webkit', 'o' ]; 371 | for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { 372 | window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ]; 373 | window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ]; 374 | } 375 | if (!window.requestAnimationFrame) { 376 | window.requestAnimationFrame = function (callback, element) { 377 | var currTime = Date.now(), timeToCall = Math.max(0, 16 - ( currTime - lastTime )); 378 | var id = window.setTimeout(function () { 379 | callback(currTime + timeToCall); 380 | }, timeToCall); 381 | lastTime = currTime + timeToCall; 382 | return id; 383 | }; 384 | } 385 | if (!window.cancelAnimationFrame) { 386 | window.cancelAnimationFrame = function (id) { 387 | clearTimeout(id); 388 | }; 389 | } 390 | 391 | //Begin animation 392 | this.animate(); 393 | }; 394 | 395 | this.update = function(world, selectedAgent){ 396 | _world = world; 397 | _selectedAgent = selectedAgent; 398 | } 399 | 400 | 401 | this.setParameters = function(parameters){ 402 | _simulation.sendCommand("setParameters", {parameters:parameters}); 403 | }; 404 | 405 | this.save = function(){ 406 | _simulation.sendCommand("save", {}); 407 | }; 408 | 409 | this.load = function(){ 410 | _simulation.sendCommand("load", {world:_this.saved}); 411 | }; 412 | 413 | 414 | 415 | 416 | 417 | }; 418 | 419 | Life.Utils = {}; 420 | /** 421 | * Produces an RGBA CSS string from four values between 0 and 1. 422 | * @param r Red component 423 | * @param g Green component 424 | * @param b Blue component 425 | * @param a Alpha component 426 | * @return {String} RGBA colour as a CSS string 427 | */ 428 | Life.Utils.rgbaToCss = function (r, g, b, a) { 429 | return "rgba(" + Math.floor(r * 255) + "," + Math.floor(g * 255) + "," + Math.floor(b * 255) + ", " + a + ")"; 430 | } -------------------------------------------------------------------------------- /LifeUI.js: -------------------------------------------------------------------------------- 1 | var Life = Life || {}; 2 | 3 | Life.UI = function(simulation, parameters){ 4 | 5 | var _this = this, 6 | _updateBrainGraph = false, 7 | _enableLogging = false; 8 | _lastSelectedAgent = null, 9 | _lastSelectedNode = null, 10 | _brainGraph = null; 11 | 12 | this.data = null; 13 | this.params = null; 14 | 15 | $('#tabs a').click(function (e) { 16 | e.preventDefault(); 17 | $(this).tab('show'); 18 | }) 19 | 20 | 21 | $( "#updateBrainGraph" ).button(); 22 | $( "#updateBrainGraph" ).click(function(){ 23 | _updateBrainGraph = !_updateBrainGraph; 24 | }); 25 | 26 | 27 | 28 | $( "#pause" ).click(function(){ 29 | simulation.sendCommand("pause"); 30 | }); 31 | 32 | $( "#clone" ).click(function(){ 33 | simulation.sendCommand("clone"); 34 | }); 35 | 36 | $( "#kill" ).click(function(){ 37 | simulation.sendCommand("kill"); 38 | }); 39 | 40 | $( "#showControls" ).click(function(){ 41 | $("#controls").toggle(); 42 | }); 43 | 44 | $( "#enableLogging" ).click(function(){ 45 | _enableLogging = !_enableLogging; 46 | }); 47 | 48 | 49 | 50 | $( "#render_viewCones" ).click(function(){ 51 | simulation.renderer.shouldRender.viewCones = !simulation.renderer.shouldRender.viewCones; 52 | }); 53 | 54 | $( "#render_health" ).click(function(){ 55 | simulation.renderer.shouldRender.health = !simulation.renderer.shouldRender.health; 56 | }); 57 | 58 | $( "#render_stats" ).click(function(){ 59 | simulation.renderer.shouldRender.stats = !simulation.renderer.shouldRender.stats; 60 | }); 61 | 62 | $( "#render_indicators" ).click(function(){ 63 | simulation.renderer.shouldRender.indicators = !simulation.renderer.shouldRender.indicators; 64 | }); 65 | 66 | $( "#render_eyes" ).click(function(){ 67 | simulation.renderer.shouldRender.eyes = !simulation.renderer.shouldRender.eyes; 68 | }); 69 | 70 | $( "#render_grass" ).click(function(){ 71 | simulation.renderer.shouldRender.food = !simulation.renderer.shouldRender.food; 72 | }); 73 | 74 | 75 | 76 | 77 | 78 | $( "#saveParameters" ).click(function(){ 79 | simulation.setParameters(_this.params); 80 | }); 81 | 82 | function initBrainGraph(){ 83 | _brainGraph = new $jit.Hypertree({ 84 | injectInto:'brain', 85 | Node:{ 86 | overridable:true, 87 | 'transform':false 88 | }, 89 | 90 | Edge:{ 91 | overridable:true 92 | }, 93 | Navigation: { 94 | enable: true, 95 | panning: 'avoid nodes', 96 | zooming: 20 97 | }, 98 | Events: { 99 | enable: true, 100 | onClick: function(node, eventInfo, e) { 101 | _lastSelectedNode = node; 102 | ht.onClick(node.id); 103 | }, 104 | onMouseEnter: function(node, eventInfo, e) { 105 | ht.canvas.getElement().style.cursor = 'pointer'; 106 | }, 107 | onMouseLeave: function(node, eventInfo, e) { 108 | ht.canvas.getElement().style.cursor = ''; 109 | } 110 | } 111 | 112 | }); 113 | } 114 | 115 | 116 | 117 | 118 | 119 | Highcharts.setOptions({ 120 | global : { 121 | useUTC : true 122 | } 123 | }); 124 | 125 | // Create the chart 126 | var fitnessChart = new Highcharts.StockChart({ 127 | chart : { 128 | renderTo : 'fitness' 129 | }, 130 | 131 | rangeSelector: { 132 | buttons: [{ 133 | count: 1, 134 | type: 'minute', 135 | text: '1M' 136 | }, { 137 | count: 5, 138 | type: 'minute', 139 | text: '5M' 140 | }, { 141 | type: 'all', 142 | text: 'All' 143 | }], 144 | inputEnabled: false, 145 | selected: 0 146 | }, 147 | 148 | title : { 149 | text : 'Fitness' 150 | }, 151 | 152 | exporting: { 153 | enabled: false 154 | }, 155 | 156 | series : [{ 157 | name : 'Best', 158 | data : [[(new Date()).getTime(), 0]] 159 | },{ 160 | name : 'Average', 161 | data : [[(new Date()).getTime(), 0]] 162 | }] 163 | }); 164 | 165 | 166 | this.setData = function(data){ 167 | _this.data = data; 168 | } 169 | 170 | simulation.onUpdate(_this.setData); 171 | 172 | this.updateGraphs = function(){ 173 | if(_enableLogging){ 174 | 175 | 176 | if(_this.data && _this.data.agent && _updateBrainGraph){ 177 | var neurons = _this.data.agent.brain.boxes; 178 | var graph = []; 179 | for(var id in neurons){ 180 | var neuron = neurons[id]; 181 | var type = "triangle"; 182 | var color = Life.Utils.rgbaToCss(0.3, neuron.output * 0.7 + 0.3, neuron.output * 0.7 + 0.3, 1); 183 | if(id < simulation.parameters.brain.inputSize){ 184 | type = "circle"; 185 | color = Life.Utils.rgbaToCss(0.3, neuron.output * 0.7 + 0.3, 0.3, 1); 186 | }else if(id > neurons.length - simulation.parameters.brain.outputSize){ 187 | type = "square"; 188 | color = Life.Utils.rgbaToCss(neuron.output * 0.7 + 0.3, 0.3, 0.3, 1); 189 | } 190 | var val = (neuron.out < 1) ? neuron.out : 1; 191 | 192 | var node = {"id":id, "name":id, data: {"$type":type, "$dim":"4", "$color":color}, "adjacencies":[] }; 193 | for(var syn in neurons[id].id){ 194 | var synapse = neurons[id].id[syn]; 195 | var width = neurons[id].weight[syn] + 3; 196 | var color = (neurons[id].type[syn] > 0.5) ? Life.Utils.rgbaToCss(0,0.5,1,0.7) : Life.Utils.rgbaToCss(1,1,1,0.2); 197 | node.adjacencies.push({"nodeTo":synapse, "data":{"$color":color, "$lineWidth":width/2}}); 198 | } 199 | graph.push(node); 200 | } 201 | 202 | if(_brainGraph === null){ 203 | initBrainGraph(); 204 | } 205 | 206 | if(_lastSelectedNode){ 207 | _brainGraph.loadJSON(graph, _lastSelectedNode.id); 208 | }else{ 209 | _brainGraph.loadJSON(graph); 210 | } 211 | _brainGraph.refresh(); 212 | } 213 | 214 | 215 | if(_this.data && _this.data.agent){ 216 | var agent = _this.data.agent; 217 | $("#agentId").html(agent.id); 218 | $("#x").html(agent.pos.x); 219 | $("#y").html(agent.pos.y); 220 | $("#angle").html(agent.angle); 221 | $("#health").html(agent.health); 222 | $("#age").html(agent.age); 223 | $("#herbivore").html(agent.herbivore); 224 | _this.plotAgentEyes(); 225 | } 226 | 227 | if(_this.data.world){ 228 | $("#tick").val(_this.data.world.tick); 229 | 230 | if(_this.params == null){ 231 | _this.params = _this.data.world.parameters; 232 | //_this.loadInitialValues(); 233 | } 234 | 235 | } 236 | 237 | var maxFitness = 0; 238 | var totalFitness = 0; 239 | for(var a in _this.data.world.agents){ 240 | var agent = _this.data.world.agents[a]; 241 | if(agent.age > maxFitness) maxFitness = agent.age; 242 | totalFitness += agent.age; 243 | } 244 | totalFitness = totalFitness / _this.data.world.agents.length; 245 | 246 | fitnessChart.series[0].addPoint([(new Date()).getTime(), maxFitness], true); 247 | fitnessChart.series[1].addPoint([(new Date()).getTime(), totalFitness], true); 248 | 249 | } 250 | }; 251 | 252 | this.plotAgentEyes = function(){ 253 | var ctx = $("#eyes")[0].getContext("2d"); 254 | ctx.clearRect(0,0,500,500); 255 | for(var index in _this.data.agent.eyes){ 256 | var eye = _this.data.agent.eyes[index]; 257 | ctx.beginPath(); 258 | ctx.moveTo(250, 250); 259 | ctx.arc(250,250,_this.data.world.parameters.agent.viewDistance, eye.direction - (eye.fov / 2) - (Math.PI / 2), eye.direction + ( eye.fov / 2) - (Math.PI / 2), false); 260 | ctx.strokeStyle = "rgba(0,0,0,0.7)"; 261 | ctx.closePath(); 262 | ctx.stroke(); 263 | 264 | ctx.beginPath(); 265 | ctx.moveTo(250, 250); 266 | ctx.lineTo(250 + (_this.data.world.parameters.agent.viewDistance + 10) * Math.cos(eye.direction - (Math.PI / 2)), 250 + (_this.data.world.parameters.agent.viewDistance + 10) * Math.sin(eye.direction - (Math.PI / 2))); 267 | ctx.stroke(); 268 | 269 | ctx.beginPath(); 270 | ctx.moveTo(250, 250); 271 | ctx.arc(250,250,_this.data.world.parameters.agent.viewDistance, eye.direction - (eye.fov / 2)- (Math.PI / 2), eye.direction + ( eye.fov / 2)- (Math.PI / 2), false); 272 | ctx.fillStyle = Life.Utils.rgbaToCss(eye.red, eye.green, eye.blue, eye.proximity * eye.proximity); 273 | ctx.closePath(); 274 | ctx.fill(); 275 | } 276 | } 277 | 278 | 279 | window.setInterval(_this.updateGraphs, 1000); 280 | 281 | 282 | } 283 | 284 | Life.Utils = {}; 285 | /** 286 | * Produces an RGBA CSS string from four values between 0 and 1. 287 | * @param r Red component 288 | * @param g Green component 289 | * @param b Blue component 290 | * @param a Alpha component 291 | * @return {String} RGBA colour as a CSS string 292 | */ 293 | Life.Utils.rgbaToCss = function (r, g, b, a) { 294 | return "rgba(" + Math.floor(r * 255) + "," + Math.floor(g * 255) + "," + Math.floor(b * 255) + ", " + a + ")"; 295 | } -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Javascript port of Scriptbots (https://sites.google.com/site/scriptbotsevo/) 2 | 3 | To use: 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 19 | 20 | For a list of default parameters see: https://github.com/JimAllanson/lifejs/wiki/Default-Parameters 21 | For a demonstration, see: http://jimallanson.github.com/lifejs/ 22 | For more information on the simulation, see: https://sites.google.com/site/scriptbotsevo/ -------------------------------------------------------------------------------- /bootstrap/css/bootstrap-responsive.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.0.4 3 | * 4 | * Copyright 2012 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world @twitter by @mdo and @fat. 9 | */ 10 | 11 | .clearfix { 12 | *zoom: 1; 13 | } 14 | 15 | .clearfix:before, 16 | .clearfix:after { 17 | display: table; 18 | content: ""; 19 | } 20 | 21 | .clearfix:after { 22 | clear: both; 23 | } 24 | 25 | .hide-text { 26 | font: 0/0 a; 27 | color: transparent; 28 | text-shadow: none; 29 | background-color: transparent; 30 | border: 0; 31 | } 32 | 33 | .input-block-level { 34 | display: block; 35 | width: 100%; 36 | min-height: 28px; 37 | -webkit-box-sizing: border-box; 38 | -moz-box-sizing: border-box; 39 | -ms-box-sizing: border-box; 40 | box-sizing: border-box; 41 | } 42 | 43 | .hidden { 44 | display: none; 45 | visibility: hidden; 46 | } 47 | 48 | .visible-phone { 49 | display: none !important; 50 | } 51 | 52 | .visible-tablet { 53 | display: none !important; 54 | } 55 | 56 | .hidden-desktop { 57 | display: none !important; 58 | } 59 | 60 | @media (max-width: 767px) { 61 | .visible-phone { 62 | display: inherit !important; 63 | } 64 | .hidden-phone { 65 | display: none !important; 66 | } 67 | .hidden-desktop { 68 | display: inherit !important; 69 | } 70 | .visible-desktop { 71 | display: none !important; 72 | } 73 | } 74 | 75 | @media (min-width: 768px) and (max-width: 979px) { 76 | .visible-tablet { 77 | display: inherit !important; 78 | } 79 | .hidden-tablet { 80 | display: none !important; 81 | } 82 | .hidden-desktop { 83 | display: inherit !important; 84 | } 85 | .visible-desktop { 86 | display: none !important ; 87 | } 88 | } 89 | 90 | @media (max-width: 480px) { 91 | .nav-collapse { 92 | -webkit-transform: translate3d(0, 0, 0); 93 | } 94 | .page-header h1 small { 95 | display: block; 96 | line-height: 18px; 97 | } 98 | input[type="checkbox"], 99 | input[type="radio"] { 100 | border: 1px solid #ccc; 101 | } 102 | .form-horizontal .control-group > label { 103 | float: none; 104 | width: auto; 105 | padding-top: 0; 106 | text-align: left; 107 | } 108 | .form-horizontal .controls { 109 | margin-left: 0; 110 | } 111 | .form-horizontal .control-list { 112 | padding-top: 0; 113 | } 114 | .form-horizontal .form-actions { 115 | padding-right: 10px; 116 | padding-left: 10px; 117 | } 118 | .modal { 119 | position: absolute; 120 | top: 10px; 121 | right: 10px; 122 | left: 10px; 123 | width: auto; 124 | margin: 0; 125 | } 126 | .modal.fade.in { 127 | top: auto; 128 | } 129 | .modal-header .close { 130 | padding: 10px; 131 | margin: -10px; 132 | } 133 | .carousel-caption { 134 | position: static; 135 | } 136 | } 137 | 138 | @media (max-width: 767px) { 139 | body { 140 | padding-right: 20px; 141 | padding-left: 20px; 142 | } 143 | .navbar-fixed-top, 144 | .navbar-fixed-bottom { 145 | margin-right: -20px; 146 | margin-left: -20px; 147 | } 148 | .container-fluid { 149 | padding: 0; 150 | } 151 | .dl-horizontal dt { 152 | float: none; 153 | width: auto; 154 | clear: none; 155 | text-align: left; 156 | } 157 | .dl-horizontal dd { 158 | margin-left: 0; 159 | } 160 | .container { 161 | width: auto; 162 | } 163 | .row-fluid { 164 | width: 100%; 165 | } 166 | .row, 167 | .thumbnails { 168 | margin-left: 0; 169 | } 170 | [class*="span"], 171 | .row-fluid [class*="span"] { 172 | display: block; 173 | float: none; 174 | width: auto; 175 | margin-left: 0; 176 | } 177 | .input-large, 178 | .input-xlarge, 179 | .input-xxlarge, 180 | input[class*="span"], 181 | select[class*="span"], 182 | textarea[class*="span"], 183 | .uneditable-input { 184 | display: block; 185 | width: 100%; 186 | min-height: 28px; 187 | -webkit-box-sizing: border-box; 188 | -moz-box-sizing: border-box; 189 | -ms-box-sizing: border-box; 190 | box-sizing: border-box; 191 | } 192 | .input-prepend input, 193 | .input-append input, 194 | .input-prepend input[class*="span"], 195 | .input-append input[class*="span"] { 196 | display: inline-block; 197 | width: auto; 198 | } 199 | } 200 | 201 | @media (min-width: 768px) and (max-width: 979px) { 202 | .row { 203 | margin-left: -20px; 204 | *zoom: 1; 205 | } 206 | .row:before, 207 | .row:after { 208 | display: table; 209 | content: ""; 210 | } 211 | .row:after { 212 | clear: both; 213 | } 214 | [class*="span"] { 215 | float: left; 216 | margin-left: 20px; 217 | } 218 | .container, 219 | .navbar-fixed-top .container, 220 | .navbar-fixed-bottom .container { 221 | width: 724px; 222 | } 223 | .span12 { 224 | width: 724px; 225 | } 226 | .span11 { 227 | width: 662px; 228 | } 229 | .span10 { 230 | width: 600px; 231 | } 232 | .span9 { 233 | width: 538px; 234 | } 235 | .span8 { 236 | width: 476px; 237 | } 238 | .span7 { 239 | width: 414px; 240 | } 241 | .span6 { 242 | width: 352px; 243 | } 244 | .span5 { 245 | width: 290px; 246 | } 247 | .span4 { 248 | width: 228px; 249 | } 250 | .span3 { 251 | width: 166px; 252 | } 253 | .span2 { 254 | width: 104px; 255 | } 256 | .span1 { 257 | width: 42px; 258 | } 259 | .offset12 { 260 | margin-left: 764px; 261 | } 262 | .offset11 { 263 | margin-left: 702px; 264 | } 265 | .offset10 { 266 | margin-left: 640px; 267 | } 268 | .offset9 { 269 | margin-left: 578px; 270 | } 271 | .offset8 { 272 | margin-left: 516px; 273 | } 274 | .offset7 { 275 | margin-left: 454px; 276 | } 277 | .offset6 { 278 | margin-left: 392px; 279 | } 280 | .offset5 { 281 | margin-left: 330px; 282 | } 283 | .offset4 { 284 | margin-left: 268px; 285 | } 286 | .offset3 { 287 | margin-left: 206px; 288 | } 289 | .offset2 { 290 | margin-left: 144px; 291 | } 292 | .offset1 { 293 | margin-left: 82px; 294 | } 295 | .row-fluid { 296 | width: 100%; 297 | *zoom: 1; 298 | } 299 | .row-fluid:before, 300 | .row-fluid:after { 301 | display: table; 302 | content: ""; 303 | } 304 | .row-fluid:after { 305 | clear: both; 306 | } 307 | .row-fluid [class*="span"] { 308 | display: block; 309 | float: left; 310 | width: 100%; 311 | min-height: 28px; 312 | margin-left: 2.762430939%; 313 | *margin-left: 2.709239449638298%; 314 | -webkit-box-sizing: border-box; 315 | -moz-box-sizing: border-box; 316 | -ms-box-sizing: border-box; 317 | box-sizing: border-box; 318 | } 319 | .row-fluid [class*="span"]:first-child { 320 | margin-left: 0; 321 | } 322 | .row-fluid .span12 { 323 | width: 99.999999993%; 324 | *width: 99.9468085036383%; 325 | } 326 | .row-fluid .span11 { 327 | width: 91.436464082%; 328 | *width: 91.38327259263829%; 329 | } 330 | .row-fluid .span10 { 331 | width: 82.87292817100001%; 332 | *width: 82.8197366816383%; 333 | } 334 | .row-fluid .span9 { 335 | width: 74.30939226%; 336 | *width: 74.25620077063829%; 337 | } 338 | .row-fluid .span8 { 339 | width: 65.74585634900001%; 340 | *width: 65.6926648596383%; 341 | } 342 | .row-fluid .span7 { 343 | width: 57.182320438000005%; 344 | *width: 57.129128948638304%; 345 | } 346 | .row-fluid .span6 { 347 | width: 48.618784527%; 348 | *width: 48.5655930376383%; 349 | } 350 | .row-fluid .span5 { 351 | width: 40.055248616%; 352 | *width: 40.0020571266383%; 353 | } 354 | .row-fluid .span4 { 355 | width: 31.491712705%; 356 | *width: 31.4385212156383%; 357 | } 358 | .row-fluid .span3 { 359 | width: 22.928176794%; 360 | *width: 22.874985304638297%; 361 | } 362 | .row-fluid .span2 { 363 | width: 14.364640883%; 364 | *width: 14.311449393638298%; 365 | } 366 | .row-fluid .span1 { 367 | width: 5.801104972%; 368 | *width: 5.747913482638298%; 369 | } 370 | input, 371 | textarea, 372 | .uneditable-input { 373 | margin-left: 0; 374 | } 375 | input.span12, 376 | textarea.span12, 377 | .uneditable-input.span12 { 378 | width: 714px; 379 | } 380 | input.span11, 381 | textarea.span11, 382 | .uneditable-input.span11 { 383 | width: 652px; 384 | } 385 | input.span10, 386 | textarea.span10, 387 | .uneditable-input.span10 { 388 | width: 590px; 389 | } 390 | input.span9, 391 | textarea.span9, 392 | .uneditable-input.span9 { 393 | width: 528px; 394 | } 395 | input.span8, 396 | textarea.span8, 397 | .uneditable-input.span8 { 398 | width: 466px; 399 | } 400 | input.span7, 401 | textarea.span7, 402 | .uneditable-input.span7 { 403 | width: 404px; 404 | } 405 | input.span6, 406 | textarea.span6, 407 | .uneditable-input.span6 { 408 | width: 342px; 409 | } 410 | input.span5, 411 | textarea.span5, 412 | .uneditable-input.span5 { 413 | width: 280px; 414 | } 415 | input.span4, 416 | textarea.span4, 417 | .uneditable-input.span4 { 418 | width: 218px; 419 | } 420 | input.span3, 421 | textarea.span3, 422 | .uneditable-input.span3 { 423 | width: 156px; 424 | } 425 | input.span2, 426 | textarea.span2, 427 | .uneditable-input.span2 { 428 | width: 94px; 429 | } 430 | input.span1, 431 | textarea.span1, 432 | .uneditable-input.span1 { 433 | width: 32px; 434 | } 435 | } 436 | 437 | @media (min-width: 1200px) { 438 | .row { 439 | margin-left: -30px; 440 | *zoom: 1; 441 | } 442 | .row:before, 443 | .row:after { 444 | display: table; 445 | content: ""; 446 | } 447 | .row:after { 448 | clear: both; 449 | } 450 | [class*="span"] { 451 | float: left; 452 | margin-left: 30px; 453 | } 454 | .container, 455 | .navbar-fixed-top .container, 456 | .navbar-fixed-bottom .container { 457 | width: 1170px; 458 | } 459 | .span12 { 460 | width: 1170px; 461 | } 462 | .span11 { 463 | width: 1070px; 464 | } 465 | .span10 { 466 | width: 970px; 467 | } 468 | .span9 { 469 | width: 870px; 470 | } 471 | .span8 { 472 | width: 770px; 473 | } 474 | .span7 { 475 | width: 670px; 476 | } 477 | .span6 { 478 | width: 570px; 479 | } 480 | .span5 { 481 | width: 470px; 482 | } 483 | .span4 { 484 | width: 370px; 485 | } 486 | .span3 { 487 | width: 270px; 488 | } 489 | .span2 { 490 | width: 170px; 491 | } 492 | .span1 { 493 | width: 70px; 494 | } 495 | .offset12 { 496 | margin-left: 1230px; 497 | } 498 | .offset11 { 499 | margin-left: 1130px; 500 | } 501 | .offset10 { 502 | margin-left: 1030px; 503 | } 504 | .offset9 { 505 | margin-left: 930px; 506 | } 507 | .offset8 { 508 | margin-left: 830px; 509 | } 510 | .offset7 { 511 | margin-left: 730px; 512 | } 513 | .offset6 { 514 | margin-left: 630px; 515 | } 516 | .offset5 { 517 | margin-left: 530px; 518 | } 519 | .offset4 { 520 | margin-left: 430px; 521 | } 522 | .offset3 { 523 | margin-left: 330px; 524 | } 525 | .offset2 { 526 | margin-left: 230px; 527 | } 528 | .offset1 { 529 | margin-left: 130px; 530 | } 531 | .row-fluid { 532 | width: 100%; 533 | *zoom: 1; 534 | } 535 | .row-fluid:before, 536 | .row-fluid:after { 537 | display: table; 538 | content: ""; 539 | } 540 | .row-fluid:after { 541 | clear: both; 542 | } 543 | .row-fluid [class*="span"] { 544 | display: block; 545 | float: left; 546 | width: 100%; 547 | min-height: 28px; 548 | margin-left: 2.564102564%; 549 | *margin-left: 2.510911074638298%; 550 | -webkit-box-sizing: border-box; 551 | -moz-box-sizing: border-box; 552 | -ms-box-sizing: border-box; 553 | box-sizing: border-box; 554 | } 555 | .row-fluid [class*="span"]:first-child { 556 | margin-left: 0; 557 | } 558 | .row-fluid .span12 { 559 | width: 100%; 560 | *width: 99.94680851063829%; 561 | } 562 | .row-fluid .span11 { 563 | width: 91.45299145300001%; 564 | *width: 91.3997999636383%; 565 | } 566 | .row-fluid .span10 { 567 | width: 82.905982906%; 568 | *width: 82.8527914166383%; 569 | } 570 | .row-fluid .span9 { 571 | width: 74.358974359%; 572 | *width: 74.30578286963829%; 573 | } 574 | .row-fluid .span8 { 575 | width: 65.81196581200001%; 576 | *width: 65.7587743226383%; 577 | } 578 | .row-fluid .span7 { 579 | width: 57.264957265%; 580 | *width: 57.2117657756383%; 581 | } 582 | .row-fluid .span6 { 583 | width: 48.717948718%; 584 | *width: 48.6647572286383%; 585 | } 586 | .row-fluid .span5 { 587 | width: 40.170940171000005%; 588 | *width: 40.117748681638304%; 589 | } 590 | .row-fluid .span4 { 591 | width: 31.623931624%; 592 | *width: 31.5707401346383%; 593 | } 594 | .row-fluid .span3 { 595 | width: 23.076923077%; 596 | *width: 23.0237315876383%; 597 | } 598 | .row-fluid .span2 { 599 | width: 14.529914530000001%; 600 | *width: 14.4767230406383%; 601 | } 602 | .row-fluid .span1 { 603 | width: 5.982905983%; 604 | *width: 5.929714493638298%; 605 | } 606 | input, 607 | textarea, 608 | .uneditable-input { 609 | margin-left: 0; 610 | } 611 | input.span12, 612 | textarea.span12, 613 | .uneditable-input.span12 { 614 | width: 1160px; 615 | } 616 | input.span11, 617 | textarea.span11, 618 | .uneditable-input.span11 { 619 | width: 1060px; 620 | } 621 | input.span10, 622 | textarea.span10, 623 | .uneditable-input.span10 { 624 | width: 960px; 625 | } 626 | input.span9, 627 | textarea.span9, 628 | .uneditable-input.span9 { 629 | width: 860px; 630 | } 631 | input.span8, 632 | textarea.span8, 633 | .uneditable-input.span8 { 634 | width: 760px; 635 | } 636 | input.span7, 637 | textarea.span7, 638 | .uneditable-input.span7 { 639 | width: 660px; 640 | } 641 | input.span6, 642 | textarea.span6, 643 | .uneditable-input.span6 { 644 | width: 560px; 645 | } 646 | input.span5, 647 | textarea.span5, 648 | .uneditable-input.span5 { 649 | width: 460px; 650 | } 651 | input.span4, 652 | textarea.span4, 653 | .uneditable-input.span4 { 654 | width: 360px; 655 | } 656 | input.span3, 657 | textarea.span3, 658 | .uneditable-input.span3 { 659 | width: 260px; 660 | } 661 | input.span2, 662 | textarea.span2, 663 | .uneditable-input.span2 { 664 | width: 160px; 665 | } 666 | input.span1, 667 | textarea.span1, 668 | .uneditable-input.span1 { 669 | width: 60px; 670 | } 671 | .thumbnails { 672 | margin-left: -30px; 673 | } 674 | .thumbnails > li { 675 | margin-left: 30px; 676 | } 677 | .row-fluid .thumbnails { 678 | margin-left: 0; 679 | } 680 | } 681 | 682 | @media (max-width: 979px) { 683 | body { 684 | padding-top: 0; 685 | } 686 | .navbar-fixed-top, 687 | .navbar-fixed-bottom { 688 | position: static; 689 | } 690 | .navbar-fixed-top { 691 | margin-bottom: 18px; 692 | } 693 | .navbar-fixed-bottom { 694 | margin-top: 18px; 695 | } 696 | .navbar-fixed-top .navbar-inner, 697 | .navbar-fixed-bottom .navbar-inner { 698 | padding: 5px; 699 | } 700 | .navbar .container { 701 | width: auto; 702 | padding: 0; 703 | } 704 | .navbar .brand { 705 | padding-right: 10px; 706 | padding-left: 10px; 707 | margin: 0 0 0 -5px; 708 | } 709 | .nav-collapse { 710 | clear: both; 711 | } 712 | .nav-collapse .nav { 713 | float: none; 714 | margin: 0 0 9px; 715 | } 716 | .nav-collapse .nav > li { 717 | float: none; 718 | } 719 | .nav-collapse .nav > li > a { 720 | margin-bottom: 2px; 721 | } 722 | .nav-collapse .nav > .divider-vertical { 723 | display: none; 724 | } 725 | .nav-collapse .nav .nav-header { 726 | color: #999999; 727 | text-shadow: none; 728 | } 729 | .nav-collapse .nav > li > a, 730 | .nav-collapse .dropdown-menu a { 731 | padding: 6px 15px; 732 | font-weight: bold; 733 | color: #999999; 734 | -webkit-border-radius: 3px; 735 | -moz-border-radius: 3px; 736 | border-radius: 3px; 737 | } 738 | .nav-collapse .btn { 739 | padding: 4px 10px 4px; 740 | font-weight: normal; 741 | -webkit-border-radius: 4px; 742 | -moz-border-radius: 4px; 743 | border-radius: 4px; 744 | } 745 | .nav-collapse .dropdown-menu li + li a { 746 | margin-bottom: 2px; 747 | } 748 | .nav-collapse .nav > li > a:hover, 749 | .nav-collapse .dropdown-menu a:hover { 750 | background-color: #222222; 751 | } 752 | .nav-collapse.in .btn-group { 753 | padding: 0; 754 | margin-top: 5px; 755 | } 756 | .nav-collapse .dropdown-menu { 757 | position: static; 758 | top: auto; 759 | left: auto; 760 | display: block; 761 | float: none; 762 | max-width: none; 763 | padding: 0; 764 | margin: 0 15px; 765 | background-color: transparent; 766 | border: none; 767 | -webkit-border-radius: 0; 768 | -moz-border-radius: 0; 769 | border-radius: 0; 770 | -webkit-box-shadow: none; 771 | -moz-box-shadow: none; 772 | box-shadow: none; 773 | } 774 | .nav-collapse .dropdown-menu:before, 775 | .nav-collapse .dropdown-menu:after { 776 | display: none; 777 | } 778 | .nav-collapse .dropdown-menu .divider { 779 | display: none; 780 | } 781 | .nav-collapse .navbar-form, 782 | .nav-collapse .navbar-search { 783 | float: none; 784 | padding: 9px 15px; 785 | margin: 9px 0; 786 | border-top: 1px solid #222222; 787 | border-bottom: 1px solid #222222; 788 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 789 | -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 790 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); 791 | } 792 | .navbar .nav-collapse .nav.pull-right { 793 | float: none; 794 | margin-left: 0; 795 | } 796 | .nav-collapse, 797 | .nav-collapse.collapse { 798 | height: 0; 799 | overflow: hidden; 800 | } 801 | .navbar .btn-navbar { 802 | display: block; 803 | } 804 | .navbar-static .navbar-inner { 805 | padding-right: 10px; 806 | padding-left: 10px; 807 | } 808 | } 809 | 810 | @media (min-width: 980px) { 811 | .nav-collapse.collapse { 812 | height: auto !important; 813 | overflow: visible !important; 814 | } 815 | } 816 | -------------------------------------------------------------------------------- /bootstrap/css/docs.css: -------------------------------------------------------------------------------- 1 | /* Add additional stylesheets below 2 | -------------------------------------------------- */ 3 | /* 4 | Bootstrap's documentation styles 5 | Special styles for presenting Bootstrap's documentation and examples 6 | */ 7 | 8 | 9 | /* Body and structure 10 | -------------------------------------------------- */ 11 | body { 12 | position: relative; 13 | padding-top: 90px; 14 | background-color: #fff; 15 | background-image: url(../img/grid-18px-masked.png); 16 | background-repeat: repeat-x; 17 | background-position: 0 40px; 18 | } 19 | 20 | 21 | /* Tweak navbar brand link to be super sleek 22 | -------------------------------------------------- */ 23 | .navbar-fixed-top .brand { 24 | padding-right: 0; 25 | padding-left: 0; 26 | margin-left: 20px; 27 | float: right; 28 | font-weight: bold; 29 | color: #000; 30 | text-shadow: 0 1px 0 rgba(255,255,255,.1), 0 0 30px rgba(255,255,255,.125); 31 | -webkit-transition: all .2s linear; 32 | -moz-transition: all .2s linear; 33 | transition: all .2s linear; 34 | } 35 | .navbar-fixed-top .brand:hover { 36 | text-decoration: none; 37 | } 38 | 39 | 40 | /* Space out sub-sections more 41 | -------------------------------------------------- */ 42 | section { 43 | padding-top: 60px; 44 | } 45 | 46 | /* Faded out hr */ 47 | hr.soften { 48 | height: 1px; 49 | margin: 54px 0; 50 | background-image: -webkit-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); 51 | background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); 52 | background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); 53 | background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); 54 | border: 0; 55 | } 56 | 57 | 58 | /* Jumbotrons 59 | -------------------------------------------------- */ 60 | .jumbotron { 61 | position: relative; 62 | } 63 | .jumbotron h1 { 64 | margin-bottom: 9px; 65 | font-size: 81px; 66 | font-weight: bold; 67 | letter-spacing: -1px; 68 | line-height: 1; 69 | } 70 | .jumbotron p { 71 | margin-bottom: 18px; 72 | font-weight: 300; 73 | } 74 | .jumbotron .btn-large { 75 | font-size: 20px; 76 | font-weight: normal; 77 | padding: 14px 24px; 78 | margin-right: 10px; 79 | -webkit-border-radius: 6px; 80 | -moz-border-radius: 6px; 81 | border-radius: 6px; 82 | } 83 | .jumbotron .btn-large small { 84 | font-size: 14px; 85 | } 86 | 87 | /* Masthead (docs home) */ 88 | .masthead { 89 | padding-top: 36px; 90 | margin-bottom: 72px; 91 | } 92 | .masthead h1, 93 | .masthead p { 94 | text-align: center; 95 | } 96 | .masthead h1 { 97 | margin-bottom: 18px; 98 | } 99 | .masthead p { 100 | margin-left: 5%; 101 | margin-right: 5%; 102 | font-size: 30px; 103 | line-height: 36px; 104 | } 105 | 106 | 107 | /* Specific jumbotrons 108 | ------------------------- */ 109 | /* supporting docs pages */ 110 | .subhead { 111 | padding-bottom: 0; 112 | margin-bottom: 9px; 113 | } 114 | .subhead h1 { 115 | font-size: 54px; 116 | } 117 | 118 | /* Subnav */ 119 | .subnav { 120 | width: 100%; 121 | height: 36px; 122 | background-color: #eeeeee; /* Old browsers */ 123 | background-repeat: repeat-x; /* Repeat the gradient */ 124 | background-image: -moz-linear-gradient(top, #f5f5f5 0%, #eeeeee 100%); /* FF3.6+ */ 125 | background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f5f5f5), color-stop(100%,#eeeeee)); /* Chrome,Safari4+ */ 126 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Chrome 10+,Safari 5.1+ */ 127 | background-image: -ms-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* IE10+ */ 128 | background-image: -o-linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* Opera 11.10+ */ 129 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f5f5f5', endColorstr='#eeeeee',GradientType=0 ); /* IE6-9 */ 130 | background-image: linear-gradient(top, #f5f5f5 0%,#eeeeee 100%); /* W3C */ 131 | border: 1px solid #e5e5e5; 132 | -webkit-border-radius: 4px; 133 | -moz-border-radius: 4px; 134 | border-radius: 4px; 135 | } 136 | .subnav .nav { 137 | margin-bottom: 0; 138 | } 139 | .subnav .nav > li > a { 140 | margin: 0; 141 | padding-top: 11px; 142 | padding-bottom: 11px; 143 | border-left: 1px solid #f5f5f5; 144 | border-right: 1px solid #e5e5e5; 145 | -webkit-border-radius: 0; 146 | -moz-border-radius: 0; 147 | border-radius: 0; 148 | } 149 | .subnav .nav > .active > a, 150 | .subnav .nav > .active > a:hover { 151 | padding-left: 13px; 152 | color: #777; 153 | background-color: #e9e9e9; 154 | border-right-color: #ddd; 155 | border-left: 0; 156 | -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 157 | -moz-box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 158 | box-shadow: inset 0 3px 5px rgba(0,0,0,.05); 159 | } 160 | .subnav .nav > .active > a .caret, 161 | .subnav .nav > .active > a:hover .caret { 162 | border-top-color: #777; 163 | } 164 | .subnav .nav > li:first-child > a, 165 | .subnav .nav > li:first-child > a:hover { 166 | border-left: 0; 167 | padding-left: 12px; 168 | -webkit-border-radius: 4px 0 0 4px; 169 | -moz-border-radius: 4px 0 0 4px; 170 | border-radius: 4px 0 0 4px; 171 | } 172 | .subnav .nav > li:last-child > a { 173 | border-right: 0; 174 | } 175 | .subnav .dropdown-menu { 176 | -webkit-border-radius: 0 0 4px 4px; 177 | -moz-border-radius: 0 0 4px 4px; 178 | border-radius: 0 0 4px 4px; 179 | } 180 | 181 | /* Fixed subnav on scroll, but only for 980px and up (sorry IE!) */ 182 | @media (min-width: 980px) { 183 | .subnav-fixed { 184 | position: fixed; 185 | top: 40px; 186 | left: 0; 187 | right: 0; 188 | z-index: 1020; /* 10 less than .navbar-fixed to prevent any overlap */ 189 | border-color: #d5d5d5; 190 | border-width: 0 0 1px; /* drop the border on the fixed edges */ 191 | -webkit-border-radius: 0; 192 | -moz-border-radius: 0; 193 | border-radius: 0; 194 | -webkit-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 195 | -moz-box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 196 | box-shadow: inset 0 1px 0 #fff, 0 1px 5px rgba(0,0,0,.1); 197 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); /* IE6-9 */ 198 | } 199 | .subnav-fixed .nav { 200 | width: 938px; 201 | margin: 0 auto; 202 | padding: 0 1px; 203 | } 204 | .subnav .nav > li:first-child > a, 205 | .subnav .nav > li:first-child > a:hover { 206 | -webkit-border-radius: 0; 207 | -moz-border-radius: 0; 208 | border-radius: 0; 209 | } 210 | } 211 | 212 | 213 | /* Quick links 214 | -------------------------------------------------- */ 215 | .bs-links { 216 | margin: 36px 0; 217 | } 218 | .quick-links { 219 | min-height: 30px; 220 | margin: 0; 221 | padding: 5px 20px; 222 | list-style: none; 223 | text-align: center; 224 | overflow: hidden; 225 | } 226 | .quick-links:first-child { 227 | min-height: 0; 228 | } 229 | .quick-links li { 230 | display: inline; 231 | margin: 0 8px; 232 | color: #999; 233 | } 234 | .quick-links .github-btn, 235 | .quick-links .tweet-btn, 236 | .quick-links .follow-btn { 237 | position: relative; 238 | top: 5px; 239 | } 240 | 241 | 242 | /* Marketing section of Overview 243 | -------------------------------------------------- */ 244 | .marketing .row { 245 | margin-bottom: 9px; 246 | } 247 | .marketing h1 { 248 | margin: 36px 0 27px; 249 | font-size: 40px; 250 | font-weight: 300; 251 | text-align: center; 252 | } 253 | .marketing h2, 254 | .marketing h3 { 255 | font-weight: 300; 256 | } 257 | .marketing h2 { 258 | font-size: 22px; 259 | } 260 | .marketing p { 261 | margin-right: 10px; 262 | } 263 | .marketing .bs-icon { 264 | float: left; 265 | margin: 7px 10px 0 0; 266 | opacity: .8; 267 | } 268 | .marketing .small-bs-icon { 269 | float: left; 270 | margin: 4px 5px 0 0; 271 | } 272 | 273 | 274 | 275 | /* Footer 276 | -------------------------------------------------- */ 277 | .footer { 278 | margin-top: 45px; 279 | padding: 35px 0 36px; 280 | border-top: 1px solid #e5e5e5; 281 | } 282 | .footer p { 283 | margin-bottom: 0; 284 | color: #555; 285 | } 286 | 287 | 288 | 289 | /* Special grid styles 290 | -------------------------------------------------- */ 291 | .show-grid { 292 | margin-top: 10px; 293 | margin-bottom: 20px; 294 | } 295 | .show-grid [class*="span"] { 296 | background-color: #eee; 297 | text-align: center; 298 | -webkit-border-radius: 3px; 299 | -moz-border-radius: 3px; 300 | border-radius: 3px; 301 | min-height: 30px; 302 | line-height: 30px; 303 | } 304 | .show-grid:hover [class*="span"] { 305 | background: #ddd; 306 | } 307 | .show-grid .show-grid { 308 | margin-top: 0; 309 | margin-bottom: 0; 310 | } 311 | .show-grid .show-grid [class*="span"] { 312 | background-color: #ccc; 313 | } 314 | 315 | 316 | /* Render mini layout previews 317 | -------------------------------------------------- */ 318 | .mini-layout { 319 | border: 1px solid #ddd; 320 | -webkit-border-radius: 6px; 321 | -moz-border-radius: 6px; 322 | border-radius: 6px; 323 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.075); 324 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,.075); 325 | box-shadow: 0 1px 2px rgba(0,0,0,.075); 326 | } 327 | .mini-layout { 328 | height: 240px; 329 | margin-bottom: 20px; 330 | padding: 9px; 331 | } 332 | .mini-layout div { 333 | -webkit-border-radius: 3px; 334 | -moz-border-radius: 3px; 335 | border-radius: 3px; 336 | } 337 | .mini-layout .mini-layout-body { 338 | background-color: #dceaf4; 339 | margin: 0 auto; 340 | width: 70%; 341 | height: 240px; 342 | } 343 | .mini-layout.fluid .mini-layout-sidebar, 344 | .mini-layout.fluid .mini-layout-header, 345 | .mini-layout.fluid .mini-layout-body { 346 | float: left; 347 | } 348 | .mini-layout.fluid .mini-layout-sidebar { 349 | background-color: #bbd8e9; 350 | width: 20%; 351 | height: 240px; 352 | } 353 | .mini-layout.fluid .mini-layout-body { 354 | width: 77.5%; 355 | margin-left: 2.5%; 356 | } 357 | 358 | 359 | /* Popover docs 360 | -------------------------------------------------- */ 361 | .popover-well { 362 | min-height: 160px; 363 | } 364 | .popover-well .popover { 365 | display: block; 366 | } 367 | .popover-well .popover-wrapper { 368 | width: 50%; 369 | height: 160px; 370 | float: left; 371 | margin-left: 55px; 372 | position: relative; 373 | } 374 | .popover-well .popover-menu-wrapper { 375 | height: 80px; 376 | } 377 | .large-bird { 378 | margin: 5px 0 0 310px; 379 | opacity: .1; 380 | } 381 | 382 | 383 | /* Download page 384 | -------------------------------------------------- */ 385 | .download .page-header { 386 | margin-top: 36px; 387 | } 388 | .page-header .toggle-all { 389 | margin-top: 5px; 390 | } 391 | 392 | /* Space out h3s when following a section */ 393 | .download h3 { 394 | margin-bottom: 5px; 395 | } 396 | .download-builder input + h3, 397 | .download-builder .checkbox + h3 { 398 | margin-top: 9px; 399 | } 400 | 401 | /* Fields for variables */ 402 | .download-builder input[type=text] { 403 | margin-bottom: 9px; 404 | font-family: Menlo, Monaco, "Courier New", monospace; 405 | font-size: 12px; 406 | color: #d14; 407 | } 408 | .download-builder input[type=text]:focus { 409 | background-color: #fff; 410 | } 411 | 412 | /* Custom, larger checkbox labels */ 413 | .download .checkbox { 414 | padding: 6px 10px 6px 25px; 415 | color: #555; 416 | background-color: #f9f9f9; 417 | -webkit-border-radius: 3px; 418 | -moz-border-radius: 3px; 419 | border-radius: 3px; 420 | cursor: pointer; 421 | } 422 | .download .checkbox:hover { 423 | color: #333; 424 | background-color: #f5f5f5; 425 | } 426 | .download .checkbox small { 427 | font-size: 12px; 428 | color: #777; 429 | } 430 | 431 | /* Variables section */ 432 | #variables label { 433 | margin-bottom: 0; 434 | } 435 | 436 | /* Giant download button */ 437 | .download-btn { 438 | margin: 36px 0 108px; 439 | } 440 | #download p, 441 | #download h4 { 442 | max-width: 50%; 443 | margin: 0 auto; 444 | color: #999; 445 | text-align: center; 446 | } 447 | #download h4 { 448 | margin-bottom: 0; 449 | } 450 | #download p { 451 | margin-bottom: 18px; 452 | } 453 | .download-btn .btn { 454 | display: block; 455 | width: auto; 456 | padding: 19px 24px; 457 | margin-bottom: 27px; 458 | font-size: 30px; 459 | line-height: 1; 460 | text-align: center; 461 | -webkit-border-radius: 6px; 462 | -moz-border-radius: 6px; 463 | border-radius: 6px; 464 | } 465 | 466 | 467 | 468 | /* Color swatches on LESS docs page 469 | -------------------------------------------------- */ 470 | /* Sets the width of the td */ 471 | .swatch-col { 472 | width: 30px; 473 | } 474 | /* Le swatch */ 475 | .swatch { 476 | display: inline-block; 477 | width: 30px; 478 | height: 20px; 479 | margin: -6px 0; 480 | -webkit-border-radius: 3px; 481 | -moz-border-radius: 3px; 482 | border-radius: 3px; 483 | } 484 | /* For white swatches, give a border */ 485 | .swatch-bordered { 486 | width: 28px; 487 | height: 18px; 488 | border: 1px solid #eee; 489 | } 490 | 491 | 492 | /* Misc 493 | -------------------------------------------------- */ 494 | 495 | /* Make tables spaced out a bit more */ 496 | h2 + table, 497 | h3 + table, 498 | h4 + table, 499 | h2 + .row { 500 | margin-top: 5px; 501 | } 502 | 503 | /* Example sites showcase */ 504 | .example-sites img { 505 | max-width: 100%; 506 | margin: 0 auto; 507 | } 508 | .marketing-byline { 509 | margin: -18px 0 27px; 510 | font-size: 18px; 511 | font-weight: 300; 512 | line-height: 24px; 513 | color: #999; 514 | text-align: center; 515 | } 516 | 517 | .scrollspy-example { 518 | height: 200px; 519 | overflow: auto; 520 | position: relative; 521 | } 522 | 523 | /* Remove bottom margin on example forms in wells */ 524 | form.well { 525 | padding: 14px; 526 | } 527 | 528 | /* Tighten up spacing */ 529 | .well hr { 530 | margin: 18px 0; 531 | } 532 | 533 | /* Fake the :focus state to demo it */ 534 | .focused { 535 | border-color: rgba(82,168,236,.8); 536 | -webkit-box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); 537 | -moz-box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); 538 | box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); 539 | outline: 0; 540 | } 541 | 542 | /* For input sizes, make them display block */ 543 | .docs-input-sizes select, 544 | .docs-input-sizes input[type=text] { 545 | display: block; 546 | margin-bottom: 9px; 547 | } 548 | 549 | /* Icons 550 | ------------------------- */ 551 | .the-icons { 552 | margin-left: 0; 553 | list-style: none; 554 | } 555 | .the-icons i:hover { 556 | background-color: rgba(255,0,0,.25); 557 | } 558 | 559 | /* Eaxmples page 560 | ------------------------- */ 561 | .bootstrap-examples .thumbnail { 562 | margin-bottom: 9px; 563 | background-color: #fff; 564 | } 565 | 566 | /* Responsive table 567 | ------------------------- */ 568 | .responsive-utilities th small { 569 | display: block; 570 | font-weight: normal; 571 | color: #999; 572 | } 573 | .responsive-utilities tbody th { 574 | font-weight: normal; 575 | } 576 | .responsive-utilities td { 577 | text-align: center; 578 | } 579 | .responsive-utilities td.is-visible { 580 | color: #468847; 581 | background-color: #dff0d8 !important; 582 | } 583 | .responsive-utilities td.is-hidden { 584 | color: #ccc; 585 | background-color: #f9f9f9 !important; 586 | } 587 | 588 | /* Responsive tests 589 | ------------------------- */ 590 | .responsive-utilities-test { 591 | margin-top: 5px; 592 | margin-left: 0; 593 | list-style: none; 594 | overflow: hidden; /* clear floats */ 595 | } 596 | .responsive-utilities-test li { 597 | position: relative; 598 | float: left; 599 | width: 25%; 600 | height: 43px; 601 | font-size: 14px; 602 | font-weight: bold; 603 | line-height: 43px; 604 | color: #999; 605 | text-align: center; 606 | border: 1px solid #ddd; 607 | -webkit-border-radius: 4px; 608 | -moz-border-radius: 4px; 609 | border-radius: 4px; 610 | } 611 | .responsive-utilities-test li + li { 612 | margin-left: 10px; 613 | } 614 | .responsive-utilities-test span { 615 | position: absolute; 616 | top: -1px; 617 | left: -1px; 618 | right: -1px; 619 | bottom: -1px; 620 | -webkit-border-radius: 4px; 621 | -moz-border-radius: 4px; 622 | border-radius: 4px; 623 | } 624 | .responsive-utilities-test span { 625 | color: #468847; 626 | background-color: #dff0d8; 627 | border: 1px solid #d6e9c6; 628 | } 629 | 630 | 631 | /* Responsive Docs 632 | -------------------------------------------------- */ 633 | @media (max-width: 480px) { 634 | 635 | /* Reduce padding above jumbotron */ 636 | body { 637 | padding-top: 70px; 638 | } 639 | 640 | /* Change up some type stuff */ 641 | h2 { 642 | margin-top: 27px; 643 | } 644 | h2 small { 645 | display: block; 646 | line-height: 18px; 647 | } 648 | h3 { 649 | margin-top: 18px; 650 | } 651 | 652 | /* icons */ 653 | .marketing .bs-icon { 654 | margin: 0; 655 | } 656 | 657 | /* Adjust the jumbotron */ 658 | .jumbotron h1, 659 | .jumbotron p { 660 | text-align: center; 661 | margin-right: 0; 662 | } 663 | .jumbotron h1 { 664 | font-size: 45px; 665 | margin-right: 0; 666 | } 667 | .jumbotron p { 668 | margin-right: 0; 669 | margin-left: 0; 670 | font-size: 18px; 671 | line-height: 24px; 672 | } 673 | .jumbotron .btn { 674 | display: block; 675 | font-size: 18px; 676 | padding: 10px 14px; 677 | margin: 0 auto 10px; 678 | } 679 | /* Masthead (home page jumbotron) */ 680 | .masthead { 681 | padding-top: 0; 682 | } 683 | 684 | /* Don't space out quick links so much */ 685 | .quick-links { 686 | margin: 40px 0 0; 687 | } 688 | /* hide the bullets on mobile since our horizontal space is limited */ 689 | .quick-links .divider { 690 | display: none; 691 | } 692 | 693 | /* center example sites */ 694 | .example-sites { 695 | margin-left: 0; 696 | } 697 | .example-sites > li { 698 | float: none; 699 | display: block; 700 | max-width: 280px; 701 | margin: 0 auto 18px; 702 | text-align: center; 703 | } 704 | .example-sites .thumbnail > img { 705 | max-width: 270px; 706 | } 707 | 708 | table code { 709 | white-space: normal; 710 | word-wrap: break-word; 711 | word-break: break-all; 712 | } 713 | 714 | /* Modal example */ 715 | .modal-example .modal { 716 | position: relative; 717 | top: auto; 718 | right: auto; 719 | bottom: auto; 720 | left: auto; 721 | } 722 | 723 | } 724 | 725 | 726 | @media (max-width: 768px) { 727 | 728 | /* Remove any padding from the body */ 729 | body { 730 | padding-top: 0; 731 | } 732 | 733 | /* Jumbotron buttons */ 734 | .jumbotron .btn { 735 | margin-bottom: 10px; 736 | } 737 | 738 | /* Subnav */ 739 | .subnav { 740 | position: static; 741 | top: auto; 742 | z-index: auto; 743 | width: auto; 744 | height: auto; 745 | background: #fff; /* whole background property since we use a background-image for gradient */ 746 | -webkit-box-shadow: none; 747 | -moz-box-shadow: none; 748 | box-shadow: none; 749 | } 750 | .subnav .nav > li { 751 | float: none; 752 | } 753 | .subnav .nav > li > a { 754 | border: 0; 755 | } 756 | .subnav .nav > li + li > a { 757 | border-top: 1px solid #e5e5e5; 758 | } 759 | .subnav .nav > li:first-child > a, 760 | .subnav .nav > li:first-child > a:hover { 761 | -webkit-border-radius: 4px 4px 0 0; 762 | -moz-border-radius: 4px 4px 0 0; 763 | border-radius: 4px 4px 0 0; 764 | } 765 | 766 | /* Popovers */ 767 | .large-bird { 768 | display: none; 769 | } 770 | .popover-well .popover-wrapper { 771 | margin-left: 0; 772 | } 773 | 774 | /* Space out the show-grid examples */ 775 | .show-grid [class*="span"] { 776 | margin-bottom: 5px; 777 | } 778 | 779 | /* Unfloat the back to top link in footer */ 780 | .footer .pull-right { 781 | float: none; 782 | } 783 | .footer p { 784 | margin-bottom: 9px; 785 | } 786 | 787 | } 788 | 789 | 790 | @media (min-width: 480px) and (max-width: 768px) { 791 | 792 | /* Scale down the jumbotron content */ 793 | .jumbotron h1 { 794 | font-size: 54px; 795 | } 796 | .jumbotron p { 797 | margin-right: 0; 798 | margin-left: 0; 799 | } 800 | 801 | } 802 | 803 | 804 | @media (min-width: 768px) and (max-width: 980px) { 805 | 806 | /* Remove any padding from the body */ 807 | body { 808 | padding-top: 0; 809 | } 810 | 811 | /* Scale down the jumbotron content */ 812 | .jumbotron h1 { 813 | font-size: 72px; 814 | } 815 | 816 | } 817 | 818 | 819 | @media (max-width: 980px) { 820 | 821 | /* Unfloat brand */ 822 | .navbar-fixed-top .brand { 823 | float: left; 824 | margin-left: 0; 825 | padding-left: 10px; 826 | padding-right: 10px; 827 | } 828 | 829 | /* Inline-block quick links for more spacing */ 830 | .quick-links li { 831 | display: inline-block; 832 | margin: 5px; 833 | } 834 | 835 | } 836 | 837 | 838 | /* LARGE DESKTOP SCREENS */ 839 | @media (min-width: 1210px) { 840 | 841 | /* Update subnav container */ 842 | .subnav-fixed .nav { 843 | width: 1168px; /* 2px less to account for left/right borders being removed when in fixed mode */ 844 | } 845 | 846 | } 847 | -------------------------------------------------------------------------------- /bootstrap/ico/apple-touch-icon-114-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/ico/apple-touch-icon-114-precomposed.png -------------------------------------------------------------------------------- /bootstrap/ico/apple-touch-icon-144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/ico/apple-touch-icon-144-precomposed.png -------------------------------------------------------------------------------- /bootstrap/ico/apple-touch-icon-57-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/ico/apple-touch-icon-57-precomposed.png -------------------------------------------------------------------------------- /bootstrap/ico/apple-touch-icon-72-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/ico/apple-touch-icon-72-precomposed.png -------------------------------------------------------------------------------- /bootstrap/ico/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/ico/favicon.ico -------------------------------------------------------------------------------- /bootstrap/img/bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/bird.png -------------------------------------------------------------------------------- /bootstrap/img/bootstrap-mdo-sfmoma-01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/bootstrap-mdo-sfmoma-01.jpg -------------------------------------------------------------------------------- /bootstrap/img/bootstrap-mdo-sfmoma-02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/bootstrap-mdo-sfmoma-02.jpg -------------------------------------------------------------------------------- /bootstrap/img/bootstrap-mdo-sfmoma-03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/bootstrap-mdo-sfmoma-03.jpg -------------------------------------------------------------------------------- /bootstrap/img/browsers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/browsers.png -------------------------------------------------------------------------------- /bootstrap/img/example-sites/fleetio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/example-sites/fleetio.png -------------------------------------------------------------------------------- /bootstrap/img/example-sites/jshint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/example-sites/jshint.png -------------------------------------------------------------------------------- /bootstrap/img/example-sites/kippt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/example-sites/kippt.png -------------------------------------------------------------------------------- /bootstrap/img/example-sites/soundready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/example-sites/soundready.png -------------------------------------------------------------------------------- /bootstrap/img/examples/bootstrap-example-fluid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/examples/bootstrap-example-fluid.jpg -------------------------------------------------------------------------------- /bootstrap/img/examples/bootstrap-example-hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/examples/bootstrap-example-hero.jpg -------------------------------------------------------------------------------- /bootstrap/img/examples/bootstrap-example-starter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/examples/bootstrap-example-starter.jpg -------------------------------------------------------------------------------- /bootstrap/img/github-16px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/github-16px.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_009_magic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_009_magic.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_042_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_042_group.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_079_podium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_079_podium.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_082_roundabout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_082_roundabout.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_155_show_thumbnails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_155_show_thumbnails.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_163_iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_163_iphone.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_214_resize_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_214_resize_small.png -------------------------------------------------------------------------------- /bootstrap/img/glyphicons/glyphicons_266_book_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/glyphicons/glyphicons_266_book_open.png -------------------------------------------------------------------------------- /bootstrap/img/grid-18px-masked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/grid-18px-masked.png -------------------------------------------------------------------------------- /bootstrap/img/icon-css3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/icon-css3.png -------------------------------------------------------------------------------- /bootstrap/img/icon-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/icon-github.png -------------------------------------------------------------------------------- /bootstrap/img/icon-html5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/icon-html5.png -------------------------------------------------------------------------------- /bootstrap/img/icon-twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/icon-twitter.png -------------------------------------------------------------------------------- /bootstrap/img/less-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/less-logo-large.png -------------------------------------------------------------------------------- /bootstrap/img/less-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/less-small.png -------------------------------------------------------------------------------- /bootstrap/img/responsive-illustrations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JimAllanson/lifejs/45d680ffcaf11904102220f04ed9becca6a7e330/bootstrap/img/responsive-illustrations.png -------------------------------------------------------------------------------- /bootstrap/js/README.md: -------------------------------------------------------------------------------- 1 | ## 2.0 BOOTSTRAP JS PHILOSOPHY 2 | These are the high-level design rules which guide the development of Bootstrap's plugin apis. 3 | 4 | --- 5 | 6 | ### DATA-ATTRIBUTE API 7 | 8 | We believe you should be able to use all plugins provided by Bootstrap purely through the markup API without writing a single line of javascript. 9 | 10 | We acknowledge that this isn't always the most performant and sometimes it may be desirable to turn this functionality off altogether. Therefore, as of 2.0 we provide the ability to disable the data attribute API by unbinding all events on the body namespaced with `'data-api'`. This looks like this: 11 | 12 | $('body').off('.data-api') 13 | 14 | To target a specific plugin, just include the plugins name as a namespace along with the data-api namespace like this: 15 | 16 | $('body').off('.alert.data-api') 17 | 18 | --- 19 | 20 | ### PROGRAMATIC API 21 | 22 | We also believe you should be able to use all plugins provided by Bootstrap purely through the JS API. 23 | 24 | All public APIs should be single, chainable methods, and return the collection acted upon. 25 | 26 | $(".btn.danger").button("toggle").addClass("fat") 27 | 28 | All methods should accept an optional options object, a string which targets a particular method, or null which initiates the default behavior: 29 | 30 | $("#myModal").modal() // initialized with defaults 31 | $("#myModal").modal({ keyboard: false }) // initialized with now keyboard 32 | $("#myModal").modal('show') // initializes and invokes show immediately afterqwe2 33 | 34 | --- 35 | 36 | ### OPTIONS 37 | 38 | Options should be sparse and add universal value. We should pick the right defaults. 39 | 40 | All plugins should have a default object which can be modified to effect all instance's default options. The defaults object should be available via `$.fn.plugin.defaults`. 41 | 42 | $.fn.modal.defaults = { … } 43 | 44 | An options definition should take the following form: 45 | 46 | *noun*: *adjective* - describes or modifies a quality of an instance 47 | 48 | examples: 49 | 50 | backdrop: true 51 | keyboard: false 52 | placement: 'top' 53 | 54 | --- 55 | 56 | ### EVENTS 57 | 58 | All events should have an infinitive and past participle form. The infinitive is fired just before an action takes place, the past participle on completion of the action. 59 | 60 | show | shown 61 | hide | hidden 62 | 63 | --- 64 | 65 | ### CONSTRUCTORS 66 | 67 | Each plugin should expose it's raw constructor on a `Constructor` property -- accessed in the following way: 68 | 69 | 70 | $.fn.popover.Constructor 71 | 72 | --- 73 | 74 | ### DATA ACCESSOR 75 | 76 | Each plugin stores a copy of the invoked class on an object. This class instance can be accessed directly through jQuery's data API like this: 77 | 78 | $('[rel=popover]').data('popover') instanceof $.fn.popover.Constructor 79 | 80 | --- 81 | 82 | ### DATA ATTRIBUTES 83 | 84 | Data attributes should take the following form: 85 | 86 | - data-{{verb}}={{plugin}} - defines main interaction 87 | - data-target || href^=# - defined on "control" element (if element controls an element other than self) 88 | - data-{{noun}} - defines class instance options 89 | 90 | examples: 91 | 92 | // control other targets 93 | data-toggle="modal" data-target="#foo" 94 | data-toggle="collapse" data-target="#foo" data-parent="#bar" 95 | 96 | // defined on element they control 97 | data-spy="scroll" 98 | 99 | data-dismiss="modal" 100 | data-dismiss="alert" 101 | 102 | data-toggle="dropdown" 103 | 104 | data-toggle="button" 105 | data-toggle="buttons-checkbox" 106 | data-toggle="buttons-radio" -------------------------------------------------------------------------------- /bootstrap/js/application.js: -------------------------------------------------------------------------------- 1 | // NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT 2 | // IT'S ALL JUST JUNK FOR OUR DOCS! 3 | // ++++++++++++++++++++++++++++++++++++++++++ 4 | 5 | !function ($) { 6 | 7 | $(function(){ 8 | 9 | // Disable certain links in docs 10 | $('section [href^=#]').click(function (e) { 11 | e.preventDefault() 12 | }) 13 | 14 | // make code pretty 15 | window.prettyPrint && prettyPrint() 16 | 17 | // add-ons 18 | $('.add-on :checkbox').on('click', function () { 19 | var $this = $(this) 20 | , method = $this.attr('checked') ? 'addClass' : 'removeClass' 21 | $(this).parents('.add-on')[method]('active') 22 | }) 23 | 24 | // position static twipsies for components page 25 | if ($(".twipsies a").length) { 26 | $(window).on('load resize', function () { 27 | $(".twipsies a").each(function () { 28 | $(this) 29 | .tooltip({ 30 | placement: $(this).attr('title') 31 | , trigger: 'manual' 32 | }) 33 | .tooltip('show') 34 | }) 35 | }) 36 | } 37 | 38 | // add tipsies to grid for scaffolding 39 | if ($('#grid-system').length) { 40 | $('#grid-system').tooltip({ 41 | selector: '.show-grid > div' 42 | , title: function () { return $(this).width() + 'px' } 43 | }) 44 | } 45 | 46 | // fix sub nav on scroll 47 | var $win = $(window) 48 | , $nav = $('.subnav') 49 | , navTop = $('.subnav').length && $('.subnav').offset().top - 40 50 | , isFixed = 0 51 | 52 | processScroll() 53 | 54 | // hack sad times - holdover until rewrite for 2.1 55 | $nav.on('click', function () { 56 | if (!isFixed) setTimeout(function () { $win.scrollTop($win.scrollTop() - 47) }, 10) 57 | }) 58 | 59 | $win.on('scroll', processScroll) 60 | 61 | function processScroll() { 62 | var i, scrollTop = $win.scrollTop() 63 | if (scrollTop >= navTop && !isFixed) { 64 | isFixed = 1 65 | $nav.addClass('subnav-fixed') 66 | } else if (scrollTop <= navTop && isFixed) { 67 | isFixed = 0 68 | $nav.removeClass('subnav-fixed') 69 | } 70 | } 71 | 72 | // tooltip demo 73 | $('.tooltip-demo.well').tooltip({ 74 | selector: "a[rel=tooltip]" 75 | }) 76 | 77 | $('.tooltip-test').tooltip() 78 | $('.popover-test').popover() 79 | 80 | // popover demo 81 | $("a[rel=popover]") 82 | .popover() 83 | .click(function(e) { 84 | e.preventDefault() 85 | }) 86 | 87 | // button state demo 88 | $('#fat-btn') 89 | .click(function () { 90 | var btn = $(this) 91 | btn.button('loading') 92 | setTimeout(function () { 93 | btn.button('reset') 94 | }, 3000) 95 | }) 96 | 97 | // carousel demo 98 | $('#myCarousel').carousel() 99 | 100 | // javascript build logic 101 | var inputsComponent = $("#components.download input") 102 | , inputsPlugin = $("#plugins.download input") 103 | , inputsVariables = $("#variables.download input") 104 | 105 | // toggle all plugin checkboxes 106 | $('#components.download .toggle-all').on('click', function (e) { 107 | e.preventDefault() 108 | inputsComponent.attr('checked', !inputsComponent.is(':checked')) 109 | }) 110 | 111 | $('#plugins.download .toggle-all').on('click', function (e) { 112 | e.preventDefault() 113 | inputsPlugin.attr('checked', !inputsPlugin.is(':checked')) 114 | }) 115 | 116 | $('#variables.download .toggle-all').on('click', function (e) { 117 | e.preventDefault() 118 | inputsVariables.val('') 119 | }) 120 | 121 | // request built javascript 122 | $('.download-btn').on('click', function () { 123 | 124 | var css = $("#components.download input:checked") 125 | .map(function () { return this.value }) 126 | .toArray() 127 | , js = $("#plugins.download input:checked") 128 | .map(function () { return this.value }) 129 | .toArray() 130 | , vars = {} 131 | , img = ['glyphicons-halflings.png', 'glyphicons-halflings-white.png'] 132 | 133 | $("#variables.download input") 134 | .each(function () { 135 | $(this).val() && (vars[ $(this).prev().text() ] = $(this).val()) 136 | }) 137 | 138 | $.ajax({ 139 | type: 'POST' 140 | , url: /\?dev/.test(window.location) ? 'http://localhost:3000' : 'http://bootstrap.herokuapp.com' 141 | , dataType: 'jsonpi' 142 | , params: { 143 | js: js 144 | , css: css 145 | , vars: vars 146 | , img: img 147 | } 148 | }) 149 | }) 150 | }) 151 | 152 | // Modified from the original jsonpi https://github.com/benvinegar/jquery-jsonpi 153 | $.ajaxTransport('jsonpi', function(opts, originalOptions, jqXHR) { 154 | var url = opts.url; 155 | 156 | return { 157 | send: function(_, completeCallback) { 158 | var name = 'jQuery_iframe_' + jQuery.now() 159 | , iframe, form 160 | 161 | iframe = $('