Added confetti option

Signed-off-by: snipe <snipe@snipe.net>
This commit is contained in:
snipe 2024-08-15 11:32:42 +01:00
parent 10dc1f1368
commit 4356cb7b9b
12 changed files with 1878 additions and 4 deletions

View file

@ -50,6 +50,7 @@ class ProfileController extends Controller
$user->skin = $request->input('skin');
$user->phone = $request->input('phone');
$user->enable_sounds = $request->input('enable_sounds', false);
$user->enable_confetti = $request->input('enable_confetti', false);
if (! config('app.lock_passwords')) {
$user->locale = $request->input('locale', 'en-US');

View file

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->boolean('enable_confetti')->default(false);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('enable_confetti');
});
}
};

10
package-lock.json generated
View file

@ -16,6 +16,7 @@
"bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.23.0",
"canvas-confetti": "^1.9.3",
"chart.js": "^2.9.4",
"clipboard": "^2.0.11",
"css-loader": "^5.0.0",
@ -4098,6 +4099,15 @@
],
"license": "CC-BY-4.0"
},
"node_modules/canvas-confetti": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.3.tgz",
"integrity": "sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==",
"funding": {
"type": "donate",
"url": "https://www.paypal.me/kirilvatev"
}
},
"node_modules/canvg": {
"version": "3.0.10",
"license": "MIT",

View file

@ -36,6 +36,7 @@
"bootstrap-datepicker": "^1.10.0",
"bootstrap-less": "^3.3.8",
"bootstrap-table": "1.23.0",
"canvas-confetti": "^1.9.3",
"chart.js": "^2.9.4",
"clipboard": "^2.0.11",
"css-loader": "^5.0.0",

View file

@ -3157,6 +3157,903 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/***/ }),
/***/ "./node_modules/canvas-confetti/dist/confetti.browser.js":
/*!***************************************************************!*\
!*** ./node_modules/canvas-confetti/dist/confetti.browser.js ***!
\***************************************************************/
/***/ (() => {
// canvas-confetti v1.9.3 built on 2024-04-30T22:19:17.794Z
!(function (window, module) {
// source content
/* globals Map */
(function main(global, module, isWorker, workerSize) {
var canUseWorker = !!(
global.Worker &&
global.Blob &&
global.Promise &&
global.OffscreenCanvas &&
global.OffscreenCanvasRenderingContext2D &&
global.HTMLCanvasElement &&
global.HTMLCanvasElement.prototype.transferControlToOffscreen &&
global.URL &&
global.URL.createObjectURL);
var canUsePaths = typeof Path2D === 'function' && typeof DOMMatrix === 'function';
var canDrawBitmap = (function () {
// this mostly supports ssr
if (!global.OffscreenCanvas) {
return false;
}
var canvas = new OffscreenCanvas(1, 1);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1, 1);
var bitmap = canvas.transferToImageBitmap();
try {
ctx.createPattern(bitmap, 'no-repeat');
} catch (e) {
return false;
}
return true;
})();
function noop() {}
// create a promise if it exists, otherwise, just
// call the function directly
function promise(func) {
var ModulePromise = module.exports.Promise;
var Prom = ModulePromise !== void 0 ? ModulePromise : global.Promise;
if (typeof Prom === 'function') {
return new Prom(func);
}
func(noop, noop);
return null;
}
var bitmapMapper = (function (skipTransform, map) {
// see https://github.com/catdad/canvas-confetti/issues/209
// creating canvases is actually pretty expensive, so we should create a
// 1:1 map for bitmap:canvas, so that we can animate the confetti in
// a performant manner, but also not store them forever so that we don't
// have a memory leak
return {
transform: function(bitmap) {
if (skipTransform) {
return bitmap;
}
if (map.has(bitmap)) {
return map.get(bitmap);
}
var canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
var ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0);
map.set(bitmap, canvas);
return canvas;
},
clear: function () {
map.clear();
}
};
})(canDrawBitmap, new Map());
var raf = (function () {
var TIME = Math.floor(1000 / 60);
var frame, cancel;
var frames = {};
var lastFrameTime = 0;
if (typeof requestAnimationFrame === 'function' && typeof cancelAnimationFrame === 'function') {
frame = function (cb) {
var id = Math.random();
frames[id] = requestAnimationFrame(function onFrame(time) {
if (lastFrameTime === time || lastFrameTime + TIME - 1 < time) {
lastFrameTime = time;
delete frames[id];
cb();
} else {
frames[id] = requestAnimationFrame(onFrame);
}
});
return id;
};
cancel = function (id) {
if (frames[id]) {
cancelAnimationFrame(frames[id]);
}
};
} else {
frame = function (cb) {
return setTimeout(cb, TIME);
};
cancel = function (timer) {
return clearTimeout(timer);
};
}
return { frame: frame, cancel: cancel };
}());
var getWorker = (function () {
var worker;
var prom;
var resolves = {};
function decorate(worker) {
function execute(options, callback) {
worker.postMessage({ options: options || {}, callback: callback });
}
worker.init = function initWorker(canvas) {
var offscreen = canvas.transferControlToOffscreen();
worker.postMessage({ canvas: offscreen }, [offscreen]);
};
worker.fire = function fireWorker(options, size, done) {
if (prom) {
execute(options, null);
return prom;
}
var id = Math.random().toString(36).slice(2);
prom = promise(function (resolve) {
function workerDone(msg) {
if (msg.data.callback !== id) {
return;
}
delete resolves[id];
worker.removeEventListener('message', workerDone);
prom = null;
bitmapMapper.clear();
done();
resolve();
}
worker.addEventListener('message', workerDone);
execute(options, id);
resolves[id] = workerDone.bind(null, { data: { callback: id }});
});
return prom;
};
worker.reset = function resetWorker() {
worker.postMessage({ reset: true });
for (var id in resolves) {
resolves[id]();
delete resolves[id];
}
};
}
return function () {
if (worker) {
return worker;
}
if (!isWorker && canUseWorker) {
var code = [
'var CONFETTI, SIZE = {}, module = {};',
'(' + main.toString() + ')(this, module, true, SIZE);',
'onmessage = function(msg) {',
' if (msg.data.options) {',
' CONFETTI(msg.data.options).then(function () {',
' if (msg.data.callback) {',
' postMessage({ callback: msg.data.callback });',
' }',
' });',
' } else if (msg.data.reset) {',
' CONFETTI && CONFETTI.reset();',
' } else if (msg.data.resize) {',
' SIZE.width = msg.data.resize.width;',
' SIZE.height = msg.data.resize.height;',
' } else if (msg.data.canvas) {',
' SIZE.width = msg.data.canvas.width;',
' SIZE.height = msg.data.canvas.height;',
' CONFETTI = module.exports.create(msg.data.canvas);',
' }',
'}',
].join('\n');
try {
worker = new Worker(URL.createObjectURL(new Blob([code])));
} catch (e) {
// eslint-disable-next-line no-console
typeof console !== undefined && typeof console.warn === 'function' ? console.warn('🎊 Could not load worker', e) : null;
return null;
}
decorate(worker);
}
return worker;
};
})();
var defaults = {
particleCount: 50,
angle: 90,
spread: 45,
startVelocity: 45,
decay: 0.9,
gravity: 1,
drift: 0,
ticks: 200,
x: 0.5,
y: 0.5,
shapes: ['square', 'circle'],
zIndex: 100,
colors: [
'#26ccff',
'#a25afd',
'#ff5e7e',
'#88ff5a',
'#fcff42',
'#ffa62d',
'#ff36ff'
],
// probably should be true, but back-compat
disableForReducedMotion: false,
scalar: 1
};
function convert(val, transform) {
return transform ? transform(val) : val;
}
function isOk(val) {
return !(val === null || val === undefined);
}
function prop(options, name, transform) {
return convert(
options && isOk(options[name]) ? options[name] : defaults[name],
transform
);
}
function onlyPositiveInt(number){
return number < 0 ? 0 : Math.floor(number);
}
function randomInt(min, max) {
// [min, max)
return Math.floor(Math.random() * (max - min)) + min;
}
function toDecimal(str) {
return parseInt(str, 16);
}
function colorsToRgb(colors) {
return colors.map(hexToRgb);
}
function hexToRgb(str) {
var val = String(str).replace(/[^0-9a-f]/gi, '');
if (val.length < 6) {
val = val[0]+val[0]+val[1]+val[1]+val[2]+val[2];
}
return {
r: toDecimal(val.substring(0,2)),
g: toDecimal(val.substring(2,4)),
b: toDecimal(val.substring(4,6))
};
}
function getOrigin(options) {
var origin = prop(options, 'origin', Object);
origin.x = prop(origin, 'x', Number);
origin.y = prop(origin, 'y', Number);
return origin;
}
function setCanvasWindowSize(canvas) {
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
}
function setCanvasRectSize(canvas) {
var rect = canvas.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
}
function getCanvas(zIndex) {
var canvas = document.createElement('canvas');
canvas.style.position = 'fixed';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.pointerEvents = 'none';
canvas.style.zIndex = zIndex;
return canvas;
}
function ellipse(context, x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise) {
context.save();
context.translate(x, y);
context.rotate(rotation);
context.scale(radiusX, radiusY);
context.arc(0, 0, 1, startAngle, endAngle, antiClockwise);
context.restore();
}
function randomPhysics(opts) {
var radAngle = opts.angle * (Math.PI / 180);
var radSpread = opts.spread * (Math.PI / 180);
return {
x: opts.x,
y: opts.y,
wobble: Math.random() * 10,
wobbleSpeed: Math.min(0.11, Math.random() * 0.1 + 0.05),
velocity: (opts.startVelocity * 0.5) + (Math.random() * opts.startVelocity),
angle2D: -radAngle + ((0.5 * radSpread) - (Math.random() * radSpread)),
tiltAngle: (Math.random() * (0.75 - 0.25) + 0.25) * Math.PI,
color: opts.color,
shape: opts.shape,
tick: 0,
totalTicks: opts.ticks,
decay: opts.decay,
drift: opts.drift,
random: Math.random() + 2,
tiltSin: 0,
tiltCos: 0,
wobbleX: 0,
wobbleY: 0,
gravity: opts.gravity * 3,
ovalScalar: 0.6,
scalar: opts.scalar,
flat: opts.flat
};
}
function updateFetti(context, fetti) {
fetti.x += Math.cos(fetti.angle2D) * fetti.velocity + fetti.drift;
fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity;
fetti.velocity *= fetti.decay;
if (fetti.flat) {
fetti.wobble = 0;
fetti.wobbleX = fetti.x + (10 * fetti.scalar);
fetti.wobbleY = fetti.y + (10 * fetti.scalar);
fetti.tiltSin = 0;
fetti.tiltCos = 0;
fetti.random = 1;
} else {
fetti.wobble += fetti.wobbleSpeed;
fetti.wobbleX = fetti.x + ((10 * fetti.scalar) * Math.cos(fetti.wobble));
fetti.wobbleY = fetti.y + ((10 * fetti.scalar) * Math.sin(fetti.wobble));
fetti.tiltAngle += 0.1;
fetti.tiltSin = Math.sin(fetti.tiltAngle);
fetti.tiltCos = Math.cos(fetti.tiltAngle);
fetti.random = Math.random() + 2;
}
var progress = (fetti.tick++) / fetti.totalTicks;
var x1 = fetti.x + (fetti.random * fetti.tiltCos);
var y1 = fetti.y + (fetti.random * fetti.tiltSin);
var x2 = fetti.wobbleX + (fetti.random * fetti.tiltCos);
var y2 = fetti.wobbleY + (fetti.random * fetti.tiltSin);
context.fillStyle = 'rgba(' + fetti.color.r + ', ' + fetti.color.g + ', ' + fetti.color.b + ', ' + (1 - progress) + ')';
context.beginPath();
if (canUsePaths && fetti.shape.type === 'path' && typeof fetti.shape.path === 'string' && Array.isArray(fetti.shape.matrix)) {
context.fill(transformPath2D(
fetti.shape.path,
fetti.shape.matrix,
fetti.x,
fetti.y,
Math.abs(x2 - x1) * 0.1,
Math.abs(y2 - y1) * 0.1,
Math.PI / 10 * fetti.wobble
));
} else if (fetti.shape.type === 'bitmap') {
var rotation = Math.PI / 10 * fetti.wobble;
var scaleX = Math.abs(x2 - x1) * 0.1;
var scaleY = Math.abs(y2 - y1) * 0.1;
var width = fetti.shape.bitmap.width * fetti.scalar;
var height = fetti.shape.bitmap.height * fetti.scalar;
var matrix = new DOMMatrix([
Math.cos(rotation) * scaleX,
Math.sin(rotation) * scaleX,
-Math.sin(rotation) * scaleY,
Math.cos(rotation) * scaleY,
fetti.x,
fetti.y
]);
// apply the transform matrix from the confetti shape
matrix.multiplySelf(new DOMMatrix(fetti.shape.matrix));
var pattern = context.createPattern(bitmapMapper.transform(fetti.shape.bitmap), 'no-repeat');
pattern.setTransform(matrix);
context.globalAlpha = (1 - progress);
context.fillStyle = pattern;
context.fillRect(
fetti.x - (width / 2),
fetti.y - (height / 2),
width,
height
);
context.globalAlpha = 1;
} else if (fetti.shape === 'circle') {
context.ellipse ?
context.ellipse(fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI) :
ellipse(context, fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI);
} else if (fetti.shape === 'star') {
var rot = Math.PI / 2 * 3;
var innerRadius = 4 * fetti.scalar;
var outerRadius = 8 * fetti.scalar;
var x = fetti.x;
var y = fetti.y;
var spikes = 5;
var step = Math.PI / spikes;
while (spikes--) {
x = fetti.x + Math.cos(rot) * outerRadius;
y = fetti.y + Math.sin(rot) * outerRadius;
context.lineTo(x, y);
rot += step;
x = fetti.x + Math.cos(rot) * innerRadius;
y = fetti.y + Math.sin(rot) * innerRadius;
context.lineTo(x, y);
rot += step;
}
} else {
context.moveTo(Math.floor(fetti.x), Math.floor(fetti.y));
context.lineTo(Math.floor(fetti.wobbleX), Math.floor(y1));
context.lineTo(Math.floor(x2), Math.floor(y2));
context.lineTo(Math.floor(x1), Math.floor(fetti.wobbleY));
}
context.closePath();
context.fill();
return fetti.tick < fetti.totalTicks;
}
function animate(canvas, fettis, resizer, size, done) {
var animatingFettis = fettis.slice();
var context = canvas.getContext('2d');
var animationFrame;
var destroy;
var prom = promise(function (resolve) {
function onDone() {
animationFrame = destroy = null;
context.clearRect(0, 0, size.width, size.height);
bitmapMapper.clear();
done();
resolve();
}
function update() {
if (isWorker && !(size.width === workerSize.width && size.height === workerSize.height)) {
size.width = canvas.width = workerSize.width;
size.height = canvas.height = workerSize.height;
}
if (!size.width && !size.height) {
resizer(canvas);
size.width = canvas.width;
size.height = canvas.height;
}
context.clearRect(0, 0, size.width, size.height);
animatingFettis = animatingFettis.filter(function (fetti) {
return updateFetti(context, fetti);
});
if (animatingFettis.length) {
animationFrame = raf.frame(update);
} else {
onDone();
}
}
animationFrame = raf.frame(update);
destroy = onDone;
});
return {
addFettis: function (fettis) {
animatingFettis = animatingFettis.concat(fettis);
return prom;
},
canvas: canvas,
promise: prom,
reset: function () {
if (animationFrame) {
raf.cancel(animationFrame);
}
if (destroy) {
destroy();
}
}
};
}
function confettiCannon(canvas, globalOpts) {
var isLibCanvas = !canvas;
var allowResize = !!prop(globalOpts || {}, 'resize');
var hasResizeEventRegistered = false;
var globalDisableForReducedMotion = prop(globalOpts, 'disableForReducedMotion', Boolean);
var shouldUseWorker = canUseWorker && !!prop(globalOpts || {}, 'useWorker');
var worker = shouldUseWorker ? getWorker() : null;
var resizer = isLibCanvas ? setCanvasWindowSize : setCanvasRectSize;
var initialized = (canvas && worker) ? !!canvas.__confetti_initialized : false;
var preferLessMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion)').matches;
var animationObj;
function fireLocal(options, size, done) {
var particleCount = prop(options, 'particleCount', onlyPositiveInt);
var angle = prop(options, 'angle', Number);
var spread = prop(options, 'spread', Number);
var startVelocity = prop(options, 'startVelocity', Number);
var decay = prop(options, 'decay', Number);
var gravity = prop(options, 'gravity', Number);
var drift = prop(options, 'drift', Number);
var colors = prop(options, 'colors', colorsToRgb);
var ticks = prop(options, 'ticks', Number);
var shapes = prop(options, 'shapes');
var scalar = prop(options, 'scalar');
var flat = !!prop(options, 'flat');
var origin = getOrigin(options);
var temp = particleCount;
var fettis = [];
var startX = canvas.width * origin.x;
var startY = canvas.height * origin.y;
while (temp--) {
fettis.push(
randomPhysics({
x: startX,
y: startY,
angle: angle,
spread: spread,
startVelocity: startVelocity,
color: colors[temp % colors.length],
shape: shapes[randomInt(0, shapes.length)],
ticks: ticks,
decay: decay,
gravity: gravity,
drift: drift,
scalar: scalar,
flat: flat
})
);
}
// if we have a previous canvas already animating,
// add to it
if (animationObj) {
return animationObj.addFettis(fettis);
}
animationObj = animate(canvas, fettis, resizer, size , done);
return animationObj.promise;
}
function fire(options) {
var disableForReducedMotion = globalDisableForReducedMotion || prop(options, 'disableForReducedMotion', Boolean);
var zIndex = prop(options, 'zIndex', Number);
if (disableForReducedMotion && preferLessMotion) {
return promise(function (resolve) {
resolve();
});
}
if (isLibCanvas && animationObj) {
// use existing canvas from in-progress animation
canvas = animationObj.canvas;
} else if (isLibCanvas && !canvas) {
// create and initialize a new canvas
canvas = getCanvas(zIndex);
document.body.appendChild(canvas);
}
if (allowResize && !initialized) {
// initialize the size of a user-supplied canvas
resizer(canvas);
}
var size = {
width: canvas.width,
height: canvas.height
};
if (worker && !initialized) {
worker.init(canvas);
}
initialized = true;
if (worker) {
canvas.__confetti_initialized = true;
}
function onResize() {
if (worker) {
// TODO this really shouldn't be immediate, because it is expensive
var obj = {
getBoundingClientRect: function () {
if (!isLibCanvas) {
return canvas.getBoundingClientRect();
}
}
};
resizer(obj);
worker.postMessage({
resize: {
width: obj.width,
height: obj.height
}
});
return;
}
// don't actually query the size here, since this
// can execute frequently and rapidly
size.width = size.height = null;
}
function done() {
animationObj = null;
if (allowResize) {
hasResizeEventRegistered = false;
global.removeEventListener('resize', onResize);
}
if (isLibCanvas && canvas) {
if (document.body.contains(canvas)) {
document.body.removeChild(canvas);
}
canvas = null;
initialized = false;
}
}
if (allowResize && !hasResizeEventRegistered) {
hasResizeEventRegistered = true;
global.addEventListener('resize', onResize, false);
}
if (worker) {
return worker.fire(options, size, done);
}
return fireLocal(options, size, done);
}
fire.reset = function () {
if (worker) {
worker.reset();
}
if (animationObj) {
animationObj.reset();
}
};
return fire;
}
// Make default export lazy to defer worker creation until called.
var defaultFire;
function getDefaultFire() {
if (!defaultFire) {
defaultFire = confettiCannon(null, { useWorker: true, resize: true });
}
return defaultFire;
}
function transformPath2D(pathString, pathMatrix, x, y, scaleX, scaleY, rotation) {
var path2d = new Path2D(pathString);
var t1 = new Path2D();
t1.addPath(path2d, new DOMMatrix(pathMatrix));
var t2 = new Path2D();
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix/DOMMatrix
t2.addPath(t1, new DOMMatrix([
Math.cos(rotation) * scaleX,
Math.sin(rotation) * scaleX,
-Math.sin(rotation) * scaleY,
Math.cos(rotation) * scaleY,
x,
y
]));
return t2;
}
function shapeFromPath(pathData) {
if (!canUsePaths) {
throw new Error('path confetti are not supported in this browser');
}
var path, matrix;
if (typeof pathData === 'string') {
path = pathData;
} else {
path = pathData.path;
matrix = pathData.matrix;
}
var path2d = new Path2D(path);
var tempCanvas = document.createElement('canvas');
var tempCtx = tempCanvas.getContext('2d');
if (!matrix) {
// attempt to figure out the width of the path, up to 1000x1000
var maxSize = 1000;
var minX = maxSize;
var minY = maxSize;
var maxX = 0;
var maxY = 0;
var width, height;
// do some line skipping... this is faster than checking
// every pixel and will be mostly still correct
for (var x = 0; x < maxSize; x += 2) {
for (var y = 0; y < maxSize; y += 2) {
if (tempCtx.isPointInPath(path2d, x, y, 'nonzero')) {
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
}
width = maxX - minX;
height = maxY - minY;
var maxDesiredSize = 10;
var scale = Math.min(maxDesiredSize/width, maxDesiredSize/height);
matrix = [
scale, 0, 0, scale,
-Math.round((width/2) + minX) * scale,
-Math.round((height/2) + minY) * scale
];
}
return {
type: 'path',
path: path,
matrix: matrix
};
}
function shapeFromText(textData) {
var text,
scalar = 1,
color = '#000000',
// see https://nolanlawson.com/2022/04/08/the-struggle-of-using-native-emoji-on-the-web/
fontFamily = '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", "EmojiOne Color", "Android Emoji", "Twemoji Mozilla", "system emoji", sans-serif';
if (typeof textData === 'string') {
text = textData;
} else {
text = textData.text;
scalar = 'scalar' in textData ? textData.scalar : scalar;
fontFamily = 'fontFamily' in textData ? textData.fontFamily : fontFamily;
color = 'color' in textData ? textData.color : color;
}
// all other confetti are 10 pixels,
// so this pixel size is the de-facto 100% scale confetti
var fontSize = 10 * scalar;
var font = '' + fontSize + 'px ' + fontFamily;
var canvas = new OffscreenCanvas(fontSize, fontSize);
var ctx = canvas.getContext('2d');
ctx.font = font;
var size = ctx.measureText(text);
var width = Math.ceil(size.actualBoundingBoxRight + size.actualBoundingBoxLeft);
var height = Math.ceil(size.actualBoundingBoxAscent + size.actualBoundingBoxDescent);
var padding = 2;
var x = size.actualBoundingBoxLeft + padding;
var y = size.actualBoundingBoxAscent + padding;
width += padding + padding;
height += padding + padding;
canvas = new OffscreenCanvas(width, height);
ctx = canvas.getContext('2d');
ctx.font = font;
ctx.fillStyle = color;
ctx.fillText(text, x, y);
var scale = 1 / scalar;
return {
type: 'bitmap',
// TODO these probably need to be transfered for workers
bitmap: canvas.transferToImageBitmap(),
matrix: [scale, 0, 0, scale, -width * scale / 2, -height * scale / 2]
};
}
module.exports = function() {
return getDefaultFire().apply(this, arguments);
};
module.exports.reset = function() {
getDefaultFire().reset();
};
module.exports.create = confettiCannon;
module.exports.shapeFromPath = shapeFromPath;
module.exports.shapeFromText = shapeFromText;
}((function () {
if (typeof window !== 'undefined') {
return window;
}
if (typeof self !== 'undefined') {
return self;
}
return this || {};
})(), module, false));
// end source content
window.confetti = module.exports;
}(window, {}));
/***/ }),
/***/ "./node_modules/jquery-ui/ui/version.js":
@ -32476,6 +33373,7 @@ __webpack_require__.r(__webpack_exports__);
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/js/snipeit.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/js/snipeit_modals.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./node_modules/canvas-confetti/dist/confetti.browser.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./node_modules/admin-lte/build/less/AdminLTE.less")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/less/app.less")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/less/overrides.less")))

