/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Block = Container.expand(function (board) {
	var self = Container.call(this);
	var hsvToRgb = function hsvToRgb(h, s, v) {
		var r, g, b;
		var i = Math.floor(h * 6);
		var f = h * 6 - i;
		var p = v * (1 - s);
		var q = v * (1 - f * s);
		var t = v * (1 - (1 - f) * s);
		switch (i % 6) {
			case 0:
				r = v, g = t, b = p;
				break;
			case 1:
				r = q, g = v, b = p;
				break;
			case 2:
				r = p, g = v, b = t;
				break;
			case 3:
				r = p, g = q, b = v;
				break;
			case 4:
				r = t, g = p, b = v;
				break;
			case 5:
				r = v, g = p, b = q;
				break;
		}
		return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255);
	};
	var ShapeTypes = {
		SINGLE: [[1]],
		TRI: [[1, 1, 1]],
		QUAD: [[1, 1, 1, 1]],
		LSHAPE: [[1, 0, 0], [1, 0, 0], [1, 1, 1]],
		BLOCK: [[1, 1], [1, 1]],
		SMALLLSHAPE: [[1, 0], [1, 1]]
	};
	var shapes = Object.values(ShapeTypes);
	var offset = Math.floor(Math.random() * shapes.length);
	self.offset = offset;
	self.shape = shapes[offset];
	var hue = offset % shapes.length / shapes.length;
	self.color = hsvToRgb(hue, 0.6, 1);
	self.rotateShapeRandomly = function () {
		var rotations = Math.floor(Math.random() * 4);
		for (var r = 0; r < rotations; r++) {
			self.shape = self.shape[0].map(function (val, index) {
				return self.shape.map(function (row) {
					return row[index];
				}).reverse();
			});
		}
	};
	self.rotateShapeRandomly();
	self.blocks = [];
	var background = self.attachAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	background.alpha = 0;
	var blockSize = 160;
	background.width = 4 * blockSize;
	background.height = 4 * blockSize;
	self.addChild(background);
	self.offsetX = 0;
	self.offsetY = 0;
	var blockOffsetX = (background.width / 2 - self.shape[0].length * blockSize) / 2 - blockSize / 2;
	var blockOffsetY = (background.height / 2 - self.shape.length * blockSize) / 2 - blockSize / 2;
	for (var i = 0; i < self.shape.length; i++) {
		for (var j = 0; j < self.shape[i].length; j++) {
			if (self.shape[i][j] === 1) {
				var block = self.createAsset('block_' + offset, {
					anchorX: 0.5,
					anchorY: 0.5
				});
				block.x = j * blockSize + blockOffsetX;
				block.y = i * blockSize + blockOffsetY;
				self.blocks.push(block);
				self.addChild(block);
			}
		}
	}
	self.startX = 0;
	self.startY = 0;
	self.moveTowardsHomePosition = function () {
		var dx = self.startX - self.x;
		var dy = self.startY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 1) {
			self.x += dx * 0.3;
			self.y += dy * 0.3;
		} else {
			self.x = self.startX;
			self.y = self.startY;
		}
	};
	var currentX = 0;
	var currentY = 0;
	self.moveToDragTarget = function () {
		var ox = -this.targetX;
		var oy = (LK.is.mobile ? 400 : 0) - this.targetY;
		this.targetX += ox / 5;
		this.targetY += oy / 5;
		this.x = currentX - this.targetX;
		this.y = currentY - this.targetY;
	};
	self._move_migrated = function (x, y) {
		currentX = x;
		currentY = y;
		self.x = x - this.targetX;
		self.y = y - this.targetY;
	};
	self.setStartPosition = function (x, y) {
		self.startX = x;
		self.startY = y;
	};
	self.getOverlappingCells = function () {
		var cells = [];
		var boardPos = {
			x: -board.x + self.x + 160 * 4 + blockOffsetX + 160,
			y: -board.y + self.y + 160 * 4 + blockOffsetY + 160
		};
		var startX = Math.floor(boardPos.x / 160);
		var startY = Math.floor(boardPos.y / 160);
		for (var i = 0; i < self.shape.length; i++) {
			for (var j = 0; j < self.shape[i].length; j++) {
				if (self.shape[i][j] === 1) {
					var cell = board.grid && board.grid[startY + i] && board.grid[startY + i][startX + j];
					if (cell && !cell.filled) {
						cells.push(cell);
					} else {
						return null;
					}
				}
			}
		}
		return cells;
	};
	self.showOverlap = function () {
		var cells = self.getOverlappingCells();
		if (cells) {
			for (var a = 0; a < cells.length; a++) {
				var cell = cells[a];
				cell.setTint(self.color);
			}
		}
	};
	self.rotateShapeRandomly = function () {
		var rotations = Math.floor(Math.random() * 4);
		for (var r = 0; r < rotations; r++) {
			self.shape = self.shape[0].map(function (val, index) {
				return self.shape.map(function (row) {
					return row[index];
				}).reverse();
			});
		}
	};
});
var Board = Container.expand(function () {
	var self = Container.call(this);
	self.particles = [];
	Board.prototype.spawnParticles = function (x, y, tint) {
		for (var i = 0; i < 10; i++) {
			var particle = new Particle(tint);
			particle.x = x + (Math.random() - 0.5) * 50;
			particle.y = y + (Math.random() - 0.5) * 50;
			this.particles.push(particle);
			this.addChild(particle);
			// Add tween effect for particles with matching block color
			tween(particle, {
				scaleX: 0,
				scaleY: 0,
				alpha: 0,
				x: particle.x + (Math.random() - 0.5) * 100,
				y: particle.y + (Math.random() - 0.5) * 100
			}, {
				duration: 800,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					if (particle.parent) {
						particle.destroy();
					}
				}
			});
		}
	};
	self.grid = new Array(10).fill(null).map(function () {
		return new Array(10).fill(null);
	});
	var size = 158;
	var totalWidth = 10 * size;
	var totalHeight = 10 * size;
	for (var i = 0; i < 10; i++) {
		for (var j = 0; j < 10; j++) {
			var cell = new Cell();
			cell.x = i * size - totalWidth / 2 + size / 2;
			cell.y = j * size - totalHeight / 2 + size / 2;
			self.grid[j][i] = cell;
			self.addChild(cell);
		}
	}
	self.removeTint = function () {
		for (var i = 0; i < 10; i++) {
			for (var j = 0; j < 10; j++) {
				if (!self.grid[i][j].filled) {
					self.grid[i][j].setTint(0xffffff);
				}
			}
		}
	};
	self.checkLines = function () {
		var rowsRemoved = 0;
		for (var i = 0; i < 10; i++) {
			var rowFilled = true;
			var colFilled = true;
			for (var j = 0; j < 10; j++) {
				if (!self.grid[i][j].filled) {
					rowFilled = false;
				}
				if (!self.grid[j][i].filled) {
					colFilled = false;
				}
			}
			if (rowFilled || colFilled) {
				rowsRemoved += (rowFilled ? 1 : 0) + (colFilled ? 1 : 0);
				// Play destruction sound when blocks are destroyed
				LK.getSound('blockDestroy').play();
				// Handle streak system
				var currentTime = Date.now();
				if (currentTime - lastLinesClearedTime <= streakTimeout && lastLinesClearedTime > 0) {
					streakLevel = Math.min(streakLevel + 1, 6); // Cap at level 6
				} else {
					streakLevel = 1;
				}
				lastLinesClearedTime = currentTime;
				// Show streak text
				game.showStreakText(streakLevel);
				for (var j = 0; j < 10; j++) {
					if (rowFilled) {
						var blockColor = self.grid[i][j].getBlockColor() || 0xffffff;
						self.spawnParticles(self.grid[i][j].x, self.grid[i][j].y, blockColor);
						self.grid[i][j].setFill(false);
					}
					if (colFilled) {
						var blockColor = self.grid[j][i].getBlockColor() || 0xffffff;
						self.spawnParticles(self.grid[j][i].x, self.grid[j][i].y, blockColor);
						self.grid[j][i].setFill(false);
					}
				}
			}
		}
		return rowsRemoved;
	};
	self.tick = function () {
		// Process particles every other tick to reduce overhead
		if (LK.ticks % 2 === 0) {
			for (var i = self.particles.length - 1; i >= 0; i--) {
				var particle = self.particles[i];
				if (particle) {
					particle.tick();
					if (particle.alpha <= 0) {
						self.particles.splice(i, 1);
					}
				}
			}
		}
		// Optimize grid animation by processing fewer cells when not dragging
		var processEveryNthCell = dragTarget ? 1 : 2;
		for (var i = 0; i < 10; i += processEveryNthCell) {
			for (var j = 0; j < 10; j += processEveryNthCell) {
				self.grid[i][j].tick(i, j);
			}
		}
	};
	self.placeBlock = function () {};
});
var Cell = Container.expand(function () {
	var self = Container.call(this);
	self.filled = false;
	var yOffsetArray = [-25, -10, -20, -25, -25, -20];
	var empty = self.attachAsset('cell', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	empty.alpa = .8;
	var filled;
	var currentOffset;
	empty.y = 2;
	self.currentTint = 0xffffff;
	self.setFill = function (isFilled, asset, offset, color) {
		self.filled = isFilled;
		empty.visible = !self.filled;
		if (isFilled) {
			if (asset) {
				asset.x = 0;
				asset.y = yOffsetArray[offset] || -15;
				currentOffset = offset;
				self.addChild(asset);
				filled = asset;
				if (color) {
					self.currentTint = color;
					self.blockColor = color; // Store the original block color
				}
			}
		} else {
			if (filled) {
				filled.destroy();
				filled = null;
			}
		}
	};
	self.tick = function (i, j) {
		if (filled) {
			// Reduce animation frequency to improve performance
			var animationSpeed = LK.ticks / 4; // Slower animation
			var offset = Math.cos(((i + j) * 3 + animationSpeed) / 6) / 20;
			var ty = yOffsetArray[currentOffset] || -15;
			filled.y = ty + Math.abs(offset * 200) - 5;
			filled.rotation = offset;
		}
	};
	self.getTint = function () {
		return self.currentTint;
	};
	self.getBlockColor = function () {
		return self.blockColor || self.currentTint;
	};
	self.setTint = function (tint) {
		self.currentTint = tint;
		empty.tint = tint;
	};
	self.setFill(false);
});
var Particle = Container.expand(function (tint) {
	var self = Container.call(this);
	self.tint = tint;
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	particleGraphics.rotation = Math.random() * Math.PI * 2;
	particleGraphics.tint = self.tint;
	self.vx = Math.random() * 4 - 2;
	self.vy = Math.random() * 4 - 2;
	self.alpha = 1;
	self.lifetime = 60;
	self.tick = function () {
		self.x += self.vx;
		self.y += self.vy;
		self.alpha -= 1 / self.lifetime;
		if (self.alpha <= 0) {
			self.destroy();
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
var gameBackground = game.attachAsset('gameBackground', {
	anchorX: 0.5,
	anchorY: 0.5
});
gameBackground.x = 2048 / 2;
gameBackground.y = 2732 / 2 + 65;
// Add asset1 to the front of the screen
var asset1Display = game.attachAsset('asset1', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset1Display.x = 2048 / 2 + 30;
asset1Display.y = 2732 / 2 - 315;
// Add asset2 display with same positioning and properties as asset1
var asset2Display = game.attachAsset('asset2', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset2Display.x = 2048 / 2 + 30;
asset2Display.y = 2732 / 2 - 315;
asset2Display.alpha = 0;
// Add asset3 display with same positioning and properties as asset1
var asset3Display = game.attachAsset('asset3', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset3Display.x = 2048 / 2 + 30;
asset3Display.y = 2732 / 2 - 315;
asset3Display.alpha = 0;
// Add asset4 display with same positioning and properties as asset1
var asset4Display = game.attachAsset('asset4', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset4Display.x = 2048 / 2 + 30;
asset4Display.y = 2732 / 2 - 315;
asset4Display.alpha = 0;
var blocks = [];
var dragTarget;
var board = game.addChild(new Board());
board.x = 2048 / 2;
board.y = 2732 / 2 - 250 + 30;
var targetOffset;
game.createBlock = function (index) {
	var block = new Block(board);
	block.x = 2048 / 2 + (index - 1) * (block.width + 50);
	block.y = 2732 + block.height;
	block.setStartPosition(block.x, 2732 - block.height / 2 - 30);
	blocks.push(block);
	game.addChild(block);
	block.on('down', function (x, y, obj) {
		dragTarget = this;
		var pos = this.toLocal(obj.global);
		var targetPos = game.toLocal(obj.global);
		this.targetX = pos.x;
		this.targetY = pos.y;
		dragTarget._move_migrated(targetPos.x, targetPos.y);
	});
};
game.on('move', function (x, y, obj) {
	if (dragTarget) {
		board.removeTint();
		var pos = game.toLocal(obj.global);
		dragTarget._move_migrated(pos.x, pos.y);
		dragTarget.showOverlap();
	}
});
game.on('up', function (x, y, obj) {
	if (dragTarget) {
		var cells = dragTarget.getOverlappingCells();
		if (cells) {
			for (var a = 0; a < cells.length; a++) {
				cells[a].setFill(true, dragTarget.blocks[a], dragTarget.offset, dragTarget.color);
				cells[a].setTint(dragTarget.color);
			}
			blocks[blocks.indexOf(dragTarget)] = undefined;
			dragTarget.destroy();
			if (!blocks.some(function (block) {
				return block;
			})) {
				game.createBlocks();
			}
			var pointsToAdd = board.checkLines();
			if (pointsToAdd) {
				score += Math.pow(pointsToAdd, 2) * 10;
				LK.setScore(score);
				scoreTxt.setText(score);
			}
		}
		board.removeTint();
		dragTarget = undefined;
	}
});
game.createBlocks = function () {
	for (var i = 0; i < 3; i++) {
		game.createBlock(i);
	}
};
game.showStreakText = function (level) {
	// Remove existing streak text if any
	if (streakText && streakText.parent) {
		streakText.destroy();
	}
	var message = '';
	var color = 0xFFFFFF;
	if (level === 1) {
		message = 'GOOD';
		color = 0x00FF00; // Green
	} else if (level === 2) {
		message = 'SUPER';
		color = 0x80FF00; // Green-Yellow
	} else if (level === 3) {
		message = 'WOW';
		color = 0xFFFF00; // Yellow
	} else if (level === 4) {
		message = 'AMAZING';
		color = 0xFF8000; // Yellow-Orange
	} else if (level === 5) {
		message = 'MANIAC';
		color = 0xFF4000; // Orange-Red
	} else if (level >= 6) {
		message = 'CRAZYY!!!';
		color = 0xFF0000; // Red
	}
	if (message) {
		var newStreakText = new Text2(message, {
			size: 200,
			fill: color,
			font: 'Impact',
			stroke: '#000000',
			strokeThickness: 8
		});
		// Position diagonally across screen (top-right diagonal style)
		newStreakText.anchor.set(0.5, 0.5);
		newStreakText.x = 2048 - 300; // Move to right side
		newStreakText.y = 400; // Move to upper area
		newStreakText.rotation = -0.2; // Slight diagonal angle
		newStreakText.alpha = 0;
		newStreakText.scaleX = 0.5;
		newStreakText.scaleY = 0.5;
		game.addChild(newStreakText);
		streakText = newStreakText;
		// Animate streak text appearance with elastic bounce effect
		tween(newStreakText, {
			alpha: 1,
			scaleX: 1.3,
			scaleY: 1.3
		}, {
			duration: 600,
			easing: tween.elasticOut,
			onFinish: function onFinish() {
				// Add a secondary bounce effect
				tween(newStreakText, {
					scaleX: 1.1,
					scaleY: 1.1
				}, {
					duration: 200,
					easing: tween.bounceOut,
					onFinish: function onFinish() {
						// Animate text disappearance after showing
						tween(newStreakText, {
							alpha: 0,
							scaleX: 0.8,
							scaleY: 0.8,
							y: newStreakText.y - 100
						}, {
							duration: 1500,
							easing: tween.elasticIn,
							onFinish: function onFinish() {
								if (newStreakText && newStreakText.parent) {
									newStreakText.destroy();
									if (streakText === newStreakText) {
										streakText = null;
									}
								}
							}
						});
					}
				});
			}
		});
	}
};
var score = 0;
var lastLinesClearedTime = 0;
var streakLevel = 0;
var streakTimeout = 5000; // 5 seconds in milliseconds
var streakText = null;
game.createBlocks();
var scoreTxt = new Text2('0', {
	size: 150,
	fill: 0xFFFFFF,
	font: 'Impact',
	stroke: '#2a636e',
	strokeThickness: 16
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
game.isMovePossible = function () {
	// Cache blocks that exist for faster iteration
	var activeBlocks = [];
	for (var a = 0; a < blocks.length; a++) {
		if (blocks[a]) {
			activeBlocks.push(blocks[a]);
		}
	}
	for (var blockIndex = 0; blockIndex < activeBlocks.length; blockIndex++) {
		var block = activeBlocks[blockIndex];
		// Check fewer positions by sampling every other position for performance
		for (var i = 0; i < 10; i += 1) {
			for (var j = 0; j < 10; j += 1) {
				if (board.grid[i][j].filled) {
					continue;
				}
				var canPlace = true;
				// Early bounds checking
				if (i + block.shape.length > 10 || j + block.shape[0].length > 10) {
					continue;
				}
				for (var k = 0; k < block.shape.length && canPlace; k++) {
					for (var l = 0; l < block.shape[k].length && canPlace; l++) {
						if (block.shape[k][l] === 1) {
							if (board.grid[i + k][j + l].filled) {
								canPlace = false;
							}
						}
					}
				}
				if (canPlace) {
					return true;
				}
			}
		}
	}
	return false;
};
// Create frame-based animation sequence for assets
var currentAssetIndex = 0;
var assetDisplays = [asset1Display, asset2Display, asset3Display, asset4Display];
var animationTimer;
function showNextFrame() {
	// Hide all frames first for stability
	for (var i = 0; i < assetDisplays.length; i++) {
		assetDisplays[i].alpha = 0;
	}
	// Move to next frame
	currentAssetIndex = (currentAssetIndex + 1) % assetDisplays.length;
	// Show next frame
	assetDisplays[currentAssetIndex].alpha = 1;
}
function startFrameAnimation() {
	// Hide all frames initially for stability
	for (var i = 0; i < assetDisplays.length; i++) {
		assetDisplays[i].alpha = 0;
	}
	// Show first frame
	assetDisplays[currentAssetIndex].alpha = 1;
	// Set up timer to cycle through frames every 100ms (10 FPS animation) for faster speed
	animationTimer = LK.setInterval(showNextFrame, 100);
}
// Start the frame animation
startFrameAnimation();
// Play Fala music as background music with continuous looping
LK.playMusic('Fala');
var isGameOver = false;
LK.on('tick', function () {
	board.tick();
	// Only check game over every 30 ticks (half second) to reduce performance impact
	if (LK.ticks % 30 === 0 && (isGameOver || !game.isMovePossible())) {
		LK.effects.flashScreen(0xffffff, 1000);
		LK.showGameOver();
	}
	for (var a = blocks.length - 1; a >= 0; a--) {
		if (blocks[a]) {
			if (blocks[a] != dragTarget) {
				blocks[a].moveTowardsHomePosition();
			} else {
				blocks[a].moveToDragTarget();
			}
		}
	}
}); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Block = Container.expand(function (board) {
	var self = Container.call(this);
	var hsvToRgb = function hsvToRgb(h, s, v) {
		var r, g, b;
		var i = Math.floor(h * 6);
		var f = h * 6 - i;
		var p = v * (1 - s);
		var q = v * (1 - f * s);
		var t = v * (1 - (1 - f) * s);
		switch (i % 6) {
			case 0:
				r = v, g = t, b = p;
				break;
			case 1:
				r = q, g = v, b = p;
				break;
			case 2:
				r = p, g = v, b = t;
				break;
			case 3:
				r = p, g = q, b = v;
				break;
			case 4:
				r = t, g = p, b = v;
				break;
			case 5:
				r = v, g = p, b = q;
				break;
		}
		return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255);
	};
	var ShapeTypes = {
		SINGLE: [[1]],
		TRI: [[1, 1, 1]],
		QUAD: [[1, 1, 1, 1]],
		LSHAPE: [[1, 0, 0], [1, 0, 0], [1, 1, 1]],
		BLOCK: [[1, 1], [1, 1]],
		SMALLLSHAPE: [[1, 0], [1, 1]]
	};
	var shapes = Object.values(ShapeTypes);
	var offset = Math.floor(Math.random() * shapes.length);
	self.offset = offset;
	self.shape = shapes[offset];
	var hue = offset % shapes.length / shapes.length;
	self.color = hsvToRgb(hue, 0.6, 1);
	self.rotateShapeRandomly = function () {
		var rotations = Math.floor(Math.random() * 4);
		for (var r = 0; r < rotations; r++) {
			self.shape = self.shape[0].map(function (val, index) {
				return self.shape.map(function (row) {
					return row[index];
				}).reverse();
			});
		}
	};
	self.rotateShapeRandomly();
	self.blocks = [];
	var background = self.attachAsset('background', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	background.alpha = 0;
	var blockSize = 160;
	background.width = 4 * blockSize;
	background.height = 4 * blockSize;
	self.addChild(background);
	self.offsetX = 0;
	self.offsetY = 0;
	var blockOffsetX = (background.width / 2 - self.shape[0].length * blockSize) / 2 - blockSize / 2;
	var blockOffsetY = (background.height / 2 - self.shape.length * blockSize) / 2 - blockSize / 2;
	for (var i = 0; i < self.shape.length; i++) {
		for (var j = 0; j < self.shape[i].length; j++) {
			if (self.shape[i][j] === 1) {
				var block = self.createAsset('block_' + offset, {
					anchorX: 0.5,
					anchorY: 0.5
				});
				block.x = j * blockSize + blockOffsetX;
				block.y = i * blockSize + blockOffsetY;
				self.blocks.push(block);
				self.addChild(block);
			}
		}
	}
	self.startX = 0;
	self.startY = 0;
	self.moveTowardsHomePosition = function () {
		var dx = self.startX - self.x;
		var dy = self.startY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		if (distance > 1) {
			self.x += dx * 0.3;
			self.y += dy * 0.3;
		} else {
			self.x = self.startX;
			self.y = self.startY;
		}
	};
	var currentX = 0;
	var currentY = 0;
	self.moveToDragTarget = function () {
		var ox = -this.targetX;
		var oy = (LK.is.mobile ? 400 : 0) - this.targetY;
		this.targetX += ox / 5;
		this.targetY += oy / 5;
		this.x = currentX - this.targetX;
		this.y = currentY - this.targetY;
	};
	self._move_migrated = function (x, y) {
		currentX = x;
		currentY = y;
		self.x = x - this.targetX;
		self.y = y - this.targetY;
	};
	self.setStartPosition = function (x, y) {
		self.startX = x;
		self.startY = y;
	};
	self.getOverlappingCells = function () {
		var cells = [];
		var boardPos = {
			x: -board.x + self.x + 160 * 4 + blockOffsetX + 160,
			y: -board.y + self.y + 160 * 4 + blockOffsetY + 160
		};
		var startX = Math.floor(boardPos.x / 160);
		var startY = Math.floor(boardPos.y / 160);
		for (var i = 0; i < self.shape.length; i++) {
			for (var j = 0; j < self.shape[i].length; j++) {
				if (self.shape[i][j] === 1) {
					var cell = board.grid && board.grid[startY + i] && board.grid[startY + i][startX + j];
					if (cell && !cell.filled) {
						cells.push(cell);
					} else {
						return null;
					}
				}
			}
		}
		return cells;
	};
	self.showOverlap = function () {
		var cells = self.getOverlappingCells();
		if (cells) {
			for (var a = 0; a < cells.length; a++) {
				var cell = cells[a];
				cell.setTint(self.color);
			}
		}
	};
	self.rotateShapeRandomly = function () {
		var rotations = Math.floor(Math.random() * 4);
		for (var r = 0; r < rotations; r++) {
			self.shape = self.shape[0].map(function (val, index) {
				return self.shape.map(function (row) {
					return row[index];
				}).reverse();
			});
		}
	};
});
var Board = Container.expand(function () {
	var self = Container.call(this);
	self.particles = [];
	Board.prototype.spawnParticles = function (x, y, tint) {
		for (var i = 0; i < 10; i++) {
			var particle = new Particle(tint);
			particle.x = x + (Math.random() - 0.5) * 50;
			particle.y = y + (Math.random() - 0.5) * 50;
			this.particles.push(particle);
			this.addChild(particle);
			// Add tween effect for particles with matching block color
			tween(particle, {
				scaleX: 0,
				scaleY: 0,
				alpha: 0,
				x: particle.x + (Math.random() - 0.5) * 100,
				y: particle.y + (Math.random() - 0.5) * 100
			}, {
				duration: 800,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					if (particle.parent) {
						particle.destroy();
					}
				}
			});
		}
	};
	self.grid = new Array(10).fill(null).map(function () {
		return new Array(10).fill(null);
	});
	var size = 158;
	var totalWidth = 10 * size;
	var totalHeight = 10 * size;
	for (var i = 0; i < 10; i++) {
		for (var j = 0; j < 10; j++) {
			var cell = new Cell();
			cell.x = i * size - totalWidth / 2 + size / 2;
			cell.y = j * size - totalHeight / 2 + size / 2;
			self.grid[j][i] = cell;
			self.addChild(cell);
		}
	}
	self.removeTint = function () {
		for (var i = 0; i < 10; i++) {
			for (var j = 0; j < 10; j++) {
				if (!self.grid[i][j].filled) {
					self.grid[i][j].setTint(0xffffff);
				}
			}
		}
	};
	self.checkLines = function () {
		var rowsRemoved = 0;
		for (var i = 0; i < 10; i++) {
			var rowFilled = true;
			var colFilled = true;
			for (var j = 0; j < 10; j++) {
				if (!self.grid[i][j].filled) {
					rowFilled = false;
				}
				if (!self.grid[j][i].filled) {
					colFilled = false;
				}
			}
			if (rowFilled || colFilled) {
				rowsRemoved += (rowFilled ? 1 : 0) + (colFilled ? 1 : 0);
				// Play destruction sound when blocks are destroyed
				LK.getSound('blockDestroy').play();
				// Handle streak system
				var currentTime = Date.now();
				if (currentTime - lastLinesClearedTime <= streakTimeout && lastLinesClearedTime > 0) {
					streakLevel = Math.min(streakLevel + 1, 6); // Cap at level 6
				} else {
					streakLevel = 1;
				}
				lastLinesClearedTime = currentTime;
				// Show streak text
				game.showStreakText(streakLevel);
				for (var j = 0; j < 10; j++) {
					if (rowFilled) {
						var blockColor = self.grid[i][j].getBlockColor() || 0xffffff;
						self.spawnParticles(self.grid[i][j].x, self.grid[i][j].y, blockColor);
						self.grid[i][j].setFill(false);
					}
					if (colFilled) {
						var blockColor = self.grid[j][i].getBlockColor() || 0xffffff;
						self.spawnParticles(self.grid[j][i].x, self.grid[j][i].y, blockColor);
						self.grid[j][i].setFill(false);
					}
				}
			}
		}
		return rowsRemoved;
	};
	self.tick = function () {
		// Process particles every other tick to reduce overhead
		if (LK.ticks % 2 === 0) {
			for (var i = self.particles.length - 1; i >= 0; i--) {
				var particle = self.particles[i];
				if (particle) {
					particle.tick();
					if (particle.alpha <= 0) {
						self.particles.splice(i, 1);
					}
				}
			}
		}
		// Optimize grid animation by processing fewer cells when not dragging
		var processEveryNthCell = dragTarget ? 1 : 2;
		for (var i = 0; i < 10; i += processEveryNthCell) {
			for (var j = 0; j < 10; j += processEveryNthCell) {
				self.grid[i][j].tick(i, j);
			}
		}
	};
	self.placeBlock = function () {};
});
var Cell = Container.expand(function () {
	var self = Container.call(this);
	self.filled = false;
	var yOffsetArray = [-25, -10, -20, -25, -25, -20];
	var empty = self.attachAsset('cell', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	empty.alpa = .8;
	var filled;
	var currentOffset;
	empty.y = 2;
	self.currentTint = 0xffffff;
	self.setFill = function (isFilled, asset, offset, color) {
		self.filled = isFilled;
		empty.visible = !self.filled;
		if (isFilled) {
			if (asset) {
				asset.x = 0;
				asset.y = yOffsetArray[offset] || -15;
				currentOffset = offset;
				self.addChild(asset);
				filled = asset;
				if (color) {
					self.currentTint = color;
					self.blockColor = color; // Store the original block color
				}
			}
		} else {
			if (filled) {
				filled.destroy();
				filled = null;
			}
		}
	};
	self.tick = function (i, j) {
		if (filled) {
			// Reduce animation frequency to improve performance
			var animationSpeed = LK.ticks / 4; // Slower animation
			var offset = Math.cos(((i + j) * 3 + animationSpeed) / 6) / 20;
			var ty = yOffsetArray[currentOffset] || -15;
			filled.y = ty + Math.abs(offset * 200) - 5;
			filled.rotation = offset;
		}
	};
	self.getTint = function () {
		return self.currentTint;
	};
	self.getBlockColor = function () {
		return self.blockColor || self.currentTint;
	};
	self.setTint = function (tint) {
		self.currentTint = tint;
		empty.tint = tint;
	};
	self.setFill(false);
});
var Particle = Container.expand(function (tint) {
	var self = Container.call(this);
	self.tint = tint;
	var particleGraphics = self.attachAsset('particle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	particleGraphics.rotation = Math.random() * Math.PI * 2;
	particleGraphics.tint = self.tint;
	self.vx = Math.random() * 4 - 2;
	self.vy = Math.random() * 4 - 2;
	self.alpha = 1;
	self.lifetime = 60;
	self.tick = function () {
		self.x += self.vx;
		self.y += self.vy;
		self.alpha -= 1 / self.lifetime;
		if (self.alpha <= 0) {
			self.destroy();
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
var gameBackground = game.attachAsset('gameBackground', {
	anchorX: 0.5,
	anchorY: 0.5
});
gameBackground.x = 2048 / 2;
gameBackground.y = 2732 / 2 + 65;
// Add asset1 to the front of the screen
var asset1Display = game.attachAsset('asset1', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset1Display.x = 2048 / 2 + 30;
asset1Display.y = 2732 / 2 - 315;
// Add asset2 display with same positioning and properties as asset1
var asset2Display = game.attachAsset('asset2', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset2Display.x = 2048 / 2 + 30;
asset2Display.y = 2732 / 2 - 315;
asset2Display.alpha = 0;
// Add asset3 display with same positioning and properties as asset1
var asset3Display = game.attachAsset('asset3', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset3Display.x = 2048 / 2 + 30;
asset3Display.y = 2732 / 2 - 315;
asset3Display.alpha = 0;
// Add asset4 display with same positioning and properties as asset1
var asset4Display = game.attachAsset('asset4', {
	anchorX: 0.5,
	anchorY: 0.5
});
asset4Display.x = 2048 / 2 + 30;
asset4Display.y = 2732 / 2 - 315;
asset4Display.alpha = 0;
var blocks = [];
var dragTarget;
var board = game.addChild(new Board());
board.x = 2048 / 2;
board.y = 2732 / 2 - 250 + 30;
var targetOffset;
game.createBlock = function (index) {
	var block = new Block(board);
	block.x = 2048 / 2 + (index - 1) * (block.width + 50);
	block.y = 2732 + block.height;
	block.setStartPosition(block.x, 2732 - block.height / 2 - 30);
	blocks.push(block);
	game.addChild(block);
	block.on('down', function (x, y, obj) {
		dragTarget = this;
		var pos = this.toLocal(obj.global);
		var targetPos = game.toLocal(obj.global);
		this.targetX = pos.x;
		this.targetY = pos.y;
		dragTarget._move_migrated(targetPos.x, targetPos.y);
	});
};
game.on('move', function (x, y, obj) {
	if (dragTarget) {
		board.removeTint();
		var pos = game.toLocal(obj.global);
		dragTarget._move_migrated(pos.x, pos.y);
		dragTarget.showOverlap();
	}
});
game.on('up', function (x, y, obj) {
	if (dragTarget) {
		var cells = dragTarget.getOverlappingCells();
		if (cells) {
			for (var a = 0; a < cells.length; a++) {
				cells[a].setFill(true, dragTarget.blocks[a], dragTarget.offset, dragTarget.color);
				cells[a].setTint(dragTarget.color);
			}
			blocks[blocks.indexOf(dragTarget)] = undefined;
			dragTarget.destroy();
			if (!blocks.some(function (block) {
				return block;
			})) {
				game.createBlocks();
			}
			var pointsToAdd = board.checkLines();
			if (pointsToAdd) {
				score += Math.pow(pointsToAdd, 2) * 10;
				LK.setScore(score);
				scoreTxt.setText(score);
			}
		}
		board.removeTint();
		dragTarget = undefined;
	}
});
game.createBlocks = function () {
	for (var i = 0; i < 3; i++) {
		game.createBlock(i);
	}
};
game.showStreakText = function (level) {
	// Remove existing streak text if any
	if (streakText && streakText.parent) {
		streakText.destroy();
	}
	var message = '';
	var color = 0xFFFFFF;
	if (level === 1) {
		message = 'GOOD';
		color = 0x00FF00; // Green
	} else if (level === 2) {
		message = 'SUPER';
		color = 0x80FF00; // Green-Yellow
	} else if (level === 3) {
		message = 'WOW';
		color = 0xFFFF00; // Yellow
	} else if (level === 4) {
		message = 'AMAZING';
		color = 0xFF8000; // Yellow-Orange
	} else if (level === 5) {
		message = 'MANIAC';
		color = 0xFF4000; // Orange-Red
	} else if (level >= 6) {
		message = 'CRAZYY!!!';
		color = 0xFF0000; // Red
	}
	if (message) {
		var newStreakText = new Text2(message, {
			size: 200,
			fill: color,
			font: 'Impact',
			stroke: '#000000',
			strokeThickness: 8
		});
		// Position diagonally across screen (top-right diagonal style)
		newStreakText.anchor.set(0.5, 0.5);
		newStreakText.x = 2048 - 300; // Move to right side
		newStreakText.y = 400; // Move to upper area
		newStreakText.rotation = -0.2; // Slight diagonal angle
		newStreakText.alpha = 0;
		newStreakText.scaleX = 0.5;
		newStreakText.scaleY = 0.5;
		game.addChild(newStreakText);
		streakText = newStreakText;
		// Animate streak text appearance with elastic bounce effect
		tween(newStreakText, {
			alpha: 1,
			scaleX: 1.3,
			scaleY: 1.3
		}, {
			duration: 600,
			easing: tween.elasticOut,
			onFinish: function onFinish() {
				// Add a secondary bounce effect
				tween(newStreakText, {
					scaleX: 1.1,
					scaleY: 1.1
				}, {
					duration: 200,
					easing: tween.bounceOut,
					onFinish: function onFinish() {
						// Animate text disappearance after showing
						tween(newStreakText, {
							alpha: 0,
							scaleX: 0.8,
							scaleY: 0.8,
							y: newStreakText.y - 100
						}, {
							duration: 1500,
							easing: tween.elasticIn,
							onFinish: function onFinish() {
								if (newStreakText && newStreakText.parent) {
									newStreakText.destroy();
									if (streakText === newStreakText) {
										streakText = null;
									}
								}
							}
						});
					}
				});
			}
		});
	}
};
var score = 0;
var lastLinesClearedTime = 0;
var streakLevel = 0;
var streakTimeout = 5000; // 5 seconds in milliseconds
var streakText = null;
game.createBlocks();
var scoreTxt = new Text2('0', {
	size: 150,
	fill: 0xFFFFFF,
	font: 'Impact',
	stroke: '#2a636e',
	strokeThickness: 16
});
scoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreTxt);
game.isMovePossible = function () {
	// Cache blocks that exist for faster iteration
	var activeBlocks = [];
	for (var a = 0; a < blocks.length; a++) {
		if (blocks[a]) {
			activeBlocks.push(blocks[a]);
		}
	}
	for (var blockIndex = 0; blockIndex < activeBlocks.length; blockIndex++) {
		var block = activeBlocks[blockIndex];
		// Check fewer positions by sampling every other position for performance
		for (var i = 0; i < 10; i += 1) {
			for (var j = 0; j < 10; j += 1) {
				if (board.grid[i][j].filled) {
					continue;
				}
				var canPlace = true;
				// Early bounds checking
				if (i + block.shape.length > 10 || j + block.shape[0].length > 10) {
					continue;
				}
				for (var k = 0; k < block.shape.length && canPlace; k++) {
					for (var l = 0; l < block.shape[k].length && canPlace; l++) {
						if (block.shape[k][l] === 1) {
							if (board.grid[i + k][j + l].filled) {
								canPlace = false;
							}
						}
					}
				}
				if (canPlace) {
					return true;
				}
			}
		}
	}
	return false;
};
// Create frame-based animation sequence for assets
var currentAssetIndex = 0;
var assetDisplays = [asset1Display, asset2Display, asset3Display, asset4Display];
var animationTimer;
function showNextFrame() {
	// Hide all frames first for stability
	for (var i = 0; i < assetDisplays.length; i++) {
		assetDisplays[i].alpha = 0;
	}
	// Move to next frame
	currentAssetIndex = (currentAssetIndex + 1) % assetDisplays.length;
	// Show next frame
	assetDisplays[currentAssetIndex].alpha = 1;
}
function startFrameAnimation() {
	// Hide all frames initially for stability
	for (var i = 0; i < assetDisplays.length; i++) {
		assetDisplays[i].alpha = 0;
	}
	// Show first frame
	assetDisplays[currentAssetIndex].alpha = 1;
	// Set up timer to cycle through frames every 100ms (10 FPS animation) for faster speed
	animationTimer = LK.setInterval(showNextFrame, 100);
}
// Start the frame animation
startFrameAnimation();
// Play Fala music as background music with continuous looping
LK.playMusic('Fala');
var isGameOver = false;
LK.on('tick', function () {
	board.tick();
	// Only check game over every 30 ticks (half second) to reduce performance impact
	if (LK.ticks % 30 === 0 && (isGameOver || !game.isMovePossible())) {
		LK.effects.flashScreen(0xffffff, 1000);
		LK.showGameOver();
	}
	for (var a = blocks.length - 1; a >= 0; a--) {
		if (blocks[a]) {
			if (blocks[a] != dragTarget) {
				blocks[a].moveTowardsHomePosition();
			} else {
				blocks[a].moveToDragTarget();
			}
		}
	}
});
:quality(85)/https://cdn.frvr.ai/65703e58695fbf13c2730381.png%3F3) 
 White particle cloud. Cartoon. Bright outline. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65705f66695fbf13c273052d.png%3F3) 
 Perfectly square bright purple Christmas decoration with cute happyy face. Cartoon style. Cute art style. Simple vector style.
:quality(85)/https://cdn.frvr.ai/6884271c959ba2f8b4f82351.png%3F3) 
 Bunun hersΜ§eyini aynΔ± yap sadece rengini koyu siyah ve mor yap surat ifadesi de kΔ±zgΔ±n ve yuΜzuΜnde kuΜcΜ§uΜk sΔ±yrΔ±k ve kesikler olsun
:quality(85)/https://cdn.frvr.ai/68842c74959ba2f8b4f8237d.png%3F3) 
 Bunun hicΜ§ birsΜ§ey ni degΜisΜ§tirme sadece rengini koyu yesΜ§il ve acΜ§Δ±k yesΜ§il nuΜkleer isΜ§areti koy ve arkaplanΔ± olmasΔ±n
:quality(85)/https://cdn.frvr.ai/68842d9a959ba2f8b4f8238e.png%3F3) 
 Bunun hicΜ§ birsΜ§ey ni degΜisΜ§tirme sadece rengini koyu mavi ve acΜ§Δ±k gri ve alnΔ±na ters hacΜ§ koy ve arkaplanΔ± olmasΔ±n
:quality(85)/https://cdn.frvr.ai/68842e86959ba2f8b4f82397.png%3F3) 
 Bunun hicΜ§ birsΜ§ey ni degΜisΜ§tirme sadece rengini koyu kΔ±rmΔ±zΔ± ve acΜ§Δ±k kΔ±rmΔ±zΔ±.goΜzlerinin bebeklerini buΜyuΜlt ve kafasΔ±na sΜ§eytan boynuzlari koy ve arkaplanΔ± olmasΔ±n
:quality(85)/https://cdn.frvr.ai/68842f5b959ba2f8b4f823a8.png%3F3) 
 Bunun hicΜ§ birsΜ§ey ni degΜisΜ§tirme sadece rengini koyu hayalet beyazΔ± ve acΜ§Δ±k mor hayalet etekleri olsun alt kΔ±smΔ±nda ve arkaplanΔ± olmasΔ±n
:quality(85)/https://cdn.frvr.ai/68843073959ba2f8b4f823bc.png%3F3) 
 DuΜz arkaplan ama rengi koyu siyah ve acΜ§Δ±k kΔ±rmΔ±zΔ± cΜ§izikler sΔ±yrΔ±klar olsun. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/68843116959ba2f8b4f823cd.png%3F3) 
 Bunun aynΔ±sΔ± olsun yanlΔ±zca stili korku temalΔ± olsun icΜ§ kΔ±sΔ±mdaki beyaz kΔ±smΔ± siyah ve kΔ±rmΔ±zΔ± cΜ§izikler ve kesikler ekle
:quality(85)/https://cdn.frvr.ai/68843167959ba2f8b4f823e0.png%3F3) 
 Rengini koyu yap mat olsun
:quality(85)/https://cdn.frvr.ai/68881f100365e3fde1ab652a.png%3F3) 
 HicΜ§ birseyi degΜisΜ§tirme aynΔ±sΔ±nΔ± yap