Skip to content

Instantly share code, notes, and snippets.

@llaine
Created February 8, 2015 16:46
Show Gist options
  • Save llaine/a7aa575d3e6682e4a415 to your computer and use it in GitHub Desktop.
Save llaine/a7aa575d3e6682e4a415 to your computer and use it in GitHub Desktop.
Drawing + canvas + easter egg
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
</body>
<script src="konami.js"></script>
<script src="harmony.js"></script>
</html>
function Point(e, o) {
this.X = e, this.Y = o
}
function Rectangle(e, o, n, t) {
this.X = e, this.Y = o, this.Width = n, this.Height = t
}
function Template(e, o) {
this.Name = e, this.Points = Resample(o, NumPoints);
var n = IndicativeAngle(this.Points);
this.Points = RotateBy(this.Points, -n), this.Points = ScaleTo(this.Points, SquareSize), this.Points = TranslateTo(this.Points, Origin)
}
function Result(e, o) {
this.Name = e, this.Score = o
}
function DollarRecognizer() {
this.Templates = new Array, this.Templates[0] = new Template("star", new Array(new Point(75, 250), new Point(75, 247), new Point(77, 244), new Point(78, 242), new Point(79, 239), new Point(80, 237), new Point(82, 234), new Point(82, 232), new Point(84, 229), new Point(85, 225), new Point(87, 222), new Point(88, 219), new Point(89, 216), new Point(91, 212), new Point(92, 208), new Point(94, 204), new Point(95, 201), new Point(96, 196), new Point(97, 194), new Point(98, 191), new Point(100, 185), new Point(102, 178), new Point(104, 173), new Point(104, 171), new Point(105, 164), new Point(106, 158), new Point(107, 156), new Point(107, 152), new Point(108, 145), new Point(109, 141), new Point(110, 139), new Point(112, 133), new Point(113, 131), new Point(116, 127), new Point(117, 125), new Point(119, 122), new Point(121, 121), new Point(123, 120), new Point(125, 122), new Point(125, 125), new Point(127, 130), new Point(128, 133), new Point(131, 143), new Point(136, 153), new Point(140, 163), new Point(144, 172), new Point(145, 175), new Point(151, 189), new Point(156, 201), new Point(161, 213), new Point(166, 225), new Point(169, 233), new Point(171, 236), new Point(174, 243), new Point(177, 247), new Point(178, 249), new Point(179, 251), new Point(180, 253), new Point(180, 255), new Point(179, 257), new Point(177, 257), new Point(174, 255), new Point(169, 250), new Point(164, 247), new Point(160, 245), new Point(149, 238), new Point(138, 230), new Point(127, 221), new Point(124, 220), new Point(112, 212), new Point(110, 210), new Point(96, 201), new Point(84, 195), new Point(74, 190), new Point(64, 182), new Point(55, 175), new Point(51, 172), new Point(49, 170), new Point(51, 169), new Point(56, 169), new Point(66, 169), new Point(78, 168), new Point(92, 166), new Point(107, 164), new Point(123, 161), new Point(140, 162), new Point(156, 162), new Point(171, 160), new Point(173, 160), new Point(186, 160), new Point(195, 160), new Point(198, 161), new Point(203, 163), new Point(208, 163), new Point(206, 164), new Point(200, 167), new Point(187, 172), new Point(174, 179), new Point(172, 181), new Point(153, 192), new Point(137, 201), new Point(123, 211), new Point(112, 220), new Point(99, 229), new Point(90, 237), new Point(80, 244), new Point(73, 250), new Point(69, 254), new Point(69, 252))), this.Recognize = function(e) {
e = Resample(e, NumPoints);
var o = IndicativeAngle(e);
e = RotateBy(e, -o), e = ScaleTo(e, SquareSize), e = TranslateTo(e, Origin);
for (var n = +1 / 0, t = 0, r = 0; r < this.Templates.length; r++) {
var i = DistanceAtBestAngle(e, this.Templates[r], -AngleRange, +AngleRange, AnglePrecision);
n > i && (n = i, t = r)
}
var s = 1 - n / HalfDiagonal;
return new Result(this.Templates[t].Name, s)
}, this.AddTemplate = function(e, o) {
this.Templates[this.Templates.length] = new Template(e, o);
for (var n = 0, t = 0; t < this.Templates.length; t++) this.Templates[t].Name == e && n++;
return n
}, this.DeleteUserTemplates = function() {
return this.Templates.length = NumTemplates, NumTemplates
}
}
function Resample(e, o) {
for (var n = PathLength(e) / (o - 1), t = 0, r = new Array(e[0]), i = 1; i < e.length; i++) {
var s = Distance(e[i - 1], e[i]);
if (t + s >= n) {
var a = e[i - 1].X + (n - t) / s * (e[i].X - e[i - 1].X),
u = e[i - 1].Y + (n - t) / s * (e[i].Y - e[i - 1].Y),
c = new Point(a, u);
r[r.length] = c, e.splice(i, 0, c), t = 0
} else t += s
}
return r.length == o - 1 && (r[r.length] = new Point(e[e.length - 1].X, e[e.length - 1].Y)), r
}
function IndicativeAngle(e) {
var o = Centroid(e);
return Math.atan2(o.Y - e[0].Y, o.X - e[0].X)
}
function RotateBy(e, o) {
for (var n = Centroid(e), t = Math.cos(o), r = Math.sin(o), i = new Array, s = 0; s < e.length; s++) {
var a = (e[s].X - n.X) * t - (e[s].Y - n.Y) * r + n.X,
u = (e[s].X - n.X) * r + (e[s].Y - n.Y) * t + n.Y;
i[i.length] = new Point(a, u)
}
return i
}
function ScaleTo(e, o) {
for (var n = BoundingBox(e), t = new Array, r = 0; r < e.length; r++) {
var i = e[r].X * (o / n.Width),
s = e[r].Y * (o / n.Height);
t[t.length] = new Point(i, s)
}
return t
}
function TranslateTo(e, o) {
for (var n = Centroid(e), t = new Array, r = 0; r < e.length; r++) {
var i = e[r].X + o.X - n.X,
s = e[r].Y + o.Y - n.Y;
t[t.length] = new Point(i, s)
}
return t
}
function DistanceAtBestAngle(e, o, n, t, r) {
for (var i = Phi * n + (1 - Phi) * t, s = DistanceAtAngle(e, o, i), a = (1 - Phi) * n + Phi * t, u = DistanceAtAngle(e, o, a); Math.abs(t - n) > r;) u > s ? (t = a, a = i, u = s, i = Phi * n + (1 - Phi) * t, s = DistanceAtAngle(e, o, i)) : (n = i, i = a, s = u, a = (1 - Phi) * n + Phi * t, u = DistanceAtAngle(e, o, a));
return Math.min(s, u)
}
function DistanceAtAngle(e, o, n) {
var t = RotateBy(e, n);
return PathDistance(t, o.Points)
}
function Centroid(e) {
for (var o = 0, n = 0, t = 0; t < e.length; t++) o += e[t].X, n += e[t].Y;
return o /= e.length, n /= e.length, new Point(o, n)
}
function BoundingBox(e) {
for (var o = +1 / 0, n = -1 / 0, t = +1 / 0, r = -1 / 0, i = 0; i < e.length; i++) e[i].X < o && (o = e[i].X), e[i].X > n && (n = e[i].X), e[i].Y < t && (t = e[i].Y), e[i].Y > r && (r = e[i].Y);
return new Rectangle(o, t, n - o, r - t)
}
function PathDistance(e, o) {
for (var n = 0, t = 0; t < e.length; t++) n += Distance(e[t], o[t]);
return n / e.length
}
function PathLength(e) {
for (var o = 0, n = 1; n < e.length; n++) o += Distance(e[n - 1], e[n]);
return o
}
function Distance(e, o) {
var n = o.X - e.X,
t = o.Y - e.Y;
return Math.sqrt(n * n + t * t)
}
function Deg2Rad(e) {
return e * Math.PI / 180
}
function Rad2Deg(e) {
return 180 * e / Math.PI
}
function starryEgg() {
if (!document.getElementById("erasure")) {
var e = document.createElement("div");
e.innerHTML = '<iframe width="384" height="313" src="http://www.youtube.com/v/E6x_-xKl-Fg&hl=en_US&fs=1&autoplay=1" frameborder="0" allowfullscreen></iframe>', document.body.appendChild(e), e.style.position = "fixed", e.style.bottom = "250px", e.style.left = "50%", e.style.marginLeft = "-190px"
}
}
window.requestAnimFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(e) {
window.setTimeout(e, 1e3 / 60)
}
}(),
function(window, document, undefined) {
function ribbon(e) {
this.init(e)
}
function bargs(e) {
var o, n = [];
for (o = 1; o < arguments.length; o++) n.push(arguments[o]);
return function() {
return e.apply(this, n)
}
}
function onWindowMouseMove(e) {
mouseX = e.clientX, mouseY = e.clientY
}
function onWindowResize() {
SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight, savecanvas = document.createElement("canvas"), savecanvas.width = canvas.width, savecanvas.height = canvas.height, savecanvas.getContext("2d").drawImage(canvas, 0, 0), canvas.width = SCREEN_WIDTH, canvas.height = SCREEN_HEIGHT, context.drawImage(savecanvas, 0, 0), brush = new ribbon(context)
}
function onDocumentMouseDown(e) {
isMenuMouseOver || e.preventDefault()
}
function onDocumentKeyDown(e) {
if (!shiftKeyIsDown) switch (e.keyCode) {
case 18:
altKeyIsDown = !0
}
}
function onDocumentKeyUp(e) {
switch (e.keyCode) {
case 16:
shiftKeyIsDown = !1, foregroundColorSelector.container.style.visibility = "hidden";
break;
case 18:
altKeyIsDown = !1
}
}
function setForegroundColor(e, o) {
foregroundColorSelector.update(e, o), COLOR = foregroundColorSelector.getColor(), menu.setForegroundColor(COLOR)
}
function onForegroundColorSelectorMouseDown(e) {
window.addEventListener("mousemove", onForegroundColorSelectorMouseMove, !1), window.addEventListener("mouseup", onForegroundColorSelectorMouseUp, !1), setForegroundColor(e.clientX - foregroundColorSelector.container.offsetLeft, e.clientY - foregroundColorSelector.container.offsetTop)
}
function onForegroundColorSelectorMouseMove(e) {
setForegroundColor(e.clientX - foregroundColorSelector.container.offsetLeft, e.clientY - foregroundColorSelector.container.offsetTop)
}
function onForegroundColorSelectorMouseUp(e) {
window.removeEventListener("mousemove", onForegroundColorSelectorMouseMove, !1), window.removeEventListener("mouseup", onForegroundColorSelectorMouseUp, !1), setForegroundColor(e.clientX - foregroundColorSelector.container.offsetLeft, e.clientY - foregroundColorSelector.container.offsetTop)
}
function onForegroundColorSelectorTouchStart(e) {
1 == e.touches.length && (e.preventDefault(), setForegroundColor(e.touches[0].pageX - foregroundColorSelector.container.offsetLeft, e.touches[0].pageY - foregroundColorSelector.container.offsetTop), window.addEventListener("touchmove", onForegroundColorSelectorTouchMove, !1), window.addEventListener("touchend", onForegroundColorSelectorTouchEnd, !1))
}
function onForegroundColorSelectorTouchMove(e) {
1 == e.touches.length && (e.preventDefault(), setForegroundColor(e.touches[0].pageX - foregroundColorSelector.container.offsetLeft, e.touches[0].pageY - foregroundColorSelector.container.offsetTop))
}
function onForegroundColorSelectorTouchEnd(e) {
0 == e.touches.length && (e.preventDefault(), window.removeEventListener("touchmove", onForegroundColorSelectorTouchMove, !1), window.removeEventListener("touchend", onForegroundColorSelectorTouchEnd, !1))
}
function setBackgroundColor(e, o) {
backgroundColorSelector.update(e, o), BACKGROUND_COLOR = backgroundColorSelector.getColor(), menu.setBackgroundColor(BACKGROUND_COLOR), document.body.style.backgroundColor = "rgb(" + BACKGROUND_COLOR[0] + ", " + BACKGROUND_COLOR[1] + ", " + BACKGROUND_COLOR[2] + ")"
}
function onBackgroundColorSelectorMouseDown() {
window.addEventListener("mousemove", onBackgroundColorSelectorMouseMove, !1), window.addEventListener("mouseup", onBackgroundColorSelectorMouseUp, !1)
}
function onBackgroundColorSelectorMouseMove(e) {
setBackgroundColor(e.clientX - backgroundColorSelector.container.offsetLeft, e.clientY - backgroundColorSelector.container.offsetTop)
}
function onBackgroundColorSelectorMouseUp(e) {
window.removeEventListener("mousemove", onBackgroundColorSelectorMouseMove, !1), window.removeEventListener("mouseup", onBackgroundColorSelectorMouseUp, !1), setBackgroundColor(e.clientX - backgroundColorSelector.container.offsetLeft, e.clientY - backgroundColorSelector.container.offsetTop)
}
function onBackgroundColorSelectorTouchStart(e) {
1 == e.touches.length && (e.preventDefault(), setBackgroundColor(e.touches[0].pageX - backgroundColorSelector.container.offsetLeft, e.touches[0].pageY - backgroundColorSelector.container.offsetTop), window.addEventListener("touchmove", onBackgroundColorSelectorTouchMove, !1), window.addEventListener("touchend", onBackgroundColorSelectorTouchEnd, !1))
}
function onBackgroundColorSelectorTouchMove(e) {
1 == e.touches.length && (e.preventDefault(), setBackgroundColor(e.touches[0].pageX - backgroundColorSelector.container.offsetLeft, e.touches[0].pageY - backgroundColorSelector.container.offsetTop))
}
function onBackgroundColorSelectorTouchEnd(e) {
0 == e.touches.length && (e.preventDefault(), window.removeEventListener("touchmove", onBackgroundColorSelectorTouchMove, !1), window.removeEventListener("touchend", onBackgroundColorSelectorTouchEnd, !1))
}
function onMenuForegroundColor() {
cleanPopUps(), foregroundColorSelector.show(), foregroundColorSelector.container.style.left = (SCREEN_WIDTH - foregroundColorSelector.container.offsetWidth) / 2 + "px", foregroundColorSelector.container.style.top = (SCREEN_HEIGHT - foregroundColorSelector.container.offsetHeight) / 2 + "px", isForegroundColorSelectorVisible = !0
}
function onMenuBackgroundColor() {
cleanPopUps(), backgroundColorSelector.show(), backgroundColorSelector.container.style.left = (SCREEN_WIDTH - backgroundColorSelector.container.offsetWidth) / 2 + "px", backgroundColorSelector.container.style.top = (SCREEN_HEIGHT - backgroundColorSelector.container.offsetHeight) / 2 + "px", isBackgroundColorSelectorVisible = !0
}
function onMenuSelectorChange() {
"" != BRUSHES[menu.selector.selectedIndex] && (brush.destroy(), brush = eval("new " + BRUSHES[menu.selector.selectedIndex] + "(context)"), window.location.hash = BRUSHES[menu.selector.selectedIndex])
}
function onMenuMouseOver() {
isMenuMouseOver = !0
}
function onMenuMouseOut() {
isMenuMouseOver = !1
}
function onMenuSave() {
var e = flattenCanvas.getContext("2d");
e.fillStyle = "rgb(" + BACKGROUND_COLOR[0] + ", " + BACKGROUND_COLOR[1] + ", " + BACKGROUND_COLOR[2] + ")", e.fillRect(0, 0, canvas.width, canvas.height), e.drawImage(canvas, 0, 0), window.open(flattenCanvas.toDataURL("image/png"), "mywindow")
}
function onMenuClear() {
context.clearRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), brush.destroy(), brush = eval("new " + BRUSHES[menu.selector.selectedIndex] + "(context)")
}
function onMenuAbout() {
cleanPopUps(), isAboutVisible = !0, about.show()
}
function onCanvasMouseMove(e) {
if (!brush.isStroking) return brush.strokeStart(e.clientX, e.clientY), brush.isStroking = !0, void(window.DollarRecognizer && (window.Rcgnzr = new DollarRecognizer));
var o, n = onCanvasMouseMove.pts,
t = e.clientX,
r = e.clientY;
onCanvasMouseMove.lastMove && e.timeStamp - onCanvasMouseMove.lastMove > 300 && (n && n.length ? (window.DollarRecognizer && (o = Rcgnzr.Recognize(n), "star" == o.Name && o.Score >= .6 && window.starryEgg && starryEgg()), onCanvasMouseMove.pts = []) : onCanvasMouseMove.pts = []), onCanvasMouseMove.lastMove = +e.timeStamp, window.Point && n && (n[n.length] = new Point(t, r)), brush.stroke(t, r)
}
function onCanvasMouseUp() {
brush.strokeEnd(), window.removeEventListener("mousemove", onCanvasMouseMove, !1), window.removeEventListener("mouseup", onCanvasMouseUp, !1)
}
function onCanvasTouchStart(e) {
cleanPopUps(), 1 == e.touches.length && (e.preventDefault(), brush.strokeStart(e.touches[0].pageX, e.touches[0].pageY), window.addEventListener("touchmove", onCanvasTouchMove, !1), window.addEventListener("touchend", onCanvasTouchEnd, !1))
}
function onCanvasTouchMove(e) {
1 == e.touches.length && (e.preventDefault(), brush.stroke(e.touches[0].pageX, e.touches[0].pageY))
}
function onCanvasTouchEnd(e) {
0 == e.touches.length && (e.preventDefault(), brush.strokeEnd(), window.removeEventListener("touchmove", onCanvasTouchMove, !1), window.removeEventListener("touchend", onCanvasTouchEnd, !1))
}
function cleanPopUps() {
isForegroundColorSelectorVisible && (foregroundColorSelector.hide(), isForegroundColorSelectorVisible = !1), isBackgroundColorSelectorVisible && (backgroundColorSelector.hide(), isBackgroundColorSelectorVisible = !1), isAboutVisible && (about.hide(), isAboutVisible = !1)
}
ribbon.prototype = {
context: null,
mouseX: null,
mouseY: null,
painters: null,
interval: null,
init: function(e) {
this.context = e, this.context.lineWidth = 1, this.context.globalCompositeOperation = "source-over", this.mouseX = SCREEN_WIDTH / 2, this.mouseY = SCREEN_HEIGHT / 2, this.painters = new Array;
for (var o = 0; 50 > o; o++) this.painters.push({
dx: SCREEN_WIDTH / 2,
dy: SCREEN_HEIGHT / 2,
ax: 0,
ay: 0,
div: .1,
ease: .2 * Math.random() + .6
});
this.isDrawing = !1;
var n = this;
! function t() {
n.update(), requestAnimFrame(t)
}()
},
destroy: function() {
clearInterval(this.interval)
},
strokeStart: function(e, o) {
this.mouseX = e, this.mouseY = o, this.context.strokeStyle = "rgba(" + COLOR[0] + ", " + COLOR[1] + ", " + COLOR[2] + ", 0.05 )";
for (var n = 0; n < this.painters.length; n++) this.painters[n].dx = e, this.painters[n].dy = o;
this.shouldDraw = !0
},
stroke: function(e, o) {
this.mouseX = e, this.mouseY = o
},
strokeEnd: function() {},
update: function() {
var e;
for (e = 0; e < this.painters.length; e++) this.context.beginPath(), this.context.moveTo(this.painters[e].dx, this.painters[e].dy), this.painters[e].dx -= this.painters[e].ax = (this.painters[e].ax + (this.painters[e].dx - this.mouseX) * this.painters[e].div) * this.painters[e].ease, this.painters[e].dy -= this.painters[e].ay = (this.painters[e].ay + (this.painters[e].dy - this.mouseY) * this.painters[e].div) * this.painters[e].ease, this.context.lineTo(this.painters[e].dx, this.painters[e].dy), this.context.stroke()
}
};
var i, brush, BRUSHES = ["ribbon"],
COLOR = [0, 0, 0],
BACKGROUND_COLOR = [250, 250, 250],
SCREEN_WIDTH = window.innerWidth,
SCREEN_HEIGHT = window.innerHeight,
container, foregroundColorSelector, backgroundColorSelector, menu, about, canvas, flattenCanvas, context, isForegroundColorSelectorVisible = !1,
isBackgroundColorSelectorVisible = !1,
isAboutVisible = !1,
isMenuMouseOver = !1,
shiftKeyIsDown = !1,
altKeyIsDown = !1;
window.harmony = function() {
container = document.createElement("div"), document.body.appendChild(container), canvas = document.createElement("canvas"), canvas.width = SCREEN_WIDTH, canvas.height = SCREEN_HEIGHT, canvas.style.cursor = "crosshair", container.appendChild(canvas), canvas.getContext && (context = canvas.getContext("2d"), flattenCanvas = document.createElement("canvas"), flattenCanvas.width = SCREEN_WIDTH, flattenCanvas.height = SCREEN_HEIGHT, brush || (brush = new ribbon(context)), window.addEventListener("mousemove", onWindowMouseMove, !1), window.addEventListener("resize", onWindowResize, !1), window.addEventListener("keydown", onDocumentKeyDown, !1), window.addEventListener("keyup", onDocumentKeyUp, !1), document.addEventListener("mouseout", onCanvasMouseUp, !1), canvas.addEventListener("mousemove", onCanvasMouseMove, !1), canvas.addEventListener("touchstart", onCanvasTouchStart, !1), onWindowResize(null))
}
}(this, this.document);
var NumTemplates = 16,
NumPoints = 64,
SquareSize = 250,
Origin = new Point(0, 0),
Diagonal = Math.sqrt(SquareSize * SquareSize + SquareSize * SquareSize),
HalfDiagonal = .5 * Diagonal,
AngleRange = Deg2Rad(45),
AnglePrecision = Deg2Rad(2),
Phi = .5 * (-1 + Math.sqrt(5)),
easter_egg = new Konami;
easter_egg.code = function() {
setTimeout(harmony, 5)
}, easter_egg.load();
var Konami = function(t) {
var e = {
addEvent: function(t, e, n, i) {
t.addEventListener ? t.addEventListener(e, n, !1) : t.attachEvent && (t["e" + e + n] = n, t[e + n] = function() {
t["e" + e + n](window.event, i)
}, t.attachEvent("on" + e, t[e + n]))
},
input: "",
pattern: "38384040373937396665",
load: function(t) {
this.addEvent(document, "keydown", function(n, i) {
return i && (e = i), e.input += n ? n.keyCode : event.keyCode, e.input.length > e.pattern.length && (e.input = e.input.substr(e.input.length - e.pattern.length)), e.input == e.pattern ? (e.code(t), e.input = "", n.preventDefault(), !1) : void 0
}, this), this.iphone.load(t)
},
code: function(t) {
window.location = t
},
iphone: {
start_x: 0,
start_y: 0,
stop_x: 0,
stop_y: 0,
tap: !1,
capture: !1,
orig_keys: "",
keys: ["UP", "UP", "DOWN", "DOWN", "LEFT", "RIGHT", "LEFT", "RIGHT", "TAP", "TAP"],
code: function(t) {
e.code(t)
},
load: function(t) {
this.orig_keys = this.keys, e.addEvent(document, "touchmove", function(t) {
if (1 == t.touches.length && 1 == e.iphone.capture) {
var n = t.touches[0];
e.iphone.stop_x = n.pageX, e.iphone.stop_y = n.pageY, e.iphone.tap = !1, e.iphone.capture = !1, e.iphone.check_direction()
}
}), e.addEvent(document, "touchend", function() {
1 == e.iphone.tap && e.iphone.check_direction(t)
}, !1), e.addEvent(document, "touchstart", function(t) {
e.iphone.start_x = t.changedTouches[0].pageX, e.iphone.start_y = t.changedTouches[0].pageY, e.iphone.tap = !0, e.iphone.capture = !0
})
},
check_direction: function(t) {
x_magnitude = Math.abs(this.start_x - this.stop_x), y_magnitude = Math.abs(this.start_y - this.stop_y), x = this.start_x - this.stop_x < 0 ? "RIGHT" : "LEFT", y = this.start_y - this.stop_y < 0 ? "DOWN" : "UP", result = x_magnitude > y_magnitude ? x : y, result = 1 == this.tap ? "TAP" : result, result == this.keys[0] && (this.keys = this.keys.slice(1, this.keys.length)), 0 == this.keys.length && (this.keys = this.orig_keys, this.code(t))
}
}
};
return "string" == typeof t && e.load(t), "function" == typeof t && (e.code = t, e.load()), e
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment