/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bubble = Container.expand(function (color) {
var self = Container.call(this);
self.color = color || 0x3498db;
self.colors = [0x3498db, 0xe74c3c, 0x2ecc71, 0xf39c12, 0x9b59b6];
var bubbleGraphics = self.attachAsset('gridBubble', {
anchorX: 0.5,
anchorY: 0.5,
tint: self.color
});
var pkText = new Text2('PK', {
size: 24,
fill: 0xFFFFFF
});
pkText.anchor.set(0.5, 0.5);
self.addChild(pkText);
self.gridX = 0;
self.gridY = 0;
self.isMoving = false;
return self;
});
var Shooter = Container.expand(function () {
var self = Container.call(this);
var shooterBase = self.attachAsset('shooter', {
anchorX: 0.5,
anchorY: 0.5
});
self.angle = 0;
self.canShoot = true;
self.shotsFired = 0;
self.maxConsecutiveShots = 2;
self.aimAt = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
self.angle = Math.atan2(dy, dx);
self.rotation = self.angle + Math.PI / 2;
};
self.shoot = function () {
if (!self.canShoot) return null;
var bubble = new ShooterBubble(nextBubbleColor);
bubble.x = self.x;
bubble.y = self.y - 50;
bubble.vx = Math.cos(self.angle) * bubble.speed;
bubble.vy = Math.sin(self.angle) * bubble.speed;
self.shotsFired++;
if (self.shotsFired >= self.maxConsecutiveShots) {
self.canShoot = false;
self.shotsFired = 0;
LK.setTimeout(function () {
self.canShoot = true;
}, 500);
}
LK.getSound('shoot').play();
return bubble;
};
return self;
});
var ShooterBubble = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
self.speed = 15;
self.vx = 0;
self.vy = -15;
var bubbleGraphics = self.attachAsset('shooterBubble', {
anchorX: 0.5,
anchorY: 0.5,
tint: color
});
var pkText = new Text2('PK', {
size: 20,
fill: 0xFFFFFF
});
pkText.anchor.set(0.5, 0.5);
self.addChild(pkText);
self.update = function () {
self.x += self.vx;
self.y += self.vy;
// Bounce off walls
if (self.x <= 40 || self.x >= 2008) {
self.vx *= -1;
if (self.x <= 40) self.x = 40;
if (self.x >= 2008) self.x = 2008;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
var GRID_WIDTH = 15;
var GRID_HEIGHT = 20;
var BUBBLE_SIZE = 70;
var BUBBLE_SPACING = 75;
var GRID_OFFSET_X = (2048 - GRID_WIDTH * BUBBLE_SPACING) / 2;
var GRID_OFFSET_Y = 100;
var bubbleColors = [0x3498db, 0xe74c3c, 0x2ecc71, 0xf39c12, 0x9b59b6];
var bubbleGrid = [];
var shooterBubbles = [];
var nextBubbleColor = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
var dropTimer = 0;
var dropInterval = 600; // 10 seconds at 60fps
// Initialize bubble grid
for (var row = 0; row < GRID_HEIGHT; row++) {
bubbleGrid[row] = [];
for (var col = 0; col < GRID_WIDTH; col++) {
bubbleGrid[row][col] = null;
}
}
// Add initial bubbles
for (var row = 0; row < 8; row++) {
for (var col = 0; col < GRID_WIDTH; col++) {
if (row % 2 === 1 && col === GRID_WIDTH - 1) continue; // Offset odd rows
var color = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
var bubble = new Bubble(color);
bubble.gridX = col;
bubble.gridY = row;
var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
bubble.x = GRID_OFFSET_X + col * BUBBLE_SPACING + offsetX;
bubble.y = GRID_OFFSET_Y + row * BUBBLE_SPACING;
bubbleGrid[row][col] = bubble;
game.addChild(bubble);
}
}
// Create shooter
var shooter = new Shooter();
shooter.x = 2048 / 2;
shooter.y = 2732 - 150;
game.addChild(shooter);
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
function getGridPosition(x, y) {
var row = Math.round((y - GRID_OFFSET_Y) / BUBBLE_SPACING);
var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
var col = Math.round((x - GRID_OFFSET_X - offsetX) / BUBBLE_SPACING);
return {
row: row,
col: col
};
}
function findMatchingBubbles(startRow, startCol, color, visited) {
if (!visited) visited = {};
var key = startRow + ',' + startCol;
if (visited[key]) return [];
visited[key] = true;
if (startRow < 0 || startRow >= GRID_HEIGHT || startCol < 0 || startCol >= GRID_WIDTH) return [];
if (!bubbleGrid[startRow][startCol] || bubbleGrid[startRow][startCol].color !== color) return [];
var matches = [bubbleGrid[startRow][startCol]];
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
if (startRow % 2 === 1) {
directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, 0], [-1, 1], [1, 0], [1, 1]];
}
for (var i = 0; i < 6; i++) {
// Check 6 neighbors for hexagonal
var newRow = startRow + directions[i][0];
var newCol = startCol + directions[i][1];
var neighborMatches = findMatchingBubbles(newRow, newCol, color, visited);
for (var j = 0; j < neighborMatches.length; j++) {
matches.push(neighborMatches[j]);
}
}
return matches;
}
function findFloatingBubbles() {
var visited = {};
var connected = {};
// Mark all bubbles connected to top row
for (var col = 0; col < GRID_WIDTH; col++) {
if (bubbleGrid[0][col]) {
markConnected(0, col, connected, visited);
}
}
// Find floating bubbles
var floating = [];
for (var row = 0; row < GRID_HEIGHT; row++) {
for (var col = 0; col < GRID_WIDTH; col++) {
if (bubbleGrid[row][col] && !connected[row + ',' + col]) {
floating.push(bubbleGrid[row][col]);
}
}
}
return floating;
}
function markConnected(row, col, connected, visited) {
var key = row + ',' + col;
if (visited[key]) return;
visited[key] = true;
if (row < 0 || row >= GRID_HEIGHT || col < 0 || col >= GRID_WIDTH) return;
if (!bubbleGrid[row][col]) return;
connected[key] = true;
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
for (var i = 0; i < 6; i++) {
var newRow = row + directions[i][0];
var newCol = col + directions[i][1];
markConnected(newRow, newCol, connected, visited);
}
}
function dropBubbles() {
// Move all bubbles down one row
for (var row = GRID_HEIGHT - 1; row > 0; row--) {
for (var col = 0; col < GRID_WIDTH; col++) {
bubbleGrid[row][col] = bubbleGrid[row - 1][col];
if (bubbleGrid[row][col]) {
bubbleGrid[row][col].gridY = row;
var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
bubbleGrid[row][col].x = GRID_OFFSET_X + col * BUBBLE_SPACING + offsetX;
bubbleGrid[row][col].y = GRID_OFFSET_Y + row * BUBBLE_SPACING;
}
}
}
// Add new row at top
for (var col = 0; col < GRID_WIDTH; col++) {
if (col === GRID_WIDTH - 1) {
bubbleGrid[0][col] = null;
continue;
}
var color = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
var bubble = new Bubble(color);
bubble.gridX = col;
bubble.gridY = 0;
bubble.x = GRID_OFFSET_X + col * BUBBLE_SPACING;
bubble.y = GRID_OFFSET_Y;
bubbleGrid[0][col] = bubble;
game.addChild(bubble);
}
// Check for game over
if (bubbleGrid[GRID_HEIGHT - 1].some(function (bubble) {
return bubble !== null;
})) {
LK.showGameOver();
}
}
game.down = function (x, y, obj) {
shooter.aimAt(x, y);
var bubble = shooter.shoot();
if (bubble) {
shooterBubbles.push(bubble);
game.addChild(bubble);
// Set next bubble color
nextBubbleColor = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
}
};
game.move = function (x, y, obj) {
shooter.aimAt(x, y);
};
game.update = function () {
// Update shooter bubbles
for (var i = shooterBubbles.length - 1; i >= 0; i--) {
var bubble = shooterBubbles[i];
// Check collision with grid bubbles
var collided = false;
for (var row = 0; row < GRID_HEIGHT && !collided; row++) {
for (var col = 0; col < GRID_WIDTH && !collided; col++) {
if (bubbleGrid[row][col] && bubble.intersects(bubbleGrid[row][col])) {
// Find nearest empty grid position
var gridPos = getGridPosition(bubble.x, bubble.y);
// Find empty spot near collision
var placed = false;
for (var checkRow = Math.max(0, gridPos.row - 1); checkRow <= Math.min(GRID_HEIGHT - 1, gridPos.row + 1) && !placed; checkRow++) {
for (var checkCol = Math.max(0, gridPos.col - 1); checkCol <= Math.min(GRID_WIDTH - 1, gridPos.col + 1) && !placed; checkCol++) {
if (!bubbleGrid[checkRow][checkCol]) {
var newBubble = new Bubble(bubble.color);
newBubble.gridX = checkCol;
newBubble.gridY = checkRow;
var offsetX = checkRow % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
newBubble.x = GRID_OFFSET_X + checkCol * BUBBLE_SPACING + offsetX;
newBubble.y = GRID_OFFSET_Y + checkRow * BUBBLE_SPACING;
bubbleGrid[checkRow][checkCol] = newBubble;
game.addChild(newBubble);
// Check for matches
var matches = findMatchingBubbles(checkRow, checkCol, bubble.color);
if (matches.length >= 3) {
LK.setScore(LK.getScore() + matches.length * 10);
scoreTxt.setText(LK.getScore());
for (var m = 0; m < matches.length; m++) {
bubbleGrid[matches[m].gridY][matches[m].gridX] = null;
matches[m].destroy();
}
// Drop floating bubbles
var floating = findFloatingBubbles();
for (var f = 0; f < floating.length; f++) {
bubbleGrid[floating[f].gridY][floating[f].gridX] = null;
floating[f].destroy();
}
LK.getSound('pop').play();
}
placed = true;
}
}
}
bubble.destroy();
shooterBubbles.splice(i, 1);
collided = true;
}
}
}
// Remove if hit top
if (bubble.y < 50) {
bubble.destroy();
shooterBubbles.splice(i, 1);
}
}
// Drop bubbles periodically
dropTimer++;
if (dropTimer >= dropInterval) {
dropBubbles();
dropTimer = 0;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,328 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Bubble = Container.expand(function (color) {
+ var self = Container.call(this);
+ self.color = color || 0x3498db;
+ self.colors = [0x3498db, 0xe74c3c, 0x2ecc71, 0xf39c12, 0x9b59b6];
+ var bubbleGraphics = self.attachAsset('gridBubble', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: self.color
+ });
+ var pkText = new Text2('PK', {
+ size: 24,
+ fill: 0xFFFFFF
+ });
+ pkText.anchor.set(0.5, 0.5);
+ self.addChild(pkText);
+ self.gridX = 0;
+ self.gridY = 0;
+ self.isMoving = false;
+ return self;
+});
+var Shooter = Container.expand(function () {
+ var self = Container.call(this);
+ var shooterBase = self.attachAsset('shooter', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.angle = 0;
+ self.canShoot = true;
+ self.shotsFired = 0;
+ self.maxConsecutiveShots = 2;
+ self.aimAt = function (targetX, targetY) {
+ var dx = targetX - self.x;
+ var dy = targetY - self.y;
+ self.angle = Math.atan2(dy, dx);
+ self.rotation = self.angle + Math.PI / 2;
+ };
+ self.shoot = function () {
+ if (!self.canShoot) return null;
+ var bubble = new ShooterBubble(nextBubbleColor);
+ bubble.x = self.x;
+ bubble.y = self.y - 50;
+ bubble.vx = Math.cos(self.angle) * bubble.speed;
+ bubble.vy = Math.sin(self.angle) * bubble.speed;
+ self.shotsFired++;
+ if (self.shotsFired >= self.maxConsecutiveShots) {
+ self.canShoot = false;
+ self.shotsFired = 0;
+ LK.setTimeout(function () {
+ self.canShoot = true;
+ }, 500);
+ }
+ LK.getSound('shoot').play();
+ return bubble;
+ };
+ return self;
+});
+var ShooterBubble = Container.expand(function (color) {
+ var self = Container.call(this);
+ self.color = color;
+ self.speed = 15;
+ self.vx = 0;
+ self.vy = -15;
+ var bubbleGraphics = self.attachAsset('shooterBubble', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: color
+ });
+ var pkText = new Text2('PK', {
+ size: 20,
+ fill: 0xFFFFFF
+ });
+ pkText.anchor.set(0.5, 0.5);
+ self.addChild(pkText);
+ self.update = function () {
+ self.x += self.vx;
+ self.y += self.vy;
+ // Bounce off walls
+ if (self.x <= 40 || self.x >= 2008) {
+ self.vx *= -1;
+ if (self.x <= 40) self.x = 40;
+ if (self.x >= 2008) self.x = 2008;
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x2c3e50
+});
+
+/****
+* Game Code
+****/
+var GRID_WIDTH = 15;
+var GRID_HEIGHT = 20;
+var BUBBLE_SIZE = 70;
+var BUBBLE_SPACING = 75;
+var GRID_OFFSET_X = (2048 - GRID_WIDTH * BUBBLE_SPACING) / 2;
+var GRID_OFFSET_Y = 100;
+var bubbleColors = [0x3498db, 0xe74c3c, 0x2ecc71, 0xf39c12, 0x9b59b6];
+var bubbleGrid = [];
+var shooterBubbles = [];
+var nextBubbleColor = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
+var dropTimer = 0;
+var dropInterval = 600; // 10 seconds at 60fps
+// Initialize bubble grid
+for (var row = 0; row < GRID_HEIGHT; row++) {
+ bubbleGrid[row] = [];
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ bubbleGrid[row][col] = null;
+ }
+}
+// Add initial bubbles
+for (var row = 0; row < 8; row++) {
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ if (row % 2 === 1 && col === GRID_WIDTH - 1) continue; // Offset odd rows
+ var color = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
+ var bubble = new Bubble(color);
+ bubble.gridX = col;
+ bubble.gridY = row;
+ var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
+ bubble.x = GRID_OFFSET_X + col * BUBBLE_SPACING + offsetX;
+ bubble.y = GRID_OFFSET_Y + row * BUBBLE_SPACING;
+ bubbleGrid[row][col] = bubble;
+ game.addChild(bubble);
+ }
+}
+// Create shooter
+var shooter = new Shooter();
+shooter.x = 2048 / 2;
+shooter.y = 2732 - 150;
+game.addChild(shooter);
+// Score display
+var scoreTxt = new Text2('0', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+function getGridPosition(x, y) {
+ var row = Math.round((y - GRID_OFFSET_Y) / BUBBLE_SPACING);
+ var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
+ var col = Math.round((x - GRID_OFFSET_X - offsetX) / BUBBLE_SPACING);
+ return {
+ row: row,
+ col: col
+ };
+}
+function findMatchingBubbles(startRow, startCol, color, visited) {
+ if (!visited) visited = {};
+ var key = startRow + ',' + startCol;
+ if (visited[key]) return [];
+ visited[key] = true;
+ if (startRow < 0 || startRow >= GRID_HEIGHT || startCol < 0 || startCol >= GRID_WIDTH) return [];
+ if (!bubbleGrid[startRow][startCol] || bubbleGrid[startRow][startCol].color !== color) return [];
+ var matches = [bubbleGrid[startRow][startCol]];
+ var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
+ if (startRow % 2 === 1) {
+ directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, 0], [-1, 1], [1, 0], [1, 1]];
+ }
+ for (var i = 0; i < 6; i++) {
+ // Check 6 neighbors for hexagonal
+ var newRow = startRow + directions[i][0];
+ var newCol = startCol + directions[i][1];
+ var neighborMatches = findMatchingBubbles(newRow, newCol, color, visited);
+ for (var j = 0; j < neighborMatches.length; j++) {
+ matches.push(neighborMatches[j]);
+ }
+ }
+ return matches;
+}
+function findFloatingBubbles() {
+ var visited = {};
+ var connected = {};
+ // Mark all bubbles connected to top row
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ if (bubbleGrid[0][col]) {
+ markConnected(0, col, connected, visited);
+ }
+ }
+ // Find floating bubbles
+ var floating = [];
+ for (var row = 0; row < GRID_HEIGHT; row++) {
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ if (bubbleGrid[row][col] && !connected[row + ',' + col]) {
+ floating.push(bubbleGrid[row][col]);
+ }
+ }
+ }
+ return floating;
+}
+function markConnected(row, col, connected, visited) {
+ var key = row + ',' + col;
+ if (visited[key]) return;
+ visited[key] = true;
+ if (row < 0 || row >= GRID_HEIGHT || col < 0 || col >= GRID_WIDTH) return;
+ if (!bubbleGrid[row][col]) return;
+ connected[key] = true;
+ var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
+ for (var i = 0; i < 6; i++) {
+ var newRow = row + directions[i][0];
+ var newCol = col + directions[i][1];
+ markConnected(newRow, newCol, connected, visited);
+ }
+}
+function dropBubbles() {
+ // Move all bubbles down one row
+ for (var row = GRID_HEIGHT - 1; row > 0; row--) {
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ bubbleGrid[row][col] = bubbleGrid[row - 1][col];
+ if (bubbleGrid[row][col]) {
+ bubbleGrid[row][col].gridY = row;
+ var offsetX = row % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
+ bubbleGrid[row][col].x = GRID_OFFSET_X + col * BUBBLE_SPACING + offsetX;
+ bubbleGrid[row][col].y = GRID_OFFSET_Y + row * BUBBLE_SPACING;
+ }
+ }
+ }
+ // Add new row at top
+ for (var col = 0; col < GRID_WIDTH; col++) {
+ if (col === GRID_WIDTH - 1) {
+ bubbleGrid[0][col] = null;
+ continue;
+ }
+ var color = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
+ var bubble = new Bubble(color);
+ bubble.gridX = col;
+ bubble.gridY = 0;
+ bubble.x = GRID_OFFSET_X + col * BUBBLE_SPACING;
+ bubble.y = GRID_OFFSET_Y;
+ bubbleGrid[0][col] = bubble;
+ game.addChild(bubble);
+ }
+ // Check for game over
+ if (bubbleGrid[GRID_HEIGHT - 1].some(function (bubble) {
+ return bubble !== null;
+ })) {
+ LK.showGameOver();
+ }
+}
+game.down = function (x, y, obj) {
+ shooter.aimAt(x, y);
+ var bubble = shooter.shoot();
+ if (bubble) {
+ shooterBubbles.push(bubble);
+ game.addChild(bubble);
+ // Set next bubble color
+ nextBubbleColor = bubbleColors[Math.floor(Math.random() * bubbleColors.length)];
+ }
+};
+game.move = function (x, y, obj) {
+ shooter.aimAt(x, y);
+};
+game.update = function () {
+ // Update shooter bubbles
+ for (var i = shooterBubbles.length - 1; i >= 0; i--) {
+ var bubble = shooterBubbles[i];
+ // Check collision with grid bubbles
+ var collided = false;
+ for (var row = 0; row < GRID_HEIGHT && !collided; row++) {
+ for (var col = 0; col < GRID_WIDTH && !collided; col++) {
+ if (bubbleGrid[row][col] && bubble.intersects(bubbleGrid[row][col])) {
+ // Find nearest empty grid position
+ var gridPos = getGridPosition(bubble.x, bubble.y);
+ // Find empty spot near collision
+ var placed = false;
+ for (var checkRow = Math.max(0, gridPos.row - 1); checkRow <= Math.min(GRID_HEIGHT - 1, gridPos.row + 1) && !placed; checkRow++) {
+ for (var checkCol = Math.max(0, gridPos.col - 1); checkCol <= Math.min(GRID_WIDTH - 1, gridPos.col + 1) && !placed; checkCol++) {
+ if (!bubbleGrid[checkRow][checkCol]) {
+ var newBubble = new Bubble(bubble.color);
+ newBubble.gridX = checkCol;
+ newBubble.gridY = checkRow;
+ var offsetX = checkRow % 2 === 1 ? BUBBLE_SPACING / 2 : 0;
+ newBubble.x = GRID_OFFSET_X + checkCol * BUBBLE_SPACING + offsetX;
+ newBubble.y = GRID_OFFSET_Y + checkRow * BUBBLE_SPACING;
+ bubbleGrid[checkRow][checkCol] = newBubble;
+ game.addChild(newBubble);
+ // Check for matches
+ var matches = findMatchingBubbles(checkRow, checkCol, bubble.color);
+ if (matches.length >= 3) {
+ LK.setScore(LK.getScore() + matches.length * 10);
+ scoreTxt.setText(LK.getScore());
+ for (var m = 0; m < matches.length; m++) {
+ bubbleGrid[matches[m].gridY][matches[m].gridX] = null;
+ matches[m].destroy();
+ }
+ // Drop floating bubbles
+ var floating = findFloatingBubbles();
+ for (var f = 0; f < floating.length; f++) {
+ bubbleGrid[floating[f].gridY][floating[f].gridX] = null;
+ floating[f].destroy();
+ }
+ LK.getSound('pop').play();
+ }
+ placed = true;
+ }
+ }
+ }
+ bubble.destroy();
+ shooterBubbles.splice(i, 1);
+ collided = true;
+ }
+ }
+ }
+ // Remove if hit top
+ if (bubble.y < 50) {
+ bubble.destroy();
+ shooterBubbles.splice(i, 1);
+ }
+ }
+ // Drop bubbles periodically
+ dropTimer++;
+ if (dropTimer >= dropInterval) {
+ dropBubbles();
+ dropTimer = 0;
+ }
+};
\ No newline at end of file