898
public/js/dist/all.js vendored
View file

@ -62351,6 +62351,903 @@ if (typeof jQuery === 'undefined') {
}(jQuery);
/***/ }),
/***/ "./node_modules/canvas-confetti/dist/confetti.browser.js":
/*!***************************************************************!*\
!*** ./node_modules/canvas-confetti/dist/confetti.browser.js ***!
\***************************************************************/
/***/ (() => {
// canvas-confetti v1.9.3 built on 2024-04-30T22:19:17.794Z
!(function (window, module) {
// source content
/* globals Map */
(function main(global, module, isWorker, workerSize) {
var canUseWorker = !!(
global.Worker &&
global.Blob &&
global.Promise &&
global.OffscreenCanvas &&
global.OffscreenCanvasRenderingContext2D &&
global.HTMLCanvasElement &&
global.HTMLCanvasElement.prototype.transferControlToOffscreen &&
global.URL &&
global.URL.createObjectURL);
var canUsePaths = typeof Path2D === 'function' && typeof DOMMatrix === 'function';
var canDrawBitmap = (function () {
// this mostly supports ssr
if (!global.OffscreenCanvas) {
return false;
}
var canvas = new OffscreenCanvas(1, 1);
var ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 1, 1);
var bitmap = canvas.transferToImageBitmap();
try {
ctx.createPattern(bitmap, 'no-repeat');
} catch (e) {
return false;
}
return true;
})();
function noop() {}
// create a promise if it exists, otherwise, just
// call the function directly
function promise(func) {
var ModulePromise = module.exports.Promise;
var Prom = ModulePromise !== void 0 ? ModulePromise : global.Promise;
if (typeof Prom === 'function') {
return new Prom(func);
}
func(noop, noop);
return null;
}
var bitmapMapper = (function (skipTransform, map) {
// see https://github.com/catdad/canvas-confetti/issues/209
// creating canvases is actually pretty expensive, so we should create a
// 1:1 map for bitmap:canvas, so that we can animate the confetti in
// a performant manner, but also not store them forever so that we don't
// have a memory leak
return {
transform: function(bitmap) {
if (skipTransform) {
return bitmap;
}
if (map.has(bitmap)) {
return map.get(bitmap);
}
var canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
var ctx = canvas.getContext('2d');
ctx.drawImage(bitmap, 0, 0);
map.set(bitmap, canvas);
return canvas;
},
clear: function () {
map.clear();
}
};
})(canDrawBitmap, new Map());
var raf = (function () {
var TIME = Math.floor(1000 / 60);
var frame, cancel;
var frames = {};
var lastFrameTime = 0;
if (typeof requestAnimationFrame === 'function' && typeof cancelAnimationFrame === 'function') {
frame = function (cb) {
var id = Math.random();
frames[id] = requestAnimationFrame(function onFrame(time) {
if (lastFrameTime === time || lastFrameTime + TIME - 1 < time) {
lastFrameTime = time;
delete frames[id];
cb();
} else {
frames[id] = requestAnimationFrame(onFrame);
}
});
return id;
};
cancel = function (id) {
if (frames[id]) {
cancelAnimationFrame(frames[id]);
}
};
} else {
frame = function (cb) {
return setTimeout(cb, TIME);
};
cancel = function (timer) {
return clearTimeout(timer);
};
}
return { frame: frame, cancel: cancel };
}());
var getWorker = (function () {
var worker;
var prom;
var resolves = {};
function decorate(worker) {
function execute(options, callback) {
worker.postMessage({ options: options || {}, callback: callback });
}
worker.init = function initWorker(canvas) {
var offscreen = canvas.transferControlToOffscreen();
worker.postMessage({ canvas: offscreen }, [offscreen]);
};
worker.fire = function fireWorker(options, size, done) {
if (prom) {
execute(options, null);
return prom;
}
var id = Math.random().toString(36).slice(2);
prom = promise(function (resolve) {
function workerDone(msg) {
if (msg.data.callback !== id) {
return;
}
delete resolves[id];
worker.removeEventListener('message', workerDone);
prom = null;
bitmapMapper.clear();
done();
resolve();
}
worker.addEventListener('message', workerDone);
execute(options, id);
resolves[id] = workerDone.bind(null, { data: { callback: id }});
});
return prom;
};
worker.reset = function resetWorker() {
worker.postMessage({ reset: true });
for (var id in resolves) {
resolves[id]();
delete resolves[id];
}
};
}
return function () {
if (worker) {
return worker;
}
if (!isWorker && canUseWorker) {
var code = [
'var CONFETTI, SIZE = {}, module = {};',
'(' + main.toString() + ')(this, module, true, SIZE);',
'onmessage = function(msg) {',
' if (msg.data.options) {',
' CONFETTI(msg.data.options).then(function () {',
' if (msg.data.callback) {',
' postMessage({ callback: msg.data.callback });',
' }',
' });',
' } else if (msg.data.reset) {',
' CONFETTI && CONFETTI.reset();',
' } else if (msg.data.resize) {',
' SIZE.width = msg.data.resize.width;',
' SIZE.height = msg.data.resize.height;',
' } else if (msg.data.canvas) {',
' SIZE.width = msg.data.canvas.width;',
' SIZE.height = msg.data.canvas.height;',
' CONFETTI = module.exports.create(msg.data.canvas);',
' }',
'}',
].join('\n');
try {
worker = new Worker(URL.createObjectURL(new Blob([code])));
} catch (e) {
// eslint-disable-next-line no-console
typeof console !== undefined && typeof console.warn === 'function' ? console.warn('🎊 Could not load worker', e) : null;
return null;
}
decorate(worker);
}
return worker;
};
})();
var defaults = {
particleCount: 50,
angle: 90,
spread: 45,
startVelocity: 45,
decay: 0.9,
gravity: 1,
drift: 0,
ticks: 200,
x: 0.5,
y: 0.5,
shapes: ['square', 'circle'],
zIndex: 100,
colors: [
'#26ccff',
'#a25afd',
'#ff5e7e',
'#88ff5a',
'#fcff42',
'#ffa62d',
'#ff36ff'
],
// probably should be true, but back-compat
disableForReducedMotion: false,
scalar: 1
};
function convert(val, transform) {
return transform ? transform(val) : val;
}
function isOk(val) {
return !(val === null || val === undefined);
}
function prop(options, name, transform) {
return convert(
options && isOk(options[name]) ? options[name] : defaults[name],
transform
);
}
function onlyPositiveInt(number){
return number < 0 ? 0 : Math.floor(number);
}
function randomInt(min, max) {
// [min, max)
return Math.floor(Math.random() * (max - min)) + min;
}
function toDecimal(str) {
return parseInt(str, 16);
}
function colorsToRgb(colors) {
return colors.map(hexToRgb);
}
function hexToRgb(str) {
var val = String(str).replace(/[^0-9a-f]/gi, '');
if (val.length < 6) {
val = val[0]+val[0]+val[1]+val[1]+val[2]+val[2];
}
return {
r: toDecimal(val.substring(0,2)),
g: toDecimal(val.substring(2,4)),
b: toDecimal(val.substring(4,6))
};
}
function getOrigin(options) {
var origin = prop(options, 'origin', Object);
origin.x = prop(origin, 'x', Number);
origin.y = prop(origin, 'y', Number);
return origin;
}
function setCanvasWindowSize(canvas) {
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;
}
function setCanvasRectSize(canvas) {
var rect = canvas.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
}
function getCanvas(zIndex) {
var canvas = document.createElement('canvas');
canvas.style.position = 'fixed';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.pointerEvents = 'none';
canvas.style.zIndex = zIndex;
return canvas;
}
function ellipse(context, x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise) {
context.save();
context.translate(x, y);
context.rotate(rotation);
context.scale(radiusX, radiusY);
context.arc(0, 0, 1, startAngle, endAngle, antiClockwise);
context.restore();
}
function randomPhysics(opts) {
var radAngle = opts.angle * (Math.PI / 180);
var radSpread = opts.spread * (Math.PI / 180);
return {
x: opts.x,
y: opts.y,
wobble: Math.random() * 10,
wobbleSpeed: Math.min(0.11, Math.random() * 0.1 + 0.05),
velocity: (opts.startVelocity * 0.5) + (Math.random() * opts.startVelocity),
angle2D: -radAngle + ((0.5 * radSpread) - (Math.random() * radSpread)),
tiltAngle: (Math.random() * (0.75 - 0.25) + 0.25) * Math.PI,
color: opts.color,
shape: opts.shape,
tick: 0,
totalTicks: opts.ticks,
decay: opts.decay,
drift: opts.drift,
random: Math.random() + 2,
tiltSin: 0,
tiltCos: 0,
wobbleX: 0,
wobbleY: 0,
gravity: opts.gravity * 3,
ovalScalar: 0.6,
scalar: opts.scalar,
flat: opts.flat
};
}
function updateFetti(context, fetti) {
fetti.x += Math.cos(fetti.angle2D) * fetti.velocity + fetti.drift;
fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity;
fetti.velocity *= fetti.decay;
if (fetti.flat) {
fetti.wobble = 0;
fetti.wobbleX = fetti.x + (10 * fetti.scalar);
fetti.wobbleY = fetti.y + (10 * fetti.scalar);
fetti.tiltSin = 0;
fetti.tiltCos = 0;
fetti.random = 1;
} else {
fetti.wobble += fetti.wobbleSpeed;
fetti.wobbleX = fetti.x + ((10 * fetti.scalar) * Math.cos(fetti.wobble));
fetti.wobbleY = fetti.y + ((10 * fetti.scalar) * Math.sin(fetti.wobble));
fetti.tiltAngle += 0.1;
fetti.tiltSin = Math.sin(fetti.tiltAngle);
fetti.tiltCos = Math.cos(fetti.tiltAngle);
fetti.random = Math.random() + 2;
}
var progress = (fetti.tick++) / fetti.totalTicks;
var x1 = fetti.x + (fetti.random * fetti.tiltCos);
var y1 = fetti.y + (fetti.random * fetti.tiltSin);
var x2 = fetti.wobbleX + (fetti.random * fetti.tiltCos);
var y2 = fetti.wobbleY + (fetti.random * fetti.tiltSin);
context.fillStyle = 'rgba(' + fetti.color.r + ', ' + fetti.color.g + ', ' + fetti.color.b + ', ' + (1 - progress) + ')';
context.beginPath();
if (canUsePaths && fetti.shape.type === 'path' && typeof fetti.shape.path === 'string' && Array.isArray(fetti.shape.matrix)) {
context.fill(transformPath2D(
fetti.shape.path,
fetti.shape.matrix,
fetti.x,
fetti.y,
Math.abs(x2 - x1) * 0.1,
Math.abs(y2 - y1) * 0.1,
Math.PI / 10 * fetti.wobble
));
} else if (fetti.shape.type === 'bitmap') {
var rotation = Math.PI / 10 * fetti.wobble;
var scaleX = Math.abs(x2 - x1) * 0.1;
var scaleY = Math.abs(y2 - y1) * 0.1;
var width = fetti.shape.bitmap.width * fetti.scalar;
var height = fetti.shape.bitmap.height * fetti.scalar;
var matrix = new DOMMatrix([
Math.cos(rotation) * scaleX,
Math.sin(rotation) * scaleX,
-Math.sin(rotation) * scaleY,
Math.cos(rotation) * scaleY,
fetti.x,
fetti.y
]);
// apply the transform matrix from the confetti shape
matrix.multiplySelf(new DOMMatrix(fetti.shape.matrix));
var pattern = context.createPattern(bitmapMapper.transform(fetti.shape.bitmap), 'no-repeat');
pattern.setTransform(matrix);
context.globalAlpha = (1 - progress);
context.fillStyle = pattern;
context.fillRect(
fetti.x - (width / 2),
fetti.y - (height / 2),
width,
height
);
context.globalAlpha = 1;
} else if (fetti.shape === 'circle') {
context.ellipse ?
context.ellipse(fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI) :
ellipse(context, fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI);
} else if (fetti.shape === 'star') {
var rot = Math.PI / 2 * 3;
var innerRadius = 4 * fetti.scalar;
var outerRadius = 8 * fetti.scalar;
var x = fetti.x;
var y = fetti.y;
var spikes = 5;
var step = Math.PI / spikes;
while (spikes--) {
x = fetti.x + Math.cos(rot) * outerRadius;
y = fetti.y + Math.sin(rot) * outerRadius;
context.lineTo(x, y);
rot += step;
x = fetti.x + Math.cos(rot) * innerRadius;
y = fetti.y + Math.sin(rot) * innerRadius;
context.lineTo(x, y);
rot += step;
}
} else {
context.moveTo(Math.floor(fetti.x), Math.floor(fetti.y));
context.lineTo(Math.floor(fetti.wobbleX), Math.floor(y1));
context.lineTo(Math.floor(x2), Math.floor(y2));
context.lineTo(Math.floor(x1), Math.floor(fetti.wobbleY));
}
context.closePath();
context.fill();
return fetti.tick < fetti.totalTicks;
}
function animate(canvas, fettis, resizer, size, done) {
var animatingFettis = fettis.slice();
var context = canvas.getContext('2d');
var animationFrame;
var destroy;
var prom = promise(function (resolve) {
function onDone() {
animationFrame = destroy = null;
context.clearRect(0, 0, size.width, size.height);
bitmapMapper.clear();
done();
resolve();
}
function update() {
if (isWorker && !(size.width === workerSize.width && size.height === workerSize.height)) {
size.width = canvas.width = workerSize.width;
size.height = canvas.height = workerSize.height;
}
if (!size.width && !size.height) {
resizer(canvas);
size.width = canvas.width;
size.height = canvas.height;
}
context.clearRect(0, 0, size.width, size.height);
animatingFettis = animatingFettis.filter(function (fetti) {
return updateFetti(context, fetti);
});
if (animatingFettis.length) {
animationFrame = raf.frame(update);
} else {
onDone();
}
}
animationFrame = raf.frame(update);
destroy = onDone;
});
return {
addFettis: function (fettis) {
animatingFettis = animatingFettis.concat(fettis);
return prom;
},
canvas: canvas,
promise: prom,
reset: function () {
if (animationFrame) {
raf.cancel(animationFrame);
}
if (destroy) {
destroy();
}
}
};
}
function confettiCannon(canvas, globalOpts) {
var isLibCanvas = !canvas;
var allowResize = !!prop(globalOpts || {}, 'resize');
var hasResizeEventRegistered = false;
var globalDisableForReducedMotion = prop(globalOpts, 'disableForReducedMotion', Boolean);
var shouldUseWorker = canUseWorker && !!prop(globalOpts || {}, 'useWorker');
var worker = shouldUseWorker ? getWorker() : null;
var resizer = isLibCanvas ? setCanvasWindowSize : setCanvasRectSize;
var initialized = (canvas && worker) ? !!canvas.__confetti_initialized : false;
var preferLessMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion)').matches;
var animationObj;
function fireLocal(options, size, done) {
var particleCount = prop(options, 'particleCount', onlyPositiveInt);
var angle = prop(options, 'angle', Number);
var spread = prop(options, 'spread', Number);
var startVelocity = prop(options, 'startVelocity', Number);
var decay = prop(options, 'decay', Number);
var gravity = prop(options, 'gravity', Number);
var drift = prop(options, 'drift', Number);
var colors = prop(options, 'colors', colorsToRgb);
var ticks = prop(options, 'ticks', Number);
var shapes = prop(options, 'shapes');
var scalar = prop(options, 'scalar');
var flat = !!prop(options, 'flat');
var origin = getOrigin(options);
var temp = particleCount;
var fettis = [];
var startX = canvas.width * origin.x;
var startY = canvas.height * origin.y;
while (temp--) {
fettis.push(
randomPhysics({
x: startX,
y: startY,
angle: angle,
spread: spread,
startVelocity: startVelocity,
color: colors[temp % colors.length],
shape: shapes[randomInt(0, shapes.length)],
ticks: ticks,
decay: decay,
gravity: gravity,
drift: drift,
scalar: scalar,
flat: flat
})
);
}
// if we have a previous canvas already animating,
// add to it
if (animationObj) {
return animationObj.addFettis(fettis);
}
animationObj = animate(canvas, fettis, resizer, size , done);
return animationObj.promise;
}
function fire(options) {
var disableForReducedMotion = globalDisableForReducedMotion || prop(options, 'disableForReducedMotion', Boolean);
var zIndex = prop(options, 'zIndex', Number);
if (disableForReducedMotion && preferLessMotion) {
return promise(function (resolve) {
resolve();
});
}
if (isLibCanvas && animationObj) {
// use existing canvas from in-progress animation
canvas = animationObj.canvas;
} else if (isLibCanvas && !canvas) {
// create and initialize a new canvas
canvas = getCanvas(zIndex);
document.body.appendChild(canvas);
}
if (allowResize && !initialized) {
// initialize the size of a user-supplied canvas
resizer(canvas);
}
var size = {
width: canvas.width,
height: canvas.height
};
if (worker && !initialized) {
worker.init(canvas);
}
initialized = true;
if (worker) {
canvas.__confetti_initialized = true;
}
function onResize() {
if (worker) {
// TODO this really shouldn't be immediate, because it is expensive
var obj = {
getBoundingClientRect: function () {
if (!isLibCanvas) {
return canvas.getBoundingClientRect();
}
}
};
resizer(obj);
worker.postMessage({
resize: {
width: obj.width,
height: obj.height
}
});
return;
}
// don't actually query the size here, since this
// can execute frequently and rapidly
size.width = size.height = null;
}
function done() {
animationObj = null;
if (allowResize) {
hasResizeEventRegistered = false;
global.removeEventListener('resize', onResize);
}
if (isLibCanvas && canvas) {
if (document.body.contains(canvas)) {
document.body.removeChild(canvas);
}
canvas = null;
initialized = false;
}
}
if (allowResize && !hasResizeEventRegistered) {
hasResizeEventRegistered = true;
global.addEventListener('resize', onResize, false);
}
if (worker) {
return worker.fire(options, size, done);
}
return fireLocal(options, size, done);
}
fire.reset = function () {
if (worker) {
worker.reset();
}
if (animationObj) {
animationObj.reset();
}
};
return fire;
}
// Make default export lazy to defer worker creation until called.
var defaultFire;
function getDefaultFire() {
if (!defaultFire) {
defaultFire = confettiCannon(null, { useWorker: true, resize: true });
}
return defaultFire;
}
function transformPath2D(pathString, pathMatrix, x, y, scaleX, scaleY, rotation) {
var path2d = new Path2D(pathString);
var t1 = new Path2D();
t1.addPath(path2d, new DOMMatrix(pathMatrix));
var t2 = new Path2D();
// see https://developer.mozilla.org/en-US/docs/Web/API/DOMMatrix/DOMMatrix
t2.addPath(t1, new DOMMatrix([
Math.cos(rotation) * scaleX,
Math.sin(rotation) * scaleX,
-Math.sin(rotation) * scaleY,
Math.cos(rotation) * scaleY,
x,
y
]));
return t2;
}
function shapeFromPath(pathData) {
if (!canUsePaths) {
throw new Error('path confetti are not supported in this browser');
}
var path, matrix;
if (typeof pathData === 'string') {
path = pathData;
} else {
path = pathData.path;
matrix = pathData.matrix;
}
var path2d = new Path2D(path);
var tempCanvas = document.createElement('canvas');
var tempCtx = tempCanvas.getContext('2d');
if (!matrix) {
// attempt to figure out the width of the path, up to 1000x1000
var maxSize = 1000;
var minX = maxSize;
var minY = maxSize;
var maxX = 0;
var maxY = 0;
var width, height;
// do some line skipping... this is faster than checking
// every pixel and will be mostly still correct
for (var x = 0; x < maxSize; x += 2) {
for (var y = 0; y < maxSize; y += 2) {
if (tempCtx.isPointInPath(path2d, x, y, 'nonzero')) {
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);
}
}
}
width = maxX - minX;
height = maxY - minY;
var maxDesiredSize = 10;
var scale = Math.min(maxDesiredSize/width, maxDesiredSize/height);
matrix = [
scale, 0, 0, scale,
-Math.round((width/2) + minX) * scale,
-Math.round((height/2) + minY) * scale
];
}
return {
type: 'path',
path: path,
matrix: matrix
};
}
function shapeFromText(textData) {
var text,
scalar = 1,
color = '#000000',
// see https://nolanlawson.com/2022/04/08/the-struggle-of-using-native-emoji-on-the-web/
fontFamily = '"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji", "EmojiOne Color", "Android Emoji", "Twemoji Mozilla", "system emoji", sans-serif';
if (typeof textData === 'string') {
text = textData;
} else {
text = textData.text;
scalar = 'scalar' in textData ? textData.scalar : scalar;
fontFamily = 'fontFamily' in textData ? textData.fontFamily : fontFamily;
color = 'color' in textData ? textData.color : color;
}
// all other confetti are 10 pixels,
// so this pixel size is the de-facto 100% scale confetti
var fontSize = 10 * scalar;
var font = '' + fontSize + 'px ' + fontFamily;
var canvas = new OffscreenCanvas(fontSize, fontSize);
var ctx = canvas.getContext('2d');
ctx.font = font;
var size = ctx.measureText(text);
var width = Math.ceil(size.actualBoundingBoxRight + size.actualBoundingBoxLeft);
var height = Math.ceil(size.actualBoundingBoxAscent + size.actualBoundingBoxDescent);
var padding = 2;
var x = size.actualBoundingBoxLeft + padding;
var y = size.actualBoundingBoxAscent + padding;
width += padding + padding;
height += padding + padding;
canvas = new OffscreenCanvas(width, height);
ctx = canvas.getContext('2d');
ctx.font = font;
ctx.fillStyle = color;
ctx.fillText(text, x, y);
var scale = 1 / scalar;
return {
type: 'bitmap',
// TODO these probably need to be transfered for workers
bitmap: canvas.transferToImageBitmap(),
matrix: [scale, 0, 0, scale, -width * scale / 2, -height * scale / 2]
};
}
module.exports = function() {
return getDefaultFire().apply(this, arguments);
};
module.exports.reset = function() {
getDefaultFire().reset();
};
module.exports.create = confettiCannon;
module.exports.shapeFromPath = shapeFromPath;
module.exports.shapeFromText = shapeFromText;
}((function () {
if (typeof window !== 'undefined') {
return window;
}
if (typeof self !== 'undefined') {
return self;
}
return this || {};
})(), module, false));
// end source content
window.confetti = module.exports;
}(window, {}));
/***/ }),
/***/ "./node_modules/jquery-ui/ui/version.js":
@ -91670,6 +92567,7 @@ __webpack_require__.r(__webpack_exports__);
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/js/snipeit.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/js/snipeit_modals.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./node_modules/canvas-confetti/dist/confetti.browser.js")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./node_modules/admin-lte/build/less/AdminLTE.less")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/less/app.less")))
/******/ __webpack_require__.O(undefined, ["css/dist/skins/skin-black-dark","css/dist/skins/_all-skins","css/build/overrides","css/build/app","css/build/AdminLTE","css/dist/skins/skin-yellow","css/dist/skins/skin-yellow-dark","css/dist/skins/skin-red","css/dist/skins/skin-red-dark","css/dist/skins/skin-purple","css/dist/skins/skin-purple-dark","css/dist/skins/skin-orange","css/dist/skins/skin-orange-dark","css/dist/skins/skin-green","css/dist/skins/skin-green-dark","css/dist/skins/skin-contrast","css/dist/skins/skin-blue","css/dist/skins/skin-blue-dark","css/dist/skins/skin-black"], () => (__webpack_require__("./resources/assets/less/overrides.less")))

