/**** 
* Classes
****/ 
var Card = Container.expand(function (context, uid, index) {
	var self = Container.call(this);
	self.row = 0;
	self.col = 0;
	self.uid = uid;
	self.id = index;
	if (!index) {
		self.isMatched = true;
		return self;
	}
	self.isMatched = false;
	nbCardsLeft++;
	self.shakeAnimation = function (card) {
		if (!card) {
			return;
		}
		var shakeCount = 0;
		var shakeTimes = 9;
		var shakeStrength = 70;
		var originalX = card.x;
		var originalY = card.y;
		function shake() {
			if (shakeCount < shakeTimes) {
				card.x = originalX + (Math.random() - 0.5) * shakeStrength;
				shakeCount++;
				LK.setTimeout(shake, 50);
			} else {
				card.x = originalX;
				card.y = originalY;
				card.scale.x = 1;
				card.scale.y = 1;
				if (card === selectedCard1) {
					selectedCard1 = null;
				}
				if (card === selectedCard2) {
					selectedCard2 = null;
				}
				isAnimating = false;
			}
		}
		shake();
	};
	self.id = index;
	self.on('down', function (x, y, obj) {
		if (!self.isMatched && !isAnimating) {
			if (!selectedCard1 || selectedCard1 && selectedCard2) {
				if (selectedCard1) {
					selectedCard1.scale.x = 1;
					selectedCard1.scale.y = 1;
					if (selectedCard1 === self) {
						selectedCard1 = null;
						return;
					}
				}
				selectedCard1 = self;
				selectedCard2 = null;
				self.scale.x = 1.2;
				self.scale.y = 1.2;
			} else if (selectedCard1 && !selectedCard2 && selectedCard1 === self) {
				selectedCard1.scale.x = 1;
				selectedCard1.scale.y = 1;
				selectedCard1 = null;
			} else if (selectedCard1 && !selectedCard2 && selectedCard1 !== self) {
				selectedCard2 = self;
				var canLink = canBeLinked(selectedCard1, selectedCard2);
				self.scale.x = 1.2;
				self.scale.y = 1.2;
				if (canLink) {
					lastMatched = true;
					selectedCard1.match(selectedCard2);
					selectedCard2.match(selectedCard1);
					selectedCard1 = null;
					selectedCard2 = null;
				} else {
					lastMatched = false;
					isAnimating = true;
					LK.setTimeout(function () {
						self.shakeAnimation(selectedCard1);
						self.shakeAnimation(selectedCard2);
					}, 300);
				}
			}
		}
	});
	var cardGraphics = self.attachAsset('card', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.match = function (otherCard) {
		if (checkGameEndTimeout) {
			LK.clearTimeout(checkGameEndTimeout);
		}
		var line = new Line(self.x, self.y, otherCard.x, otherCard.y);
		game.addChild(line);
		var tadaAnimationSteps = 10;
		var tadaAnimationCount = 0;
		var scaleDelta = 0.2;
		var tadaDelay = 0;
		var tadaDelayMax = 60;
		self.tadaAnimation = function () {
			if (tadaAnimationCount < tadaAnimationSteps) {
				self.scale.x += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
				self.scale.y += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
				tadaAnimationCount++;
			} else {
				LK.off('tick', self.tadaAnimation);
			}
		};
		self.shrinkAnimation = function () {
			if (self.scale.x > 0.1) {
				self.scale.x -= 0.01;
				self.scale.y -= 0.01;
				self.rotation += 0.1;
			} else {
				self.visible = false;
				LK.off('tick', self.tadaAnimation);
				LK.off('tick', self.shrinkAnimation);
				currentSolvedPairs[self.id] = true;
				currentNbSolved = Object.keys(currentSolvedPairs).length;
				if (checkGameEndTimeout) {
					LK.clearTimeout(checkGameEndTimeout);
				}
				checkGameEndTimeout = LK.setTimeout(function () {
					if (currentNbSolved >= lastNbPossible) {
						checkGameEnd(context, self.id);
					}
				}, 1000);
			}
		};
		LK.on('tick', self.tadaAnimation);
		self.isMatched = true;
		LK.setTimeout(function () {
			LK.on('tick', self.shrinkAnimation);
		}, tadaAnimationSteps * 50);
		LK.setTimeout(function () {
			line.destroy();
		}, 1000);
	};
	var picture = self.addChild(new Picture(index));
	picture.x = 0;
	picture.y = 0;
	return self;
});
var Line = Container.expand(function (startX, startY, endX, endY) {
	var self = Container.call(this);
	var lineGraphics = self.attachAsset('line', {});
	lineGraphics.width = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
	lineGraphics.rotation = Math.atan2(endY - startY, endX - startX);
	lineGraphics.x = startX;
	lineGraphics.y = startY;
	self.addChild(lineGraphics);
	return self;
});
var Picture = Container.expand(function (index) {
	var self = Container.call(this);
	self.index = index;
	var pictureGraphics = self.createAsset('picture' + self.index, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var TimerLine = Container.expand(function (width, height) {
	var self = Container.call(this);
	var timerGraphics = self.attachAsset('timerLine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	timerGraphics.width = width;
	timerGraphics.height = height;
	timerGraphics.tint = 0x00FF00;
	self.addChild(timerGraphics);
	self._update_migrated = function (elapsedTime) {
		var totalTicks = levelDurationInSeconds * 1000;
		var deltaWidth = this.initialWidth / totalTicks;
		timerGraphics.width = Math.max(0, timerGraphics.width - deltaWidth * elapsedTime);
		if (timerGraphics.width / this.initialWidth < 0.25) {
			timerGraphics.tint = 0xFF1E1E - Math.round(0xFF * (this.initialWidth / timerGraphics.width)) << 16;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
function _slicedToArray(r, e) {
	return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _nonIterableRest() {
	throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
	if (r) {
		if ("string" == typeof r) {
			return _arrayLikeToArray(r, a);
		}
		var t = {}.toString.call(r).slice(8, -1);
		return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
	}
}
function _arrayLikeToArray(r, a) {
	(null == a || a > r.length) && (a = r.length);
	for (var e = 0, n = Array(a); e < a; e++) {
		n[e] = r[e];
	}
	return n;
}
function _iterableToArrayLimit(r, l) {
	var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
	if (null != t) {
		var e,
			n,
			i,
			u,
			a = [],
			f = !0,
			o = !1;
		try {
			if (i = (t = t.call(r)).next, 0 === l) {
				if (Object(t) !== t) {
					return;
				}
				f = !1;
			} else {
				for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
					;
				}
			}
		} catch (r) {
			o = !0, n = r;
		} finally {
			try {
				if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
					return;
				}
			} finally {
				if (o) {
					throw n;
				}
			}
		}
		return a;
	}
}
function _arrayWithHoles(r) {
	if (Array.isArray(r)) {
		return r;
	}
}
var level = 0;
var levels = [{
	'rows': 2,
	'cols': 2,
	'time': 20
}, {
	'rows': 4,
	'cols': 4,
	'time': 60
}, {
	'rows': 6,
	'cols': 6,
	'time': 120
}, {
	'rows': 8,
	'cols': 8,
	'time': 180
}, {
	'rows': 10,
	'cols': 10,
	'time': 300
}, {
	'rows': 11,
	'cols': 10,
	'time': 420
}, {
	'rows': 12,
	'cols': 10,
	'time': 600
}];
level = Math.min(levels.length - 1, Math.max(0, level));
var levelDurationInSeconds = levels[level].time;
var MAX_INIT_TRIES = 1000;
var debug = false;
var lastMatched = false;
var cardPairs = [];
var cards = [];
var selectedCard1 = null;
var selectedCard2 = null;
var isInitializing = false;
var isAnimating = false;
var isRemixing = false;
var nbRows = 2 + 2;
var nbCols = 1 + 2;
var nbCards = nbRows * nbCols;
var nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
var nbCardsLeft = 0;
var lastNbPossible = 0;
var currentSolvedPairs = [];
var currentNbSolved = 0;
var cardWidth = 200;
var cardHeight = 200;
var horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
var verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
var shuffleDifficulty = 4;
var lastCheckCaller = 0;
var isPlaying = false;
var isGameEndChecking = false;
var isTryingInitGame = false;
var checkGameEndTimeout = null;
if (nbCards % 2) {
	console.error('Invalid number of cards ! Should be even.', nbCards);
	LK.showGameOver();
	nbCols++;
}
function prepareConfig(level) {
	cardPairs = [];
	cards.forEach(function (row) {
		row.forEach(function (card) {
			if (card) {
				card.destroy();
			}
		});
	});
	cards = [];
	nbRows = levels[level].rows + 2;
	nbCols = levels[level].cols + 2;
	nbCards = nbRows * nbCols;
	if (nbCards % 2) {
		console.error('Invalid number of cards ! Should be even.', nbCards);
		LK.showGameOver();
		nbCols++;
	}
	nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
	horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
	verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
	nbCardsLeft = 0;
	lastNbPossible = 0;
	currentSolvedPairs = [];
	currentNbSolved = 0;
	lastCheckCaller = 0;
	checkGameEndTimeout = null;
	selectedCard1 = null;
	selectedCard2 = null;
	isAnimating = false;
	isRemixing = false;
}
function timeBasedRandom() {
	var currentTime = Date.now();
	var timeSeed = currentTime % 1000;
	var randomValue = Math.random() * timeSeed;
	return randomValue - Math.floor(randomValue);
}
function shuffleArray(array, onlyNonEmpty) {
	for (var i = array.length - 1; i > 0; i--) {
		var j = Math.floor(timeBasedRandom() * (i + 1));
		if (onlyNonEmpty && (!array[i] || !array[j])) {
			continue;
		}
		var temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	return array;
}
function shuffleWithDifficulty(array, difficulty, onlyNonEmpty) {
	difficulty = Math.max(0, Math.min(10, difficulty));
	var maxSwapDistance = Math.ceil(array.length * (difficulty / 10));
	var numberOfSwaps = Math.ceil(array.length * (difficulty / 10));
	for (var i = 0; i < numberOfSwaps; i++) {
		var firstIndex = Math.floor(timeBasedRandom() * array.length);
		var swapDistance = Math.floor(timeBasedRandom() * maxSwapDistance);
		var secondIndex = (firstIndex + swapDistance) % array.length;
		if (onlyNonEmpty && (!array[firstIndex] || !array[secondIndex])) {
			continue;
		}
		var temp = array[firstIndex];
		array[firstIndex] = array[secondIndex];
		array[secondIndex] = temp;
	}
	ensureAdjacentIndexes(array, difficulty);
	return array;
}
function ensureAdjacentIndexes(array, difficulty) {
	var numberOfPairsToSwap = Math.floor(array.length * 0.5 * (1 / difficulty) * 0.5);
	var pairsToSwap = [];
	for (var i = 0; i < array.length - 1; i++) {
		for (var j = i + 1; j < array.length; j++) {
			if (array[i] && array[j] && array[i] === array[j] && !pairsToSwap.includes(array[i])) {
				pairsToSwap.push(array[i]);
			}
		}
	}
	shuffleArray(pairsToSwap, false);
	pairsToSwap = pairsToSwap.slice(0, numberOfPairsToSwap);
	for (var i = 0; i < array.length - 1; i++) {
		for (var j = i + 1; j < array.length; j++) {
			if (array[i] && array[j] && array[i] === array[j] && pairsToSwap.includes(array[i]) && array[i + 1]) {
				var temp = array[i + 1];
				array[i + 1] = array[j];
				array[j] = temp;
				pairsToSwap.splice(pairsToSwap.indexOf(array[i]), 1);
				break;
			}
		}
	}
}
function canBeLinked(card1, card2) {
	if (card1 === card2 || !card1 || !card2 || card1.id !== card2.id) {
		return false;
	}
	var visited = Array.from({
		length: nbRows
	}, function () {
		return Array(nbCols).fill(false);
	});
	function dfs(card, bends, direction) {
		if (!card || visited[card.row][card.col] || bends > 2) {
			return false;
		}
		if (card === card2) {
			return true;
		}
		visited[card.row][card.col] = true;
		var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
		for (var _i = 0, _directions = directions; _i < _directions.length; _i++) {
			var _directions$_i = _slicedToArray(_directions[_i], 2),
				di = _directions$_i[0],
				dj = _directions$_i[1];
			var ni = card.row + di,
				nj = card.col + dj;
			if (ni >= 0 && ni < nbRows && nj >= 0 && nj < nbCols) {
				var nextCard = cards[ni][nj];
				if (!nextCard || !nextCard.id || nextCard.isMatched || nextCard === card2) {
					if (di !== 0) {
						if (dfs(nextCard, bends + (direction === -1), 1)) {
							return true;
						}
					} else if (dj !== 0) {
						if (dfs(nextCard, bends + (direction === 1), -1)) {
							return true;
						}
					}
				}
			}
		}
		visited[card.row][card.col] = false;
		return false;
	}
	return dfs(card1, 0);
}
function remixCards(currentDifficulty, callback) {
	if (isRemixing) {
		return false;
	}
	isRemixing = true;
	var unmatchedCards = cards.flat().filter(function (card) {
		return !card.isMatched;
	});
	var oldPositions = unmatchedCards.map(function (card) {
		return {
			uid: card.uid,
			id: card.id,
			x: card.x,
			y: card.y
		};
	});
	var indexes = unmatchedCards.map(function (card) {
		return card.id;
	});
	indexes = shuffleWithDifficulty(indexes, currentDifficulty);
	var reorderedPosition = [];
	var treatedIndexes = [];
	for (var i = 0; i < oldPositions.length; i++) {
		var originId = oldPositions[i].id;
		for (var j = 0; j < indexes.length; j++) {
			var newId = indexes[j];
			if (originId === newId && !treatedIndexes[j]) {
				reorderedPosition[i] = {
					uid: oldPositions[j].uid,
					id: oldPositions[j].id,
					x: oldPositions[j].x,
					y: oldPositions[j].y
				};
				treatedIndexes[j] = true;
				break;
			}
		}
	}
	unmatchedCards.forEach(function (card, index) {
		var newPos = reorderedPosition[index];
		var _moveCard = function moveCard() {
			var dx = 0;
			var dy = 0;
			if (newPos) {
				dx = newPos.x - card.x;
				dy = newPos.y - card.y;
			}
			if (index == 1) {}
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < 1) {
				card.x = newPos.x;
				card.y = newPos.y;
				var newCol = Math.floor((card.x - horizontalOffset) / cardWidth);
				var newRow = Math.floor((card.y - verticalOffset) / cardHeight);
				if (cards[card.row] && cards[card.row][card.col] === card) {
					cards[card.row][card.col] = undefined;
				}
				card.col = newCol;
				card.row = newRow;
				cards[newRow][newCol] = card;
				LK.off('tick', _moveCard);
			} else {
				card.x += dx * 0.05;
				card.y += dy * 0.05;
			}
		};
		LK.on('tick', _moveCard);
	});
	LK.setTimeout(function () {
		isRemixing = false;
		if (callback) {
			callback();
		}
	}, 4000);
}
function checkGameEnd(context, callerId) {
	if (isGameEndChecking) {
		return;
	}
	if (lastCheckCaller === callerId) {
		return;
	}
	isGameEndChecking = true;
	lastCheckCaller = callerId;
	nbCardsLeft = cards.flat().filter(function (card) {
		return !card.isMatched;
	}).length;
	if (!nbCardsLeft) {
		isPlaying = false;
		LK.setTimeout(function () {
			if (level + 1 >= levels.length) {
				showConfettiAnimation(context, function () {
					LK.showGameOver();
				}, true);
			} else {
				level++;
				level = Math.min(levels.length - 1, Math.max(0, level));
				showConfettiAnimation(context, function () {
					isGameEndChecking = false;
					tryInitGame(context);
				});
			}
		}, 300);
		return;
	}
	if (currentNbSolved >= lastNbPossible) {
		var isPossible = checkBoardPossible();
		var canContinue = currentNbSolved < lastNbPossible;
		if (!canContinue) {
			tryRemixCards();
		}
	}
	isGameEndChecking = false;
}
function checkBoardPossible() {
	var nbPossible = 0;
	var nbImpossible = 0;
	var indexesChecked = [];
	for (var i = 0; i < cardPairs.length; i++) {
		var index = cardPairs[i];
		if (!index || indexesChecked[index]) {
			continue;
		}
		var card1 = cards.flat().find(function (card) {
			return card.id === index;
		});
		var card2 = cards.flat().find(function (card) {
			return card.id === index && card !== card1;
		});
		if (canBeLinked(card1, card2)) {
			nbPossible++;
		} else {
			nbImpossible++;
		}
		indexesChecked[index] = true;
	}
	lastNbPossible = nbPossible;
	return Math.max(currentNbSolved, nbPossible) >= (nbImpossible + nbPossible) * 0.1;
}
function initGame(self, currentDifficulty) {
	if (isInitializing) {
		console.log('already Initializing...');
		return;
	}
	isInitializing = true;
	prepareConfig(level);
	var nextPairIndex = 1;
	for (var i = 0; i < nbCards; i++) {
		var row = Math.floor(i / nbCols);
		var col = i % nbCols;
		if (row === 0 || row === nbRows - 1 || col === 0 || col === nbCols - 1) {
			cardPairs.push(0);
		} else {
			cardPairs.push(nextPairIndex);
			nextPairIndex = nextPairIndex % nbPairs + 1;
		}
	}
	cardPairs = shuffleWithDifficulty(cardPairs, currentDifficulty, true);
	for (var i = 0; i < nbCards; i++) {
		var row = Math.floor(i / nbCols);
		var col = i % nbCols;
		var card = self.addChild(new Card(self, i, cardPairs[i]));
		card.col = col;
		card.row = row;
		card.x = horizontalOffset + card.col * cardWidth;
		card.y = verticalOffset + card.row * cardHeight;
		if (!cards[card.row]) {
			cards[card.row] = [];
		}
		cards[card.row][card.col] = card;
	}
	isInitializing = false;
}
function tryInitGame(context) {
	if (isTryingInitGame) {
		console.log('Already tryInitGame...');
		return;
	}
	var isPossible = false;
	var nbTries = 0;
	var currentDifficulty = shuffleDifficulty;
	while (!isPossible && nbTries <= MAX_INIT_TRIES) {
		initGame(context, currentDifficulty);
		isPossible = checkBoardPossible();
		isPlaying = isPossible;
		nbTries++;
		currentDifficulty--;
	}
	if (nbTries > MAX_INIT_TRIES) {
		console.warn('Unable to init game after ' + nbTries + ' tries');
	}
	isTryingInitGame = false;
}
function tryRemixCards(nbTries, currentDifficulty) {
	nbTries = nbTries || 0;
	currentDifficulty = currentDifficulty || shuffleDifficulty;
	remixCards(currentDifficulty, function () {
		var isPossible = checkBoardPossible();
		nbTries++;
		currentDifficulty--;
		if (nbTries > MAX_INIT_TRIES) {
			isPossible = true;
			console.warn('Unable to remix game after ' + nbTries + ' tries');
		}
		if (!isPossible) {
			tryRemixCards(nbTries, currentDifficulty);
		}
	});
}
function showConfettiAnimation(self, callback, isFinal) {
	var confettiCount = 50 + 5 * level + (isFinal ? 50 : 0);
	var confettiGraphics;
	var backgroundImage = self.createAsset('background' + (level + (isFinal ? 1 : 0)), {
		anchorX: 0.5,
		anchorY: 0.5
	});
	backgroundImage.x = 2048 / 2;
	backgroundImage.y = 2732 / 2;
	self.addChild(backgroundImage);
	var congratulationsText = new Text2('Congratulations!', {
		size: 150,
		fill: '#ffffff'
	});
	if (isFinal) {
		congratulationsText.anchor.set(0.5, 0);
		congratulationsText.x = 0;
		congratulationsText.y = 20;
		LK.gui.top.addChild(congratulationsText);
	}
	for (var i = 0; i < confettiCount; i++) {
		confettiGraphics = self.createAsset('picture' + (1 + i % (nbPairs - 1)), {});
		confettiGraphics.x = Math.random() * 2048;
		confettiGraphics.y = -30 - Math.random() * 2000;
		confettiGraphics.rotation = Math.random() * Math.PI * 2;
		self.addChild(confettiGraphics);
		(function (confetti) {
			var totalTicks = 420 + (isFinal ? 300 : 0);
			var tickCount = 0;
			LK.on('tick', function () {
				if (tickCount < totalTicks) {
					confetti.y += 7 + 10 * Math.random() + (isFinal ? 10 : 0);
					confetti.rotation += 0.05;
					tickCount++;
				} else {
					LK.off('tick', arguments.callee);
					if (i === confettiCount && callback) {
						if (!isFinal) {
							backgroundImage.destroy();
						}
						callback();
					}
					confetti.destroy();
				}
			});
		})(confettiGraphics);
	}
}
function preload(context) {
	var titleText = new Text2('Xmas Pairs', {
		size: 200,
		fill: '#9bc5bc',
		anchor: {
			x: 0.5,
			y: 0.5
		}
	});
	titleText.x = 2048 / 8;
	titleText.y = 2732 / 8;
	LK.gui.addChild(titleText);
	var loadingText = new Text2('Loading...', {
		size: 100,
		fill: '#ffffff',
		anchor: {
			x: 0.5,
			y: 0.5
		}
	});
	loadingText.x = 2048 / 4;
	loadingText.y = 2732 / 4;
	LK.gui.addChild(loadingText);
	var assetsToLoad = ['line', 'picture1', 'picture2', 'picture3', 'picture8', 'picture7', 'picture24', 'picture17', 'picture16', 'picture4', 'picture29', 'picture6', 'picture14', 'picture15', 'picture20', 'picture9', 'picture10', 'picture27', 'picture12', 'picture19', 'picture26', 'picture22', 'picture18', 'picture28', 'picture23', 'picture13', 'picture21', 'picture5', 'picture11', 'picture25', 'picture30', 'picture32', 'picture31', 'picture37', 'picture39', 'picture44', 'picture38', 'picture48', 'picture47', 'picture50', 'picture42', 'picture46', 'picture45', 'picture43', 'picture49', 'picture34', 'picture33', 'picture40', 'picture36', 'picture35', 'picture41', 'picture55', 'picture52', 'picture54', 'picture53', 'picture51', 'picture56', 'picture59', 'picture60', 'picture57', 'picture58', 'picture64', 'picture63', 'picture61', 'picture62', 'picture65', 'card', 'timerLine', 'background1', 'background2', 'background3', 'background4', 'background5', 'background6', 'background7'];
	var loadedAssets = 0;
	assetsToLoad.forEach(function (asset) {
		var assetInstance = LK.getAsset(asset, {
			anchorX: 0.5,
			anchorY: 0.5
		});
		loadedAssets++;
		if (loadedAssets === assetsToLoad.length) {
			LK.setTimeout(function () {
				loadingText.destroy();
				titleText.destroy();
				tryInitGame(context);
			}, 1200);
		}
	});
}
preload(game);
if (debug) {
	game.timerLine = new TimerLine(1400, 20);
	game.timerLine.initialWidth = 1400;
	game.timerLine.x = 710;
	game.timerLine.y = game.timerLine.y;
	LK.gui.topLeft.addChild(game.timerLine);
	var tickTime = Date.now();
	LK.on('tick', function () {
		if (isPlaying && !isRemixing) {
			var elapsedTime = Date.now() - tickTime;
			game.timerLine._update_migrated(elapsedTime);
			tickTime = Date.now();
		}
	});
	var matchDebugText = new Text2('Match:', {
		size: 50,
		fill: '#ffffff'
	});
	matchDebugText.anchor.set(0, 0);
	LK.gui.topLeft.addChild(matchDebugText);
	LK.on('tick', function () {
		matchDebugText.setText('Level: ' + (level + 1) + ' Solved: ' + currentNbSolved + '/' + lastNbPossible + ' / isPlaying=' + isPlaying + ' / time=' + levelDurationInSeconds);
	});
} /**** 
* Classes
****/ 
var Card = Container.expand(function (context, uid, index) {
	var self = Container.call(this);
	self.row = 0;
	self.col = 0;
	self.uid = uid;
	self.id = index;
	if (!index) {
		self.isMatched = true;
		return self;
	}
	self.isMatched = false;
	nbCardsLeft++;
	self.shakeAnimation = function (card) {
		if (!card) {
			return;
		}
		var shakeCount = 0;
		var shakeTimes = 9;
		var shakeStrength = 70;
		var originalX = card.x;
		var originalY = card.y;
		function shake() {
			if (shakeCount < shakeTimes) {
				card.x = originalX + (Math.random() - 0.5) * shakeStrength;
				shakeCount++;
				LK.setTimeout(shake, 50);
			} else {
				card.x = originalX;
				card.y = originalY;
				card.scale.x = 1;
				card.scale.y = 1;
				if (card === selectedCard1) {
					selectedCard1 = null;
				}
				if (card === selectedCard2) {
					selectedCard2 = null;
				}
				isAnimating = false;
			}
		}
		shake();
	};
	self.id = index;
	self.on('down', function (x, y, obj) {
		if (!self.isMatched && !isAnimating) {
			if (!selectedCard1 || selectedCard1 && selectedCard2) {
				if (selectedCard1) {
					selectedCard1.scale.x = 1;
					selectedCard1.scale.y = 1;
					if (selectedCard1 === self) {
						selectedCard1 = null;
						return;
					}
				}
				selectedCard1 = self;
				selectedCard2 = null;
				self.scale.x = 1.2;
				self.scale.y = 1.2;
			} else if (selectedCard1 && !selectedCard2 && selectedCard1 === self) {
				selectedCard1.scale.x = 1;
				selectedCard1.scale.y = 1;
				selectedCard1 = null;
			} else if (selectedCard1 && !selectedCard2 && selectedCard1 !== self) {
				selectedCard2 = self;
				var canLink = canBeLinked(selectedCard1, selectedCard2);
				self.scale.x = 1.2;
				self.scale.y = 1.2;
				if (canLink) {
					lastMatched = true;
					selectedCard1.match(selectedCard2);
					selectedCard2.match(selectedCard1);
					selectedCard1 = null;
					selectedCard2 = null;
				} else {
					lastMatched = false;
					isAnimating = true;
					LK.setTimeout(function () {
						self.shakeAnimation(selectedCard1);
						self.shakeAnimation(selectedCard2);
					}, 300);
				}
			}
		}
	});
	var cardGraphics = self.attachAsset('card', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.match = function (otherCard) {
		if (checkGameEndTimeout) {
			LK.clearTimeout(checkGameEndTimeout);
		}
		var line = new Line(self.x, self.y, otherCard.x, otherCard.y);
		game.addChild(line);
		var tadaAnimationSteps = 10;
		var tadaAnimationCount = 0;
		var scaleDelta = 0.2;
		var tadaDelay = 0;
		var tadaDelayMax = 60;
		self.tadaAnimation = function () {
			if (tadaAnimationCount < tadaAnimationSteps) {
				self.scale.x += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
				self.scale.y += tadaAnimationCount % 2 === 0 ? scaleDelta : -scaleDelta;
				tadaAnimationCount++;
			} else {
				LK.off('tick', self.tadaAnimation);
			}
		};
		self.shrinkAnimation = function () {
			if (self.scale.x > 0.1) {
				self.scale.x -= 0.01;
				self.scale.y -= 0.01;
				self.rotation += 0.1;
			} else {
				self.visible = false;
				LK.off('tick', self.tadaAnimation);
				LK.off('tick', self.shrinkAnimation);
				currentSolvedPairs[self.id] = true;
				currentNbSolved = Object.keys(currentSolvedPairs).length;
				if (checkGameEndTimeout) {
					LK.clearTimeout(checkGameEndTimeout);
				}
				checkGameEndTimeout = LK.setTimeout(function () {
					if (currentNbSolved >= lastNbPossible) {
						checkGameEnd(context, self.id);
					}
				}, 1000);
			}
		};
		LK.on('tick', self.tadaAnimation);
		self.isMatched = true;
		LK.setTimeout(function () {
			LK.on('tick', self.shrinkAnimation);
		}, tadaAnimationSteps * 50);
		LK.setTimeout(function () {
			line.destroy();
		}, 1000);
	};
	var picture = self.addChild(new Picture(index));
	picture.x = 0;
	picture.y = 0;
	return self;
});
var Line = Container.expand(function (startX, startY, endX, endY) {
	var self = Container.call(this);
	var lineGraphics = self.attachAsset('line', {});
	lineGraphics.width = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2));
	lineGraphics.rotation = Math.atan2(endY - startY, endX - startX);
	lineGraphics.x = startX;
	lineGraphics.y = startY;
	self.addChild(lineGraphics);
	return self;
});
var Picture = Container.expand(function (index) {
	var self = Container.call(this);
	self.index = index;
	var pictureGraphics = self.createAsset('picture' + self.index, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	return self;
});
var TimerLine = Container.expand(function (width, height) {
	var self = Container.call(this);
	var timerGraphics = self.attachAsset('timerLine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	timerGraphics.width = width;
	timerGraphics.height = height;
	timerGraphics.tint = 0x00FF00;
	self.addChild(timerGraphics);
	self._update_migrated = function (elapsedTime) {
		var totalTicks = levelDurationInSeconds * 1000;
		var deltaWidth = this.initialWidth / totalTicks;
		timerGraphics.width = Math.max(0, timerGraphics.width - deltaWidth * elapsedTime);
		if (timerGraphics.width / this.initialWidth < 0.25) {
			timerGraphics.tint = 0xFF1E1E - Math.round(0xFF * (this.initialWidth / timerGraphics.width)) << 16;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
function _slicedToArray(r, e) {
	return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _nonIterableRest() {
	throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
	if (r) {
		if ("string" == typeof r) {
			return _arrayLikeToArray(r, a);
		}
		var t = {}.toString.call(r).slice(8, -1);
		return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
	}
}
function _arrayLikeToArray(r, a) {
	(null == a || a > r.length) && (a = r.length);
	for (var e = 0, n = Array(a); e < a; e++) {
		n[e] = r[e];
	}
	return n;
}
function _iterableToArrayLimit(r, l) {
	var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
	if (null != t) {
		var e,
			n,
			i,
			u,
			a = [],
			f = !0,
			o = !1;
		try {
			if (i = (t = t.call(r)).next, 0 === l) {
				if (Object(t) !== t) {
					return;
				}
				f = !1;
			} else {
				for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0) {
					;
				}
			}
		} catch (r) {
			o = !0, n = r;
		} finally {
			try {
				if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) {
					return;
				}
			} finally {
				if (o) {
					throw n;
				}
			}
		}
		return a;
	}
}
function _arrayWithHoles(r) {
	if (Array.isArray(r)) {
		return r;
	}
}
var level = 0;
var levels = [{
	'rows': 2,
	'cols': 2,
	'time': 20
}, {
	'rows': 4,
	'cols': 4,
	'time': 60
}, {
	'rows': 6,
	'cols': 6,
	'time': 120
}, {
	'rows': 8,
	'cols': 8,
	'time': 180
}, {
	'rows': 10,
	'cols': 10,
	'time': 300
}, {
	'rows': 11,
	'cols': 10,
	'time': 420
}, {
	'rows': 12,
	'cols': 10,
	'time': 600
}];
level = Math.min(levels.length - 1, Math.max(0, level));
var levelDurationInSeconds = levels[level].time;
var MAX_INIT_TRIES = 1000;
var debug = false;
var lastMatched = false;
var cardPairs = [];
var cards = [];
var selectedCard1 = null;
var selectedCard2 = null;
var isInitializing = false;
var isAnimating = false;
var isRemixing = false;
var nbRows = 2 + 2;
var nbCols = 1 + 2;
var nbCards = nbRows * nbCols;
var nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
var nbCardsLeft = 0;
var lastNbPossible = 0;
var currentSolvedPairs = [];
var currentNbSolved = 0;
var cardWidth = 200;
var cardHeight = 200;
var horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
var verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
var shuffleDifficulty = 4;
var lastCheckCaller = 0;
var isPlaying = false;
var isGameEndChecking = false;
var isTryingInitGame = false;
var checkGameEndTimeout = null;
if (nbCards % 2) {
	console.error('Invalid number of cards ! Should be even.', nbCards);
	LK.showGameOver();
	nbCols++;
}
function prepareConfig(level) {
	cardPairs = [];
	cards.forEach(function (row) {
		row.forEach(function (card) {
			if (card) {
				card.destroy();
			}
		});
	});
	cards = [];
	nbRows = levels[level].rows + 2;
	nbCols = levels[level].cols + 2;
	nbCards = nbRows * nbCols;
	if (nbCards % 2) {
		console.error('Invalid number of cards ! Should be even.', nbCards);
		LK.showGameOver();
		nbCols++;
	}
	nbPairs = (nbCards - nbRows * 2 - (nbCols - 2) * 2) / 2;
	horizontalOffset = (2048 - (nbCols - 1) * cardWidth) / 2;
	verticalOffset = (2732 - (nbRows - 1) * cardHeight) / 2;
	nbCardsLeft = 0;
	lastNbPossible = 0;
	currentSolvedPairs = [];
	currentNbSolved = 0;
	lastCheckCaller = 0;
	checkGameEndTimeout = null;
	selectedCard1 = null;
	selectedCard2 = null;
	isAnimating = false;
	isRemixing = false;
}
function timeBasedRandom() {
	var currentTime = Date.now();
	var timeSeed = currentTime % 1000;
	var randomValue = Math.random() * timeSeed;
	return randomValue - Math.floor(randomValue);
}
function shuffleArray(array, onlyNonEmpty) {
	for (var i = array.length - 1; i > 0; i--) {
		var j = Math.floor(timeBasedRandom() * (i + 1));
		if (onlyNonEmpty && (!array[i] || !array[j])) {
			continue;
		}
		var temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
	return array;
}
function shuffleWithDifficulty(array, difficulty, onlyNonEmpty) {
	difficulty = Math.max(0, Math.min(10, difficulty));
	var maxSwapDistance = Math.ceil(array.length * (difficulty / 10));
	var numberOfSwaps = Math.ceil(array.length * (difficulty / 10));
	for (var i = 0; i < numberOfSwaps; i++) {
		var firstIndex = Math.floor(timeBasedRandom() * array.length);
		var swapDistance = Math.floor(timeBasedRandom() * maxSwapDistance);
		var secondIndex = (firstIndex + swapDistance) % array.length;
		if (onlyNonEmpty && (!array[firstIndex] || !array[secondIndex])) {
			continue;
		}
		var temp = array[firstIndex];
		array[firstIndex] = array[secondIndex];
		array[secondIndex] = temp;
	}
	ensureAdjacentIndexes(array, difficulty);
	return array;
}
function ensureAdjacentIndexes(array, difficulty) {
	var numberOfPairsToSwap = Math.floor(array.length * 0.5 * (1 / difficulty) * 0.5);
	var pairsToSwap = [];
	for (var i = 0; i < array.length - 1; i++) {
		for (var j = i + 1; j < array.length; j++) {
			if (array[i] && array[j] && array[i] === array[j] && !pairsToSwap.includes(array[i])) {
				pairsToSwap.push(array[i]);
			}
		}
	}
	shuffleArray(pairsToSwap, false);
	pairsToSwap = pairsToSwap.slice(0, numberOfPairsToSwap);
	for (var i = 0; i < array.length - 1; i++) {
		for (var j = i + 1; j < array.length; j++) {
			if (array[i] && array[j] && array[i] === array[j] && pairsToSwap.includes(array[i]) && array[i + 1]) {
				var temp = array[i + 1];
				array[i + 1] = array[j];
				array[j] = temp;
				pairsToSwap.splice(pairsToSwap.indexOf(array[i]), 1);
				break;
			}
		}
	}
}
function canBeLinked(card1, card2) {
	if (card1 === card2 || !card1 || !card2 || card1.id !== card2.id) {
		return false;
	}
	var visited = Array.from({
		length: nbRows
	}, function () {
		return Array(nbCols).fill(false);
	});
	function dfs(card, bends, direction) {
		if (!card || visited[card.row][card.col] || bends > 2) {
			return false;
		}
		if (card === card2) {
			return true;
		}
		visited[card.row][card.col] = true;
		var directions = [[-1, 0], [1, 0], [0, -1], [0, 1]];
		for (var _i = 0, _directions = directions; _i < _directions.length; _i++) {
			var _directions$_i = _slicedToArray(_directions[_i], 2),
				di = _directions$_i[0],
				dj = _directions$_i[1];
			var ni = card.row + di,
				nj = card.col + dj;
			if (ni >= 0 && ni < nbRows && nj >= 0 && nj < nbCols) {
				var nextCard = cards[ni][nj];
				if (!nextCard || !nextCard.id || nextCard.isMatched || nextCard === card2) {
					if (di !== 0) {
						if (dfs(nextCard, bends + (direction === -1), 1)) {
							return true;
						}
					} else if (dj !== 0) {
						if (dfs(nextCard, bends + (direction === 1), -1)) {
							return true;
						}
					}
				}
			}
		}
		visited[card.row][card.col] = false;
		return false;
	}
	return dfs(card1, 0);
}
function remixCards(currentDifficulty, callback) {
	if (isRemixing) {
		return false;
	}
	isRemixing = true;
	var unmatchedCards = cards.flat().filter(function (card) {
		return !card.isMatched;
	});
	var oldPositions = unmatchedCards.map(function (card) {
		return {
			uid: card.uid,
			id: card.id,
			x: card.x,
			y: card.y
		};
	});
	var indexes = unmatchedCards.map(function (card) {
		return card.id;
	});
	indexes = shuffleWithDifficulty(indexes, currentDifficulty);
	var reorderedPosition = [];
	var treatedIndexes = [];
	for (var i = 0; i < oldPositions.length; i++) {
		var originId = oldPositions[i].id;
		for (var j = 0; j < indexes.length; j++) {
			var newId = indexes[j];
			if (originId === newId && !treatedIndexes[j]) {
				reorderedPosition[i] = {
					uid: oldPositions[j].uid,
					id: oldPositions[j].id,
					x: oldPositions[j].x,
					y: oldPositions[j].y
				};
				treatedIndexes[j] = true;
				break;
			}
		}
	}
	unmatchedCards.forEach(function (card, index) {
		var newPos = reorderedPosition[index];
		var _moveCard = function moveCard() {
			var dx = 0;
			var dy = 0;
			if (newPos) {
				dx = newPos.x - card.x;
				dy = newPos.y - card.y;
			}
			if (index == 1) {}
			var distance = Math.sqrt(dx * dx + dy * dy);
			if (distance < 1) {
				card.x = newPos.x;
				card.y = newPos.y;
				var newCol = Math.floor((card.x - horizontalOffset) / cardWidth);
				var newRow = Math.floor((card.y - verticalOffset) / cardHeight);
				if (cards[card.row] && cards[card.row][card.col] === card) {
					cards[card.row][card.col] = undefined;
				}
				card.col = newCol;
				card.row = newRow;
				cards[newRow][newCol] = card;
				LK.off('tick', _moveCard);
			} else {
				card.x += dx * 0.05;
				card.y += dy * 0.05;
			}
		};
		LK.on('tick', _moveCard);
	});
	LK.setTimeout(function () {
		isRemixing = false;
		if (callback) {
			callback();
		}
	}, 4000);
}
function checkGameEnd(context, callerId) {
	if (isGameEndChecking) {
		return;
	}
	if (lastCheckCaller === callerId) {
		return;
	}
	isGameEndChecking = true;
	lastCheckCaller = callerId;
	nbCardsLeft = cards.flat().filter(function (card) {
		return !card.isMatched;
	}).length;
	if (!nbCardsLeft) {
		isPlaying = false;
		LK.setTimeout(function () {
			if (level + 1 >= levels.length) {
				showConfettiAnimation(context, function () {
					LK.showGameOver();
				}, true);
			} else {
				level++;
				level = Math.min(levels.length - 1, Math.max(0, level));
				showConfettiAnimation(context, function () {
					isGameEndChecking = false;
					tryInitGame(context);
				});
			}
		}, 300);
		return;
	}
	if (currentNbSolved >= lastNbPossible) {
		var isPossible = checkBoardPossible();
		var canContinue = currentNbSolved < lastNbPossible;
		if (!canContinue) {
			tryRemixCards();
		}
	}
	isGameEndChecking = false;
}
function checkBoardPossible() {
	var nbPossible = 0;
	var nbImpossible = 0;
	var indexesChecked = [];
	for (var i = 0; i < cardPairs.length; i++) {
		var index = cardPairs[i];
		if (!index || indexesChecked[index]) {
			continue;
		}
		var card1 = cards.flat().find(function (card) {
			return card.id === index;
		});
		var card2 = cards.flat().find(function (card) {
			return card.id === index && card !== card1;
		});
		if (canBeLinked(card1, card2)) {
			nbPossible++;
		} else {
			nbImpossible++;
		}
		indexesChecked[index] = true;
	}
	lastNbPossible = nbPossible;
	return Math.max(currentNbSolved, nbPossible) >= (nbImpossible + nbPossible) * 0.1;
}
function initGame(self, currentDifficulty) {
	if (isInitializing) {
		console.log('already Initializing...');
		return;
	}
	isInitializing = true;
	prepareConfig(level);
	var nextPairIndex = 1;
	for (var i = 0; i < nbCards; i++) {
		var row = Math.floor(i / nbCols);
		var col = i % nbCols;
		if (row === 0 || row === nbRows - 1 || col === 0 || col === nbCols - 1) {
			cardPairs.push(0);
		} else {
			cardPairs.push(nextPairIndex);
			nextPairIndex = nextPairIndex % nbPairs + 1;
		}
	}
	cardPairs = shuffleWithDifficulty(cardPairs, currentDifficulty, true);
	for (var i = 0; i < nbCards; i++) {
		var row = Math.floor(i / nbCols);
		var col = i % nbCols;
		var card = self.addChild(new Card(self, i, cardPairs[i]));
		card.col = col;
		card.row = row;
		card.x = horizontalOffset + card.col * cardWidth;
		card.y = verticalOffset + card.row * cardHeight;
		if (!cards[card.row]) {
			cards[card.row] = [];
		}
		cards[card.row][card.col] = card;
	}
	isInitializing = false;
}
function tryInitGame(context) {
	if (isTryingInitGame) {
		console.log('Already tryInitGame...');
		return;
	}
	var isPossible = false;
	var nbTries = 0;
	var currentDifficulty = shuffleDifficulty;
	while (!isPossible && nbTries <= MAX_INIT_TRIES) {
		initGame(context, currentDifficulty);
		isPossible = checkBoardPossible();
		isPlaying = isPossible;
		nbTries++;
		currentDifficulty--;
	}
	if (nbTries > MAX_INIT_TRIES) {
		console.warn('Unable to init game after ' + nbTries + ' tries');
	}
	isTryingInitGame = false;
}
function tryRemixCards(nbTries, currentDifficulty) {
	nbTries = nbTries || 0;
	currentDifficulty = currentDifficulty || shuffleDifficulty;
	remixCards(currentDifficulty, function () {
		var isPossible = checkBoardPossible();
		nbTries++;
		currentDifficulty--;
		if (nbTries > MAX_INIT_TRIES) {
			isPossible = true;
			console.warn('Unable to remix game after ' + nbTries + ' tries');
		}
		if (!isPossible) {
			tryRemixCards(nbTries, currentDifficulty);
		}
	});
}
function showConfettiAnimation(self, callback, isFinal) {
	var confettiCount = 50 + 5 * level + (isFinal ? 50 : 0);
	var confettiGraphics;
	var backgroundImage = self.createAsset('background' + (level + (isFinal ? 1 : 0)), {
		anchorX: 0.5,
		anchorY: 0.5
	});
	backgroundImage.x = 2048 / 2;
	backgroundImage.y = 2732 / 2;
	self.addChild(backgroundImage);
	var congratulationsText = new Text2('Congratulations!', {
		size: 150,
		fill: '#ffffff'
	});
	if (isFinal) {
		congratulationsText.anchor.set(0.5, 0);
		congratulationsText.x = 0;
		congratulationsText.y = 20;
		LK.gui.top.addChild(congratulationsText);
	}
	for (var i = 0; i < confettiCount; i++) {
		confettiGraphics = self.createAsset('picture' + (1 + i % (nbPairs - 1)), {});
		confettiGraphics.x = Math.random() * 2048;
		confettiGraphics.y = -30 - Math.random() * 2000;
		confettiGraphics.rotation = Math.random() * Math.PI * 2;
		self.addChild(confettiGraphics);
		(function (confetti) {
			var totalTicks = 420 + (isFinal ? 300 : 0);
			var tickCount = 0;
			LK.on('tick', function () {
				if (tickCount < totalTicks) {
					confetti.y += 7 + 10 * Math.random() + (isFinal ? 10 : 0);
					confetti.rotation += 0.05;
					tickCount++;
				} else {
					LK.off('tick', arguments.callee);
					if (i === confettiCount && callback) {
						if (!isFinal) {
							backgroundImage.destroy();
						}
						callback();
					}
					confetti.destroy();
				}
			});
		})(confettiGraphics);
	}
}
function preload(context) {
	var titleText = new Text2('Xmas Pairs', {
		size: 200,
		fill: '#9bc5bc',
		anchor: {
			x: 0.5,
			y: 0.5
		}
	});
	titleText.x = 2048 / 8;
	titleText.y = 2732 / 8;
	LK.gui.addChild(titleText);
	var loadingText = new Text2('Loading...', {
		size: 100,
		fill: '#ffffff',
		anchor: {
			x: 0.5,
			y: 0.5
		}
	});
	loadingText.x = 2048 / 4;
	loadingText.y = 2732 / 4;
	LK.gui.addChild(loadingText);
	var assetsToLoad = ['line', 'picture1', 'picture2', 'picture3', 'picture8', 'picture7', 'picture24', 'picture17', 'picture16', 'picture4', 'picture29', 'picture6', 'picture14', 'picture15', 'picture20', 'picture9', 'picture10', 'picture27', 'picture12', 'picture19', 'picture26', 'picture22', 'picture18', 'picture28', 'picture23', 'picture13', 'picture21', 'picture5', 'picture11', 'picture25', 'picture30', 'picture32', 'picture31', 'picture37', 'picture39', 'picture44', 'picture38', 'picture48', 'picture47', 'picture50', 'picture42', 'picture46', 'picture45', 'picture43', 'picture49', 'picture34', 'picture33', 'picture40', 'picture36', 'picture35', 'picture41', 'picture55', 'picture52', 'picture54', 'picture53', 'picture51', 'picture56', 'picture59', 'picture60', 'picture57', 'picture58', 'picture64', 'picture63', 'picture61', 'picture62', 'picture65', 'card', 'timerLine', 'background1', 'background2', 'background3', 'background4', 'background5', 'background6', 'background7'];
	var loadedAssets = 0;
	assetsToLoad.forEach(function (asset) {
		var assetInstance = LK.getAsset(asset, {
			anchorX: 0.5,
			anchorY: 0.5
		});
		loadedAssets++;
		if (loadedAssets === assetsToLoad.length) {
			LK.setTimeout(function () {
				loadingText.destroy();
				titleText.destroy();
				tryInitGame(context);
			}, 1200);
		}
	});
}
preload(game);
if (debug) {
	game.timerLine = new TimerLine(1400, 20);
	game.timerLine.initialWidth = 1400;
	game.timerLine.x = 710;
	game.timerLine.y = game.timerLine.y;
	LK.gui.topLeft.addChild(game.timerLine);
	var tickTime = Date.now();
	LK.on('tick', function () {
		if (isPlaying && !isRemixing) {
			var elapsedTime = Date.now() - tickTime;
			game.timerLine._update_migrated(elapsedTime);
			tickTime = Date.now();
		}
	});
	var matchDebugText = new Text2('Match:', {
		size: 50,
		fill: '#ffffff'
	});
	matchDebugText.anchor.set(0, 0);
	LK.gui.topLeft.addChild(matchDebugText);
	LK.on('tick', function () {
		matchDebugText.setText('Level: ' + (level + 1) + ' Solved: ' + currentNbSolved + '/' + lastNbPossible + ' / isPlaying=' + isPlaying + ' / time=' + levelDurationInSeconds);
	});
}
 a photo realistic top view of empty flat beige plastic square. Single Game Texture. In-Game asset. 2d. No background. High contrast. No shadows.
 a christmas tree. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gift. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas ball. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a golden christmas tree star. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas hat. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas leaf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas holly leaf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas snow flake. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas snow man. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas reindeer. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas candy cane. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas green ball . plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gingerbrean man. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas pine cone. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas present green. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas boe tie. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas socks. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas penguin. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas decorated blue present. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas scarf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gloves. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas blue decorated ball. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas candle. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas snow globe. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 an christmas elongated cuboid present. plastic style. No shadow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a round christmas gift.plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a round christmas gift.plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 one cute christmas elf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 one cute christmas elf. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 one cute christmas reindeer head. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 one cute christmas reindeer head with a red nose. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 one christmas bell. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a couple of christmas bells. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gifts bag. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas candle. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a cute santa clauss. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 Santa's sleigh. Side view. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 Reimagine the cute teddy bear sitting without background. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 Christmas Rocking Horse. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 One Christmas Matryoshka Doll. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A christmas Miniature Train. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A christmas Toy Soldier. Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 A christmas Music Box . Plastic style Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a cute polar bear cub. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a sled plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gingerbread girl. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas gingerbread house. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a cute christmas jack in the box. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a cute christmas cookie. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas log cacke. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a christmas donut. plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a cute christmas owl. Plastic style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 a feeric christmas landscape at night with decorated trees Background image
 a feeric christmas landscape at night with snow men and snow flakes Background image
 a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, Background image
 a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, Santa's reindeers, green, red and blue presents Background image
 a feeric christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, cute penguin, Santa's reindeers, green, red and blue presents and a lot of toys, a sled, gingerbread boy and girl, snow globes, a cute polar bear cub. a gingerbread house Background image
 A Magical feeric starry christmas landscape at night with a snow man , candy canes ,holly leafs and snow flakes, cute penguin, Santa's reindeers, green, red and blue presents and a lot of toys, a sled, gingerbread boy and girl, snow globes, cute polar bears cub and a gingerbread house. Realistic. Plastic style. Background image