{"id":5646928,"date":"2022-11-28T14:28:12","date_gmt":"2022-11-28T19:28:12","guid":{"rendered":"https:\/\/lightning.ai\/pages\/?page_id=5646928"},"modified":"2022-11-28T14:28:12","modified_gmt":"2022-11-28T19:28:12","slug":"deep-learning-fundamentals","status":"publish","type":"page","link":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/","title":{"rendered":"Deep Learning Fundamentals"},"content":{"rendered":"","protected":false},"excerpt":{"rendered":"","protected":false},"author":16,"featured_media":0,"parent":5646342,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"pages\/page-flexible-blocks.php","meta":{"inline_featured_image":false,"footnotes":"","_links_to":"","_links_to_target":""},"acf":{"sections":[{"acf_fc_layout":"full_width","content":"<h1 class=\"mx-3\">Jump Start Your Deep Learning Journey<\/h1>\n","classnames":"heading","section_id":"","gradient_canvas":false,"color_mode":"Dark"},{"acf_fc_layout":"two_column","heading":"","left_content":"<h3>Want a university-quality deep learning course without the university cost or time commitment?<\/h3>\n<p>Learn for free from Lightning\u2019s Sebastian Raschka through concise, practical lessons built for busy students and professionals<\/p>\n<div class=\"profile-card d-flex mt-5\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" class=\"alignnone size-medium wp-image-5646932\" srcset=\"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-150x150@2x.jpg 300w, https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-150x150.jpg 150w, https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-125x125.jpg 125w, https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian.jpg 765w, https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-300x300@2x.jpg 600w, https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2022\/11\/sebastian-125x125@2x.jpg 250w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/p>\n<h5>Sebastian Raschka <span class=\"d-block\">Lead AI Educator, Lightning.AI<\/span><\/h5>\n<\/div>\n","right_content":"<div class=\"formwrap d-inline-block\"><canvas id='c' class=\"position-absolute\"><\/canvas><\/p>\n<h4 class=\"d-block font-weight-bold\">Join the waitlist today and be the first to know!<\/h4>\n\n<div class=\"wpcf7 no-js\" id=\"wpcf7-f5646930-o1\" lang=\"en-US\" dir=\"ltr\">\n<div class=\"screen-reader-response\"><p role=\"status\" aria-live=\"polite\" aria-atomic=\"true\"><\/p> <ul><\/ul><\/div>\n<form action=\"\/pages\/wp-json\/wp\/v2\/pages\/5646928#wpcf7-f5646930-o1\" method=\"post\" class=\"wpcf7-form init\" aria-label=\"Contact form\" novalidate=\"novalidate\" data-status=\"init\">\n<div style=\"display: none;\">\n<input type=\"hidden\" name=\"_wpcf7\" value=\"5646930\" \/>\n<input type=\"hidden\" name=\"_wpcf7_version\" value=\"5.8.7\" \/>\n<input type=\"hidden\" name=\"_wpcf7_locale\" value=\"en_US\" \/>\n<input type=\"hidden\" name=\"_wpcf7_unit_tag\" value=\"wpcf7-f5646930-o1\" \/>\n<input type=\"hidden\" name=\"_wpcf7_container_post\" value=\"0\" \/>\n<input type=\"hidden\" name=\"_wpcf7_posted_data_hash\" value=\"\" \/>\n<\/div>\n<div class=\"newsletter multiline\">\n\t<div class=\"row\">\n\t\t<div class=\"col-12 col-lg-6\">\n\t\t\t<p><label>First name<\/label>\n\t\t\t<\/p>\n\t\t\t<div class=\"input_wrap\">\n\t\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"firstname\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"firstname\" \/><\/span>\n\t\t\t\t<\/p>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t<div class=\"col-12 col-lg-6\">\n\t\t\t<p><label>Last name<\/label>\n\t\t\t<\/p>\n\t\t\t<div class=\"input_wrap\">\n\t\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"lastname\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-text wpcf7-validates-as-required\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"text\" name=\"lastname\" \/><\/span>\n\t\t\t\t<\/p>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t<div class=\"col-12 col-lg-12 mt-2\">\n\t\t\t<p><label>Email<\/label>\n\t\t\t<\/p>\n\t\t\t<div class=\"input_wrap\">\n\t\t\t\t<p><span class=\"wpcf7-form-control-wrap\" data-name=\"email\"><input size=\"40\" class=\"wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email\" aria-required=\"true\" aria-invalid=\"false\" value=\"\" type=\"email\" name=\"email\" \/><\/span>\n\t\t\t\t<\/p>\n\t\t\t<\/div>\n\t\t<\/div>\n\t\t<div class=\"col-12 d-flex justify-content-center mt-4\">\n\t\t\t<p><input class=\"wpcf7-form-control wpcf7-submit has-spinner\" type=\"submit\" value=\"Notify Me\" \/>\n\t\t\t<\/p>\n\t\t<\/div>\n\t<\/div>\n<\/div><div class=\"wpcf7-response-output\" aria-hidden=\"true\"><\/div>\n<\/form>\n<\/div>\n<\/div>\n","classnames":"hero","section_id":"","column_widths":""},{"acf_fc_layout":"raw_html","content":"<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@500;800&display=swap\" rel=\"stylesheet\">","classnames":"position-absolute d-none","section_id":""}],"custom_styles":".heading .container{\r\n\tpadding:75px 0 0;\r\n}\r\n\r\n.wpcf7 form.sent .wpcf7-response-output {\r\n    border: none;\r\n    background: rgba(255,255,255,0.5);\r\n    font-weight: 900;\r\n    text-align: center;\r\n    padding: 0.5rem;\r\n    border-left: 5px solid var(--blue);\r\n    max-width: calc(100% - 2.25rem);\r\n}\r\n\r\nspan.wpcf7-not-valid-tip {\r\n    background: rgba(255,255,255,0.5);\r\n    padding: 0 0.5rem;\r\n    border-radius: 5px;\r\n    font-weight: 900;\r\n    margin-top: 0.25rem;\r\n}\r\n\r\n.wpcf7 form.invalid .wpcf7-response-output {\r\n    background: #ffb900;\r\n    margin: 1rem 0;\r\n    box-sizing: border-box;\r\n    font-weight: 900;\r\n    max-width: calc(100% - 1.75rem);\r\n}\r\n\r\n.newsletter.multiline input{\r\n    box-shadow:none;\r\n    border:none;\r\n    height:35px;\r\n    box-sizing:border-box;\r\n    border-radius:5px;\r\n    width:100%;\r\n  padding-left:1rem;\r\n  padding-right:1rem;\r\n}\r\n\r\n.newsletter.multiline label{\r\n    color:#fff;\r\n    font-weight:900;\r\n}\r\n\r\n.input_wrap, .input_wrap span {\r\n    width:100%;\r\n    min-width:100%;\r\n}\r\n\r\n\r\nspan.wpcf7-spinner {}\r\n\r\ninput.wpcf7-form-control.has-spinner.wpcf7-submit {\r\n    margin-top:1rem;\r\n    background:var(--purple);\r\n    box-shadow:inset 0 0 0 40px rgba(0,0,0,0.15), 0 5px 10px -2.5px rgba(0,0,0,0.5);\r\n    color:#fff;\r\n    font-weight:900;\r\n    height:40px;\r\n    cursor:pointer;\r\n    transition:0.2s ease-in-out;\r\n}\r\n\r\ninput.wpcf7-form-control.has-spinner.wpcf7-submit:hover{\r\n    background:var(--blue-500);\r\n}\r\n\r\n.newsletter.multiline .col-12.col-lg-12.mt-2 {\r\n    padding-top:1rem;\r\n}\r\n\r\n    .profile-card.d-flex.mt-5 {\r\n    margin-bottom:1rem;\r\n    }\r\n\r\n@media (min-width:992px){\r\n    .profile-card.d-flex.mt-5 {\r\n    border-top: 1px solid rgba(0,0,0,0.125);\r\n    padding-top:2rem;\r\n        margin-bottom:0;\r\n    }\r\n}\r\n\r\n@media (max-width:992px){\r\n    .formwrap.d-inline-block {\r\n    margin-top: 3rem;\r\n}\r\n}\r\n\r\n.hero .container{\r\npadding:2rem 1rem 4rem;\r\n  border-radius:5px;\r\n  background:rgba(255,255,255,0.25);\r\n  margin-bottom:75px;\r\n  box-shadow:0 20px 40px -20px rgba(0,0,0,0.25);\r\n}\r\n\r\nhtml.no-js{\r\nmargin-top: 0px !important;\r\n}\r\n\r\nlabel.d-none {\r\n    display: block !important;\r\n    color: #fff;\r\n    padding: 0 0.5rem;\r\n    font-size: 16px;\r\n}\r\n\r\ndiv#wpadminbar:not(:hover){\r\nopacity:0;\r\n}\r\n\r\n.single-line .wpcf7-submit {\r\n    font-weight: 900;\r\n    transition: 0.3s ease-in-out;\r\n}\r\n\r\n\r\n.hero .container {\r\n    display: flex;\r\n    flex-direction: row;\r\n    flex-wrap: wrap;\r\n}\r\n\r\n.hero .container img{\r\n    width:125px;\r\n  height:auto;\r\n  border-radius:100%;\r\n  box-shadow:0 20px 40px -20px rgba(0,0,0,0.95);\r\n}\r\n\r\n\r\nsection.raw.canvas {\r\n    position: absolute;\r\n    width: 100vw;\r\n    height: calc(100vh - 50px);\r\n    top: 0;\r\n    left: 0;\r\n    pointer-events: none;\r\n    z-index: -2;\r\n    overflow: hidden;\r\n}\r\n\r\nsection h1{\r\n    font-weight:900;\r\n  font-family: 'Plus Jakarta Sans', sans-serif;\r\n  margin:0 0 3rem;\r\n}\r\n\r\nsection.hero h3{\r\n    margin:0 0 2rem;\r\n}\r\n\r\nsection.hero h4{\r\n    margin: 2rem 0 1rem;\r\n}\r\n\r\n\r\ndiv#lightning-ai-footer {\r\n    background: #fff;\r\n    position:relative;\r\n    z-index:10;\r\n}\r\n\r\nbody{\r\n    background:radial-gradient(ellipse at bottom, #566ed3 -25%, #fff) 50% 50% \/ 150% 100% no-repeat;\r\n}\r\n\r\n.formwrap.d-inline-block {\r\n    padding: 0.5rem 1.5rem 5rem;\r\n    background: radial-gradient(ellipse at bottom, var(--blue-500) -75%, var(--purple));\r\n    border-radius:5px;\r\n    box-shadow:0 20px 40px -20px rgba(0,0,0,0.75);\r\n    margin:0.5rem 0 1.5rem;\r\n    width:clamp(300px, 100%, 600px);\r\n}\r\n\r\n.formwrap.d-inline-block h4{\r\n    color:#fff;\r\n    padding-bottom:1rem;\r\n}\r\n\r\n.formwrap.d-inline-block {\r\n    position:relative;\r\n    overflow:hidden;\r\n}\r\n\r\n.formwrap.d-inline-block canvas{\r\n    left:50%;\r\n    top:50%;\r\n    transform:translate(-50%, -50%);\r\n    width:200%;\r\n    left:50%;\r\n    height:100%;\r\n    width:clamp(1400px, 100vw, 3000px);\r\n      mix-blend-mode: lighten;\r\n  transform: translate(-50%, -35%) scale(2);\r\n    opacity: 0.75;\r\n  transition:0.6s ease-in-out;\r\n}\r\n\r\n.formwrap.d-inline-block:hover canvas{\r\n transform: translate(-50%, -37.5%) scale(3);\r\n    opacity: 0.85;\r\n}\r\n\r\n.formwrap.d-inline-block h4, .formwrap.d-inline-block div{\r\n    position:relative;\r\n    z-index:3;\r\n}\r\n\r\n@media (min-width:992px){\r\n    h1.mx-3 {\r\n    font-size: 60px;\r\n    font-weight: 900;\r\n    line-height: 72px;\r\n    }\r\n}\r\n\r\nsection.hero h3{\r\n    font-weight:900;\r\n}\r\n\r\nsection.hero h3 ~ p{\r\n    font-size:18px;\r\n}\r\n\r\nsection.hero img{\r\n    marign-top:1rem\r\n}\r\n\r\n\r\n.profile-card.d-flex {\r\n    justify-content:flex-start;\r\n    align-items:center;;\r\n}\r\n\r\n.profile-card.d-flex img{\r\n    margin-right:20px;\r\n}\r\n\r\n.profile-card.d-flex h5{\r\n    font-weight:900;\r\n}\r\n\r\n.profile-card.d-flex h5 span{\r\n    font-weight:200;\r\n  font-style:italic;\r\n  font-size:16px;\r\n}\r\n","custom_scripts":"\/*\r\n * A fast javascript implementation of simplex noise by Jonas Wagner\r\n *\r\n * Based on a speed-improved simplex noise algorithm for 2D, 3D and 4D in Java.\r\n * Which is based on example code by Stefan Gustavson (stegu@itn.liu.se).\r\n * With Optimisations by Peter Eastman (peastman@drizzle.stanford.edu).\r\n * Better rank ordering method by Stefan Gustavson in 2012.\r\n *\r\n *\r\n * Copyright (C) 2012 Jonas Wagner\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining\r\n * a copy of this software and associated documentation files (the\r\n * \"Software\"), to deal in the Software without restriction, including\r\n * without limitation the rights to use, copy, modify, merge, publish,\r\n * distribute, sublicense, and\/or sell copies of the Software, and to\r\n * permit persons to whom the Software is furnished to do so, subject to\r\n * the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be\r\n * included in all copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r\n * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r\n * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r\n * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n *\r\n *\/\r\n(function () {\r\n\"use strict\";\r\n\r\nvar F2 = 0.5 * (Math.sqrt(3.0) - 1.0),\r\n    G2 = (3.0 - Math.sqrt(3.0)) \/ 6.0,\r\n    F3 = 1.0 \/ 3.0,\r\n    G3 = 1.0 \/ 6.0,\r\n    F4 = (Math.sqrt(5.0) - 1.0) \/ 4.0,\r\n    G4 = (5.0 - Math.sqrt(5.0)) \/ 20.0;\r\n\r\n\r\nfunction SimplexNoise(random) {\r\n    if (!random) random = Math.random;\r\n    this.p = new Uint8Array(256);\r\n    this.perm = new Uint8Array(512);\r\n    this.permMod12 = new Uint8Array(512);\r\n    for (var i = 0; i < 256; i++) {\r\n        this.p[i] = random() * 256;\r\n    }\r\n    for (i = 0; i < 512; i++) {\r\n        this.perm[i] = this.p[i & 255];\r\n        this.permMod12[i] = this.perm[i] % 12;\r\n    }\r\n\r\n}\r\nSimplexNoise.prototype = {\r\n    grad3: new Float32Array([1, 1, 0,\r\n                            - 1, 1, 0,\r\n                            1, - 1, 0,\r\n\r\n                            - 1, - 1, 0,\r\n                            1, 0, 1,\r\n                            - 1, 0, 1,\r\n\r\n                            1, 0, - 1,\r\n                            - 1, 0, - 1,\r\n                            0, 1, 1,\r\n\r\n                            0, - 1, 1,\r\n                            0, 1, - 1,\r\n                            0, - 1, - 1]),\r\n    grad4: new Float32Array([0, 1, 1, 1, 0, 1, 1, - 1, 0, 1, - 1, 1, 0, 1, - 1, - 1,\r\n                            0, - 1, 1, 1, 0, - 1, 1, - 1, 0, - 1, - 1, 1, 0, - 1, - 1, - 1,\r\n                            1, 0, 1, 1, 1, 0, 1, - 1, 1, 0, - 1, 1, 1, 0, - 1, - 1,\r\n                            - 1, 0, 1, 1, - 1, 0, 1, - 1, - 1, 0, - 1, 1, - 1, 0, - 1, - 1,\r\n                            1, 1, 0, 1, 1, 1, 0, - 1, 1, - 1, 0, 1, 1, - 1, 0, - 1,\r\n                            - 1, 1, 0, 1, - 1, 1, 0, - 1, - 1, - 1, 0, 1, - 1, - 1, 0, - 1,\r\n                            1, 1, 1, 0, 1, 1, - 1, 0, 1, - 1, 1, 0, 1, - 1, - 1, 0,\r\n                            - 1, 1, 1, 0, - 1, 1, - 1, 0, - 1, - 1, 1, 0, - 1, - 1, - 1, 0]),\r\n    noise2D: function (xin, yin) {\r\n        var permMod12 = this.permMod12,\r\n            perm = this.perm,\r\n            grad3 = this.grad3;\r\n        var n0=0, n1=0, n2=0; \/\/ Noise contributions from the three corners\r\n        \/\/ Skew the input space to determine which simplex cell we're in\r\n        var s = (xin + yin) * F2; \/\/ Hairy factor for 2D\r\n        var i = Math.floor(xin + s);\r\n        var j = Math.floor(yin + s);\r\n        var t = (i + j) * G2;\r\n        var X0 = i - t; \/\/ Unskew the cell origin back to (x,y) space\r\n        var Y0 = j - t;\r\n        var x0 = xin - X0; \/\/ The x,y distances from the cell origin\r\n        var y0 = yin - Y0;\r\n        \/\/ For the 2D case, the simplex shape is an equilateral triangle.\r\n        \/\/ Determine which simplex we are in.\r\n        var i1, j1; \/\/ Offsets for second (middle) corner of simplex in (i,j) coords\r\n        if (x0 > y0) {\r\n            i1 = 1;\r\n            j1 = 0;\r\n        } \/\/ lower triangle, XY order: (0,0)->(1,0)->(1,1)\r\n        else {\r\n            i1 = 0;\r\n            j1 = 1;\r\n        } \/\/ upper triangle, YX order: (0,0)->(0,1)->(1,1)\r\n        \/\/ A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and\r\n        \/\/ a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where\r\n        \/\/ c = (3-sqrt(3))\/6\r\n        var x1 = x0 - i1 + G2; \/\/ Offsets for middle corner in (x,y) unskewed coords\r\n        var y1 = y0 - j1 + G2;\r\n        var x2 = x0 - 1.0 + 2.0 * G2; \/\/ Offsets for last corner in (x,y) unskewed coords\r\n        var y2 = y0 - 1.0 + 2.0 * G2;\r\n        \/\/ Work out the hashed gradient indices of the three simplex corners\r\n        var ii = i & 255;\r\n        var jj = j & 255;\r\n        \/\/ Calculate the contribution from the three corners\r\n        var t0 = 0.5 - x0 * x0 - y0 * y0;\r\n        if (t0 >= 0) {\r\n            var gi0 = permMod12[ii + perm[jj]] * 3;\r\n            t0 *= t0;\r\n            n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0); \/\/ (x,y) of grad3 used for 2D gradient\r\n        }\r\n        var t1 = 0.5 - x1 * x1 - y1 * y1;\r\n        if (t1 >= 0) {\r\n            var gi1 = permMod12[ii + i1 + perm[jj + j1]] * 3;\r\n            t1 *= t1;\r\n            n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1);\r\n        }\r\n        var t2 = 0.5 - x2 * x2 - y2 * y2;\r\n        if (t2 >= 0) {\r\n            var gi2 = permMod12[ii + 1 + perm[jj + 1]] * 3;\r\n            t2 *= t2;\r\n            n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2);\r\n        }\r\n        \/\/ Add contributions from each corner to get the final noise value.\r\n        \/\/ The result is scaled to return values in the interval [-1,1].\r\n        return 70.0 * (n0 + n1 + n2);\r\n    },\r\n    \/\/ 3D simplex noise\r\n    noise3D: function (xin, yin, zin) {\r\n        var permMod12 = this.permMod12,\r\n            perm = this.perm,\r\n            grad3 = this.grad3;\r\n        var n0, n1, n2, n3; \/\/ Noise contributions from the four corners\r\n        \/\/ Skew the input space to determine which simplex cell we're in\r\n        var s = (xin + yin + zin) * F3; \/\/ Very nice and simple skew factor for 3D\r\n        var i = Math.floor(xin + s);\r\n        var j = Math.floor(yin + s);\r\n        var k = Math.floor(zin + s);\r\n        var t = (i + j + k) * G3;\r\n        var X0 = i - t; \/\/ Unskew the cell origin back to (x,y,z) space\r\n        var Y0 = j - t;\r\n        var Z0 = k - t;\r\n        var x0 = xin - X0; \/\/ The x,y,z distances from the cell origin\r\n        var y0 = yin - Y0;\r\n        var z0 = zin - Z0;\r\n        \/\/ For the 3D case, the simplex shape is a slightly irregular tetrahedron.\r\n        \/\/ Determine which simplex we are in.\r\n        var i1, j1, k1; \/\/ Offsets for second corner of simplex in (i,j,k) coords\r\n        var i2, j2, k2; \/\/ Offsets for third corner of simplex in (i,j,k) coords\r\n        if (x0 >= y0) {\r\n            if (y0 >= z0) {\r\n                i1 = 1;\r\n                j1 = 0;\r\n                k1 = 0;\r\n                i2 = 1;\r\n                j2 = 1;\r\n                k2 = 0;\r\n            } \/\/ X Y Z order\r\n            else if (x0 >= z0) {\r\n                i1 = 1;\r\n                j1 = 0;\r\n                k1 = 0;\r\n                i2 = 1;\r\n                j2 = 0;\r\n                k2 = 1;\r\n            } \/\/ X Z Y order\r\n            else {\r\n                i1 = 0;\r\n                j1 = 0;\r\n                k1 = 1;\r\n                i2 = 1;\r\n                j2 = 0;\r\n                k2 = 1;\r\n            } \/\/ Z X Y order\r\n        }\r\n        else { \/\/ x0<y0\r\n            if (y0 < z0) {\r\n                i1 = 0;\r\n                j1 = 0;\r\n                k1 = 1;\r\n                i2 = 0;\r\n                j2 = 1;\r\n                k2 = 1;\r\n            } \/\/ Z Y X order\r\n            else if (x0 < z0) {\r\n                i1 = 0;\r\n                j1 = 1;\r\n                k1 = 0;\r\n                i2 = 0;\r\n                j2 = 1;\r\n                k2 = 1;\r\n            } \/\/ Y Z X order\r\n            else {\r\n                i1 = 0;\r\n                j1 = 1;\r\n                k1 = 0;\r\n                i2 = 1;\r\n                j2 = 1;\r\n                k2 = 0;\r\n            } \/\/ Y X Z order\r\n        }\r\n        \/\/ A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),\r\n        \/\/ a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and\r\n        \/\/ a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where\r\n        \/\/ c = 1\/6.\r\n        var x1 = x0 - i1 + G3; \/\/ Offsets for second corner in (x,y,z) coords\r\n        var y1 = y0 - j1 + G3;\r\n        var z1 = z0 - k1 + G3;\r\n        var x2 = x0 - i2 + 2.0 * G3; \/\/ Offsets for third corner in (x,y,z) coords\r\n        var y2 = y0 - j2 + 2.0 * G3;\r\n        var z2 = z0 - k2 + 2.0 * G3;\r\n        var x3 = x0 - 1.0 + 3.0 * G3; \/\/ Offsets for last corner in (x,y,z) coords\r\n        var y3 = y0 - 1.0 + 3.0 * G3;\r\n        var z3 = z0 - 1.0 + 3.0 * G3;\r\n        \/\/ Work out the hashed gradient indices of the four simplex corners\r\n        var ii = i & 255;\r\n        var jj = j & 255;\r\n        var kk = k & 255;\r\n        \/\/ Calculate the contribution from the four corners\r\n        var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;\r\n        if (t0 < 0) n0 = 0.0;\r\n        else {\r\n            var gi0 = permMod12[ii + perm[jj + perm[kk]]] * 3;\r\n            t0 *= t0;\r\n            n0 = t0 * t0 * (grad3[gi0] * x0 + grad3[gi0 + 1] * y0 + grad3[gi0 + 2] * z0);\r\n        }\r\n        var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;\r\n        if (t1 < 0) n1 = 0.0;\r\n        else {\r\n            var gi1 = permMod12[ii + i1 + perm[jj + j1 + perm[kk + k1]]] * 3;\r\n            t1 *= t1;\r\n            n1 = t1 * t1 * (grad3[gi1] * x1 + grad3[gi1 + 1] * y1 + grad3[gi1 + 2] * z1);\r\n        }\r\n        var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;\r\n        if (t2 < 0) n2 = 0.0;\r\n        else {\r\n            var gi2 = permMod12[ii + i2 + perm[jj + j2 + perm[kk + k2]]] * 3;\r\n            t2 *= t2;\r\n            n2 = t2 * t2 * (grad3[gi2] * x2 + grad3[gi2 + 1] * y2 + grad3[gi2 + 2] * z2);\r\n        }\r\n        var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;\r\n        if (t3 < 0) n3 = 0.0;\r\n        else {\r\n            var gi3 = permMod12[ii + 1 + perm[jj + 1 + perm[kk + 1]]] * 3;\r\n            t3 *= t3;\r\n            n3 = t3 * t3 * (grad3[gi3] * x3 + grad3[gi3 + 1] * y3 + grad3[gi3 + 2] * z3);\r\n        }\r\n        \/\/ Add contributions from each corner to get the final noise value.\r\n        \/\/ The result is scaled to stay just inside [-1,1]\r\n        return 32.0 * (n0 + n1 + n2 + n3);\r\n    },\r\n    \/\/ 4D simplex noise, better simplex rank ordering method 2012-03-09\r\n    noise4D: function (x, y, z, w) {\r\n        var permMod12 = this.permMod12,\r\n            perm = this.perm,\r\n            grad4 = this.grad4;\r\n\r\n        var n0, n1, n2, n3, n4; \/\/ Noise contributions from the five corners\r\n        \/\/ Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in\r\n        var s = (x + y + z + w) * F4; \/\/ Factor for 4D skewing\r\n        var i = Math.floor(x + s);\r\n        var j = Math.floor(y + s);\r\n        var k = Math.floor(z + s);\r\n        var l = Math.floor(w + s);\r\n        var t = (i + j + k + l) * G4; \/\/ Factor for 4D unskewing\r\n        var X0 = i - t; \/\/ Unskew the cell origin back to (x,y,z,w) space\r\n        var Y0 = j - t;\r\n        var Z0 = k - t;\r\n        var W0 = l - t;\r\n        var x0 = x - X0; \/\/ The x,y,z,w distances from the cell origin\r\n        var y0 = y - Y0;\r\n        var z0 = z - Z0;\r\n        var w0 = w - W0;\r\n        \/\/ For the 4D case, the simplex is a 4D shape I won't even try to describe.\r\n        \/\/ To find out which of the 24 possible simplices we're in, we need to\r\n        \/\/ determine the magnitude ordering of x0, y0, z0 and w0.\r\n        \/\/ Six pair-wise comparisons are performed between each possible pair\r\n        \/\/ of the four coordinates, and the results are used to rank the numbers.\r\n        var rankx = 0;\r\n        var ranky = 0;\r\n        var rankz = 0;\r\n        var rankw = 0;\r\n        if (x0 > y0) rankx++;\r\n        else ranky++;\r\n        if (x0 > z0) rankx++;\r\n        else rankz++;\r\n        if (x0 > w0) rankx++;\r\n        else rankw++;\r\n        if (y0 > z0) ranky++;\r\n        else rankz++;\r\n        if (y0 > w0) ranky++;\r\n        else rankw++;\r\n        if (z0 > w0) rankz++;\r\n        else rankw++;\r\n        var i1, j1, k1, l1; \/\/ The integer offsets for the second simplex corner\r\n        var i2, j2, k2, l2; \/\/ The integer offsets for the third simplex corner\r\n        var i3, j3, k3, l3; \/\/ The integer offsets for the fourth simplex corner\r\n        \/\/ simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.\r\n        \/\/ Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w\r\n        \/\/ impossible. Only the 24 indices which have non-zero entries make any sense.\r\n        \/\/ We use a thresholding to set the coordinates in turn from the largest magnitude.\r\n        \/\/ Rank 3 denotes the largest coordinate.\r\n        i1 = rankx >= 3 ? 1 : 0;\r\n        j1 = ranky >= 3 ? 1 : 0;\r\n        k1 = rankz >= 3 ? 1 : 0;\r\n        l1 = rankw >= 3 ? 1 : 0;\r\n        \/\/ Rank 2 denotes the second largest coordinate.\r\n        i2 = rankx >= 2 ? 1 : 0;\r\n        j2 = ranky >= 2 ? 1 : 0;\r\n        k2 = rankz >= 2 ? 1 : 0;\r\n        l2 = rankw >= 2 ? 1 : 0;\r\n        \/\/ Rank 1 denotes the second smallest coordinate.\r\n        i3 = rankx >= 1 ? 1 : 0;\r\n        j3 = ranky >= 1 ? 1 : 0;\r\n        k3 = rankz >= 1 ? 1 : 0;\r\n        l3 = rankw >= 1 ? 1 : 0;\r\n        \/\/ The fifth corner has all coordinate offsets = 1, so no need to compute that.\r\n        var x1 = x0 - i1 + G4; \/\/ Offsets for second corner in (x,y,z,w) coords\r\n        var y1 = y0 - j1 + G4;\r\n        var z1 = z0 - k1 + G4;\r\n        var w1 = w0 - l1 + G4;\r\n        var x2 = x0 - i2 + 2.0 * G4; \/\/ Offsets for third corner in (x,y,z,w) coords\r\n        var y2 = y0 - j2 + 2.0 * G4;\r\n        var z2 = z0 - k2 + 2.0 * G4;\r\n        var w2 = w0 - l2 + 2.0 * G4;\r\n        var x3 = x0 - i3 + 3.0 * G4; \/\/ Offsets for fourth corner in (x,y,z,w) coords\r\n        var y3 = y0 - j3 + 3.0 * G4;\r\n        var z3 = z0 - k3 + 3.0 * G4;\r\n        var w3 = w0 - l3 + 3.0 * G4;\r\n        var x4 = x0 - 1.0 + 4.0 * G4; \/\/ Offsets for last corner in (x,y,z,w) coords\r\n        var y4 = y0 - 1.0 + 4.0 * G4;\r\n        var z4 = z0 - 1.0 + 4.0 * G4;\r\n        var w4 = w0 - 1.0 + 4.0 * G4;\r\n        \/\/ Work out the hashed gradient indices of the five simplex corners\r\n        var ii = i & 255;\r\n        var jj = j & 255;\r\n        var kk = k & 255;\r\n        var ll = l & 255;\r\n        \/\/ Calculate the contribution from the five corners\r\n        var t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;\r\n        if (t0 < 0) n0 = 0.0;\r\n        else {\r\n            var gi0 = (perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32) * 4;\r\n            t0 *= t0;\r\n            n0 = t0 * t0 * (grad4[gi0] * x0 + grad4[gi0 + 1] * y0 + grad4[gi0 + 2] * z0 + grad4[gi0 + 3] * w0);\r\n        }\r\n        var t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;\r\n        if (t1 < 0) n1 = 0.0;\r\n        else {\r\n            var gi1 = (perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32) * 4;\r\n            t1 *= t1;\r\n            n1 = t1 * t1 * (grad4[gi1] * x1 + grad4[gi1 + 1] * y1 + grad4[gi1 + 2] * z1 + grad4[gi1 + 3] * w1);\r\n        }\r\n        var t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;\r\n        if (t2 < 0) n2 = 0.0;\r\n        else {\r\n            var gi2 = (perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32) * 4;\r\n            t2 *= t2;\r\n            n2 = t2 * t2 * (grad4[gi2] * x2 + grad4[gi2 + 1] * y2 + grad4[gi2 + 2] * z2 + grad4[gi2 + 3] * w2);\r\n        }\r\n        var t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;\r\n        if (t3 < 0) n3 = 0.0;\r\n        else {\r\n            var gi3 = (perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32) * 4;\r\n            t3 *= t3;\r\n            n3 = t3 * t3 * (grad4[gi3] * x3 + grad4[gi3 + 1] * y3 + grad4[gi3 + 2] * z3 + grad4[gi3 + 3] * w3);\r\n        }\r\n        var t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;\r\n        if (t4 < 0) n4 = 0.0;\r\n        else {\r\n            var gi4 = (perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32) * 4;\r\n            t4 *= t4;\r\n            n4 = t4 * t4 * (grad4[gi4] * x4 + grad4[gi4 + 1] * y4 + grad4[gi4 + 2] * z4 + grad4[gi4 + 3] * w4);\r\n        }\r\n        \/\/ Sum up and scale the result to cover the range [-1,1]\r\n        return 27.0 * (n0 + n1 + n2 + n3 + n4);\r\n    }\r\n\r\n\r\n};\r\n\r\nwindow.SimplexNoise = SimplexNoise;\r\n\r\n})();\r\n\r\n\r\n\/**\r\n * requestAnimationFrame\r\n *\/\r\nwindow.requestAnimationFrame = (function(){\r\n    return  window.requestAnimationFrame       ||\r\n            window.webkitRequestAnimationFrame ||\r\n            window.mozRequestAnimationFrame    ||\r\n            window.oRequestAnimationFrame      ||\r\n            window.msRequestAnimationFrame     ||\r\n            function (callback) {\r\n                window.setTimeout(callback, 1000 \/ 60);\r\n            };\r\n})();\r\n\r\n\r\n\/**\r\n * Vector\r\n *\/\r\nfunction Vector(x, y) {\r\n    this.x = x || 0;\r\n    this.y = y || 0;\r\n}\r\n\r\n\r\nVector.add = function(a, b) {\r\n    return new Vector(a.x + b.x, a.y + b.y);\r\n};\r\n\r\nVector.sub = function(a, b) {\r\n    return new Vector(a.x - b.x, a.y - b.y);\r\n};\r\n\r\nVector.prototype = {\r\n    set: function(x, y) {\r\n        if (typeof x === 'object') {\r\n            y = x.y;\r\n            x = x.x;\r\n        }\r\n        this.x = x || 0;\r\n        this.y = y || 0;\r\n        return this;\r\n    },\r\n\r\n    add: function(v) {\r\n        this.x += v.x;\r\n        this.y += v.y;\r\n        return this;\r\n    },\r\n\r\n    sub: function(v) {\r\n        this.x -= v.x;\r\n        this.y -= v.y;\r\n        return this;\r\n    },\r\n\r\n    scale: function(s) {\r\n        this.x *= s;\r\n        this.y *= s;\r\n        return this;\r\n    },\r\n\r\n    length: function() {\r\n        return Math.sqrt(this.x * this.x + this.y * this.y);\r\n    },\r\n\r\n    normalize: function() {\r\n        var len = Math.sqrt(this.x * this.x + this.y * this.y);\r\n        if (len) {\r\n            this.x \/= len;\r\n            this.y \/= len;\r\n        }\r\n        return this;\r\n    },\r\n\r\n    angle: function() {\r\n        return Math.atan2(this.y, this.x);\r\n    },\r\n\r\n    distanceTo: function(v) {\r\n        var dx = v.x - this.x,\r\n            dy = v.y - this.y;\r\n        return Math.sqrt(dx * dx + dy * dy);\r\n    },\r\n\r\n    distanceToSq: function(v) {\r\n        var dx = v.x - this.x,\r\n            dy = v.y - this.y;\r\n        return dx * dx + dy * dy;\r\n    },\r\n\r\n    clone: function() {\r\n        return new Vector(this.x, this.y);\r\n    }\r\n};\r\n\r\n\r\n\/**\r\n * Point\r\n *\/\r\nfunction Point(x, y, radius) {\r\n    Vector.call(this, x, y);\r\n\r\n    this.radius = radius || 7;\r\n\r\n    this.vec = new Vector(random(1, -1), random(1, -1)).normalize();\r\n    this._easeRadius    = this.radius;\r\n    this._currentRadius = this.radius;\r\n\r\n}\r\n\r\nPoint.prototype = (function(o) {\r\n    var s = new Vector(0, 0), p;\r\n    for (p in o) {\r\n        s[p] = o[p];\r\n    }\r\n    return s;\r\n})({\r\n    color:       'rgb(255, 255, 255)',\r\n    dragging:    false,\r\n    _latestDrag: null,\r\n\r\n    update: function(points, bounds) {\r\n        this._currentRadius = random(this._easeRadius, this._easeRadius * 0.35);\r\n        this._easeRadius += (this.radius - this._easeRadius) * 0.1;\r\n\r\n        if (this.dragging) return;\r\n\r\n        var vec = this.vec,\r\n            i, len, p, d;\r\n\r\n        for (i = 0, len = points.length; i < len; i++) {\r\n            p = points[i];\r\n            if (p !== this) {\r\n                d = this.distanceToSq(p);\r\n                if (d < 90000) {\r\n                    vec.add(Vector.sub(this, p).normalize().scale(0.03));\r\n                } else if (d > 250000) {\r\n                    vec.add(Vector.sub(p, this).normalize().scale(0.015));\r\n                }\r\n            }\r\n        }\r\n\r\n        if (vec.length() > 3) vec.normalize().scale(3);\r\n\r\n        this.add(vec);\r\n\r\n        if (this.x < bounds.x) {\r\n            this.x = bounds.x;\r\n            if (vec.x < 0) vec.x *= -1;\r\n\r\n        } else if (this.x > bounds.right) {\r\n            this.x = bounds.right;\r\n            if (vec.x > 0) vec.x *= -1;\r\n        }\r\n\r\n        if (this.y < bounds.y) {\r\n            this.y = bounds.y;\r\n            if (vec.y < 0) vec.y *= -1;\r\n\r\n        } else if (this.y > bounds.bottom) {\r\n            this.y = bounds.bottom;\r\n            if (vec.y > 0) vec.y *= -1;\r\n        }\r\n    },\r\n\r\n    hitTest: function(p) {\r\n        if (this.distanceToSq(p) < 900) {\r\n            this._easeRadius = this.radius * 2.5;\r\n            return true;\r\n        }\r\n        return false;\r\n    },\r\n\r\n    startDrag: function() {\r\n        this.dragging = true;\r\n        this.vec.set(0, 0);\r\n        this._latestDrag = new Vector().set(this);\r\n    },\r\n\r\n    drag: function(p) {\r\n        this._latestDrag.set(this);\r\n        this.set(p);\r\n    },\r\n\r\n    endDrag: function() {\r\n        this.vec = Vector.sub(this, this._latestDrag);\r\n        this.dragging = false;\r\n    },\r\n\r\n    draw: function(ctx) {\r\n        ctx.save();\r\n        ctx.fillStyle = this.color;\r\n        ctx.beginPath();\r\n        ctx.arc(this.x, this.y, this._currentRadius, 0, Math.PI * 2, false);\r\n        ctx.fill();\r\n        ctx.shadowBlur  = 20;\r\n        ctx.shadowColor = this.color;\r\n        ctx.fillStyle   = 'rgba(0, 0, 0, 1)';\r\n        ctx.globalCompositeOperation = 'lighter';\r\n        ctx.beginPath();\r\n        ctx.arc(this.x, this.y, this._currentRadius, 0, Math.PI * 2, false);\r\n        ctx.fill();\r\n        ctx.restore();\r\n    }\r\n});\r\n\r\n\r\n\/**\r\n * Lightning\r\n *\/\r\nfunction Lightning(startPoint, endPoint, step) {\r\n    this.startPoint = startPoint || new Vector();\r\n    this.endPoint   = endPoint || new Vector();\r\n    this.step       = step || 45;\r\n\r\n    this.children = [];\r\n}\r\n\r\nLightning.prototype = {\r\n    color:         'rgba(255, 255, 255, 0.75)',\r\n    speed:         0.006,\r\n    amplitude:     0.35,\r\n    lineWidth:     3,\r\n    blur :         75,\r\n    blurColor:     'rgba(255, 255, 255, 0.25)',\r\n    points:        3,\r\n    off:           0,\r\n    _simplexNoise: new SimplexNoise(),\r\n    \/\/ Case by child\r\n    parent:        null,\r\n    startStep:     0,\r\n    endStep:       0,\r\n\r\n    length: function() {\r\n        return this.startPoint.distanceTo(this.endPoint);\r\n    },\r\n\r\n    getChildNum: function() {\r\n        return children.length;\r\n    },\r\n\r\n    setChildNum: function(num) {\r\n        var children = this.children, child,\r\n            i, len;\r\n\r\n        len = this.children.length;\r\n\r\n        if (len > num) {\r\n            for (i = num; i < len; i++) {\r\n                children[i].dispose();\r\n            }\r\n            children.splice(num, len - num);\r\n\r\n        } else {\r\n            for (i = len; i < num; i++) {\r\n                child = new Lightning();\r\n                child._setAsChild(this);\r\n                children.push(child);\r\n            }\r\n        }\r\n    },\r\n\r\n    update: function() {\r\n        var startPoint = this.startPoint,\r\n            endPoint   = this.endPoint,\r\n            \r\n            length, normal, radian, sinv, cosv,\r\n            points, off, waveWidth, n, av, ax, ay, bv, bx, by, m, x, y,\r\n            children, child,\r\n            i, len;\r\n\r\n        if (this.parent) {\r\n            if (this.endStep > this.parent.step) {\r\n                this._updateStepsByParent();\r\n            }\r\n\r\n            startPoint.set(this.parent.points[this.startStep]);\r\n            endPoint.set(this.parent.points[this.endStep]);\r\n        }\r\n\r\n        length = this.length();\r\n        normal = Vector.sub(endPoint, startPoint).normalize().scale(length \/ this.step);\r\n        radian = normal.angle();\r\n        sinv   = Math.sin(radian);\r\n        cosv   = Math.cos(radian);\r\n\r\n        points    = this.points = [];\r\n        off       = this.off += random(this.speed, this.speed * 0.2);\r\n        waveWidth = (this.parent ? length * 1.5 : length) * this.amplitude;\r\n        if (waveWidth > 750) waveWidth = 750;\r\n\r\n        for (i = 0, len = this.step + 1; i < len; i++) {\r\n            n = i \/ 60;\r\n            av = waveWidth * this._noise(n - off, 0) * 0.5;\r\n            ax = sinv * av;\r\n            ay = cosv * av;\r\n\r\n            bv = waveWidth * this._noise(n + off, 0) * 0.5;\r\n            bx = sinv * bv;\r\n            by = cosv * bv;\r\n\r\n            m = Math.sin((Math.PI * (i \/ (len - 1))));\r\n\r\n            x = startPoint.x + normal.x * i + (ax - bx) * m;\r\n            y = startPoint.y + normal.y * i - (ay - by) * m;\r\n\r\n            points.push(new Vector(x, y));\r\n        }\r\n\r\n        children = this.children;\r\n\r\n        for (i = 0, len = children.length; i < len; i++) {\r\n            child = children[i];\r\n            child.color     = this.color;\r\n            child.speed     = this.speed * 1.35;\r\n            child.amplitude = this.amplitude;\r\n            child.lineWidth = this.lineWidth * 0.75;\r\n            child.blur      = this.blur;\r\n            child.blurColor = this.blurColor;\r\n            children[i].update();\r\n        }\r\n    },\r\n\r\n    draw: function(ctx) {\r\n        var points = this.points,\r\n            children = this.children,\r\n            i, len, p, d;\r\n\r\n        \/\/ Blur\r\n        if (this.blur) {\r\n            ctx.save();\r\n            ctx.globalCompositeOperation = 'lighter';\r\n            ctx.fillStyle   = 'rgba(0, 0, 0, 1)';\r\n            ctx.shadowBlur  = this.blur;\r\n            ctx.shadowColor = this.blurColor;\r\n            ctx.beginPath();\r\n            for (i = 0, len = points.length; i < len; i++) {\r\n                p = points[i];\r\n                d = len > 1 ? p.distanceTo(points[i === len - 1 ? i - 1 : i + 1]) : 0;\r\n                ctx.moveTo(p.x + d, p.y);\r\n                ctx.arc(p.x, p.y, d, 0, Math.PI * 2, false);\r\n            }\r\n            ctx.fill();\r\n            ctx.restore();\r\n        }\r\n\r\n        ctx.save();\r\n        ctx.lineWidth = random(this.lineWidth, 0.5);\r\n        ctx.strokeStyle = this.color;\r\n        ctx.beginPath();\r\n        for (i = 0, len = points.length; i < len; i++) {\r\n            p = points[i];\r\n            ctx[i === 0 ? 'moveTo' : 'lineTo'](p.x, p.y);\r\n        }\r\n        ctx.stroke();\r\n        ctx.restore();\r\n\r\n        \/\/ Draw children\r\n        for (i = 0, len = this.children.length; i < len; i++) {\r\n            children[i].draw(ctx);\r\n        }\r\n    },\r\n\r\n    dispose: function() {\r\n        if (this._timeoutId) {\r\n            clearTimeout(this._timeoutId);\r\n        }\r\n        this._simplexNoise = null;\r\n    },\r\n\r\n    _noise: function(v) {\r\n        var octaves = 6,\r\n            fallout = 0.5,\r\n            amp = 1, f = 1, sum = 0,\r\n            i;\r\n\r\n        for (i = 0; i < octaves; ++i) {\r\n            amp *= fallout;\r\n            sum += amp * (this._simplexNoise.noise2D(v * f, 0) + 1) * 0.5;\r\n            f *= 2;\r\n        }\r\n\r\n        return sum;\r\n    },\r\n\r\n    _setAsChild: function(lightning) {\r\n        if (!(lightning instanceof Lightning)) return;\r\n        this.parent = lightning;\r\n\r\n        var self = this,\r\n            setTimer = function() {\r\n                self._updateStepsByParent();\r\n                self._timeoutId = setTimeout(setTimer, randint(1500));\r\n            };\r\n\r\n        self._timeoutId = setTimeout(setTimer, randint(1500));\r\n    },\r\n\r\n    _updateStepsByParent: function() {\r\n        if (!this.parent) return;\r\n        var parentStep = this.parent.step;\r\n        this.startStep = randint(parentStep - 2);\r\n        this.endStep   = this.startStep + randint(parentStep - this.startStep - 2) + 2;\r\n        this.step = this.endStep - this.startStep;\r\n    }\r\n};\r\n\r\n\r\n\/**\r\n * Rect\r\n *\/\r\nfunction Rect(x, y, width, height) {\r\n    this.x = x || 0;\r\n    this.y = y || 0;\r\n    this.width  = width || 0;\r\n    this.height = height || 0;\r\n    this.right  = this.x + this.width;\r\n    this.bottom = this.y + this.height;\r\n}\r\n\r\n\r\n\/\/ Helpers\r\n\r\nfunction random(max, min) {\r\n    if (typeof max !== 'number') {\r\n        return Math.random();\r\n    } else if (typeof min !== 'number') {\r\n        min = 0;\r\n    }\r\n    return Math.random() * (max - min) + min;\r\n}\r\n\r\n\r\nfunction randint(max, min) {\r\n    if (!max) return 0;\r\n    return random(max + 1, min) | 0;\r\n}\r\n\r\n\r\n\r\n\/\/ Initialize\r\n\r\n(function() {\r\n\r\n    \/\/ Vars\r\n\r\n    var canvas, context,\r\n        centerX, centerY, grad,\r\n        mouse,\r\n        bounds,\r\n        points,\r\n        lightning,\r\n        gui, control;\r\n\r\n\r\n    \/\/ Event Listeners\r\n\r\n    function resize() {\r\n        canvas.width  = 1400;\r\n        canvas.height = window.innerHeight;\r\n        centerX = canvas.width * 0.5;\r\n        centerY = canvas.height * 0.5;\r\n        context = canvas.getContext('2d');\r\n        grad = context.createRadialGradient(centerX, centerY, 0, centerX, centerY, Math.sqrt(centerX * centerX + centerY * centerY));\r\n        grad.addColorStop(0, 'rgba(0, 0, 0, 0)');\r\n        grad.addColorStop(1, 'rgba(0, 0, 0, 0.4)');\r\n    }\r\n\r\n    function mouseMove(e) {\r\n        mouse.set(e.clientX, e.clientY);\r\n\r\n        var i, hit = false;\r\n        for (i = 0; i < 2; i++) {\r\n            if ((!hit && points[i].hitTest(mouse)) || points[i].dragging)\r\n                hit = true;\r\n        }\r\n        document.body.style.cursor = hit ? 'pointer' : 'default';\r\n    }\r\n\r\n    function mouseDown(e) {\r\n        for (var i = 0; i < 2; i++) {\r\n            if (points[i].hitTest(mouse)) {\r\n                points[i].startDrag();\r\n                return;\r\n            }\r\n        }\r\n    }\r\n\r\n    function mouseUp(e) {\r\n        for (var i = 0; i < 2; i++) {\r\n            if (points[i].dragging)\r\n                points[i].endDrag();\r\n        }\r\n    }\r\n\r\n\r\n    \/\/ GUI Control\r\n\r\n    control = {\r\n        childNum: 10,\r\n        color: [255, 255, 255],\r\n        backgroundColor: '#566ed3'\r\n    };\r\n\r\n\r\n    \/\/ Init\r\n\r\n    canvas = document.getElementById('c');\r\n\r\n    window.addEventListener('resize', resize, false);\r\n    resize(null);\r\n\r\n    bounds = new Rect(0, 0, canvas.width, canvas.height);\r\n    mouse  = new Vector();\r\n\r\n    lightning = new Lightning();\r\n\r\n    points = [\r\n        new Point(centerX - (1400\/2) - 20, centerY, lightning.lineWidth * 1.25),\r\n        new Point(centerX + (1400\/2) + 20, centerY, lightning.lineWidth * 1.25)\r\n    ];\r\n\r\n    lightning.startPoint.set(points[0]);\r\n    lightning.endPoint.set(points[1]);\r\n    lightning.setChildNum(6);\r\n\r\n    canvas.addEventListener('mousemove', mouseMove, false);\r\n    canvas.addEventListener('mousedown', mouseDown, false);\r\n    canvas.addEventListener('mouseup', mouseUp, false);\r\n\r\n\r\n    \/\/ Start Update\r\n\r\n    var loop = function() {\r\n        context.save();\r\n        context.fillStyle = control.backgroundColor;\r\n        context.fillRect(0, 0, canvas.width, canvas.height);\r\n        context.fillStyle = grad;\r\n        context.fillRect(0, 0, canvas.width, canvas.height);\r\n        context.restore();\r\n\r\n        lightning.startPoint.set(points[0]);\r\n        lightning.endPoint.set(points[1]);\r\n        lightning.step = Math.ceil(lightning.length() \/ 10);\r\n        if (lightning.step < 5) lightning.step = 5;\r\n\r\n        lightning.update();\r\n        lightning.draw(context);\r\n\r\n        var i, p;\r\n\r\n        for (i = 0; i < 2; i++) {\r\n            p = points[i];\r\n            if (p.dragging) p.drag(mouse);\r\n            p.draw(context);\r\n        }\r\n\r\n        requestAnimationFrame(loop);\r\n    };\r\n    loop();\r\n\r\n})();\r\n"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Deep Learning Fundamentals - Lightning AI<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Deep Learning Fundamentals - Lightning AI\" \/>\n<meta property=\"og:url\" content=\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/\" \/>\n<meta property=\"og:site_name\" content=\"Lightning AI\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@LightningAI\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/\",\"url\":\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/\",\"name\":\"Deep Learning Fundamentals - Lightning AI\",\"isPartOf\":{\"@id\":\"https:\/\/lightning.ai\/pages\/#website\"},\"datePublished\":\"2022-11-28T19:28:12+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/lightning.ai\/pages\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AI Education\",\"item\":\"https:\/\/lightning.ai\/pages\/ai-education\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Deep Learning Fundamentals\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/lightning.ai\/pages\/#website\",\"url\":\"https:\/\/lightning.ai\/pages\/\",\"name\":\"Lightning AI\",\"description\":\"The platform for teams to build AI.\",\"publisher\":{\"@id\":\"https:\/\/lightning.ai\/pages\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/lightning.ai\/pages\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/lightning.ai\/pages\/#organization\",\"name\":\"Lightning AI\",\"url\":\"https:\/\/lightning.ai\/pages\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/lightning.ai\/pages\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2023\/02\/image-17.png\",\"contentUrl\":\"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2023\/02\/image-17.png\",\"width\":1744,\"height\":856,\"caption\":\"Lightning AI\"},\"image\":{\"@id\":\"https:\/\/lightning.ai\/pages\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/LightningAI\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Deep Learning Fundamentals - Lightning AI","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/","og_locale":"en_US","og_type":"article","og_title":"Deep Learning Fundamentals - Lightning AI","og_url":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/","og_site_name":"Lightning AI","twitter_card":"summary_large_image","twitter_site":"@LightningAI","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/","url":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/","name":"Deep Learning Fundamentals - Lightning AI","isPartOf":{"@id":"https:\/\/lightning.ai\/pages\/#website"},"datePublished":"2022-11-28T19:28:12+00:00","breadcrumb":{"@id":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/lightning.ai\/pages\/ai-education\/deep-learning-fundamentals\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/lightning.ai\/pages\/"},{"@type":"ListItem","position":2,"name":"AI Education","item":"https:\/\/lightning.ai\/pages\/ai-education\/"},{"@type":"ListItem","position":3,"name":"Deep Learning Fundamentals"}]},{"@type":"WebSite","@id":"https:\/\/lightning.ai\/pages\/#website","url":"https:\/\/lightning.ai\/pages\/","name":"Lightning AI","description":"The platform for teams to build AI.","publisher":{"@id":"https:\/\/lightning.ai\/pages\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/lightning.ai\/pages\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/lightning.ai\/pages\/#organization","name":"Lightning AI","url":"https:\/\/lightning.ai\/pages\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/lightning.ai\/pages\/#\/schema\/logo\/image\/","url":"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2023\/02\/image-17.png","contentUrl":"https:\/\/lightningaidev.wpengine.com\/wp-content\/uploads\/2023\/02\/image-17.png","width":1744,"height":856,"caption":"Lightning AI"},"image":{"@id":"https:\/\/lightning.ai\/pages\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/LightningAI"]}]}},"_links":{"self":[{"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/pages\/5646928"}],"collection":[{"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/comments?post=5646928"}],"version-history":[{"count":0,"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/pages\/5646928\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/pages\/5646342"}],"wp:attachment":[{"href":"https:\/\/lightning.ai\/pages\/wp-json\/wp\/v2\/media?parent=5646928"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}