View file

@ -1,5 +1,5 @@
{
"/js/build/app.js": "/js/build/app.js?id=da3f7fee4a180ba924f6a3920c94eb71",
"/js/build/app.js": "/js/build/app.js?id=5030f4cb69d0d0b87b7fe6ba1b9eece9",
"/css/dist/skins/skin-black-dark.css": "/css/dist/skins/skin-black-dark.css?id=f0b08873a06bb54daeee176a9459f4a9",
"/css/dist/skins/_all-skins.css": "/css/dist/skins/_all-skins.css?id=f4397c717b99fce41a633ca6edd5d1f4",
"/css/build/overrides.css": "/css/build/overrides.css?id=a759aa24710e294392877c5139fda40e",
@ -111,5 +111,5 @@
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=8abbb6aea625ec64cd7ebdad77ebf6e5",
"/js/build/vendor.js": "/js/build/vendor.js?id=c1c24b883f48dc3d16b817aed0b457cc",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=859e11e4e6b05c84e4b7302de29bac5e",
"/js/dist/all.js": "/js/dist/all.js?id=ea6fb4f01f01c2194310403dafc1658f"
"/js/dist/all.js": "/js/dist/all.js?id=05654cea82a7a1b78cb20e449d004268"
}

View file

@ -13,4 +13,5 @@ return array(
'profile_updated' => 'Account successfully updated',
'no_tokens' => 'You have not created any personal access tokens.',
'enable_sounds' => 'Enable sound effects',
'enable_confetti' => 'Enable confetti effects',
);

View file

@ -89,15 +89,24 @@
</div>
</div>
<div class="form-group{{ $errors->has('enable_sounds') ? ' has-error' : '' }}">
<div class="form-group">
<div class="col-md-9 col-md-offset-3">
<label for="enable_sounds" class="form-control">
<label class="form-control">
<input type="checkbox" name="enable_sounds" value="1" {{ old('enable_sounds', $user->enable_sounds) ? 'checked' : '' }}>
{{ trans('account/general.enable_sounds') }}
</label>
</div>
</div>
<div class="form-group">
<div class="col-md-9 col-md-offset-3">
<label class="form-control">
<input type="checkbox" name="enable_confetti" value="1" {{ old('enable_confetti', $user->enable_confetti) ? 'checked' : '' }}>
{{ trans('account/general.enable_confetti') }}
</label>
</div>
</div>
<!-- Gravatar Email -->
<div class="form-group {{ $errors->has('gravatar') ? ' has-error' : '' }}">
<label for="gravatar" class="col-md-3 control-label">{{ trans('general.gravatar_email') }}

View file

@ -32,6 +32,7 @@
{{ $message }}
</div>
</div>
@include ('partials.confetti-js')
@endif
@ -44,6 +45,7 @@
{!! $message !!}
</div>
</div>
@include ('partials.confetti-js')
@endif

View file

@ -0,0 +1,25 @@
@if (auth()->user() && auth()->user()->enable_confetti=='1')
<script>
var duration = 1500;
var animationEnd = Date.now() + duration;
var defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
function randomInRange(min, max) {
return Math.random() * (max - min) + min;
}
var interval = setInterval(function() {
var timeLeft = animationEnd - Date.now();
if (timeLeft <= 0) {
return clearInterval(interval);
}
var particleCount = 50 * (timeLeft / duration);
// since particles fall down, start a bit higher than random
confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 } });
confetti({ ...defaults, particleCount, origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 } });
}, 250);
</script>
@endif

View file

@ -65,6 +65,7 @@ mix
[
"./resources/assets/js/snipeit.js", //this is the actual Snipe-IT JS - require()s bootstrap.js
"./resources/assets/js/snipeit_modals.js",
"./node_modules/canvas-confetti/dist/confetti.browser.js",
],
"./public/js/build/app.js" //because of compiling - this does not work very well :(
)