Code edit (1 edits merged)
Please save this source code
User prompt
Powerpuff Rocket Adventure
Initial prompt
Toca flying rocket 🚀 (2016). The powerpuff girls are in a rocket 🚀. 5 4 3 2 1 blast off! Choose level 1 space, level 2 Saturn, or level 3 earth to get started, press the up or down button to make the rocket go up or down.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BackgroundElement = Container.expand(function (type) {
var self = Container.call(this);
var bgGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -2;
self.update = function () {
self.x += self.speed;
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5;
self.update = function () {
self.x += self.speed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5;
self.update = function () {
self.x += self.speed;
// Gentle floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
};
return self;
});
var Rocket = Container.expand(function () {
var self = Container.call(this);
var rocketGraphics = self.attachAsset('rocket', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.verticalSpeed = 0;
self.maxVerticalSpeed = 8;
self.acceleration = 0.3;
self.deceleration = 0.2;
self.update = function () {
// Continuous forward movement
self.x += self.speed;
// Apply vertical movement with deceleration
if (self.verticalSpeed > 0) {
self.verticalSpeed -= self.deceleration;
if (self.verticalSpeed < 0) self.verticalSpeed = 0;
} else if (self.verticalSpeed < 0) {
self.verticalSpeed += self.deceleration;
if (self.verticalSpeed > 0) self.verticalSpeed = 0;
}
self.y += self.verticalSpeed;
// Keep rocket within screen bounds
if (self.y < 100) self.y = 100;
if (self.y > 2632) self.y = 2632;
};
self.moveUp = function () {
self.verticalSpeed = -self.maxVerticalSpeed;
};
self.moveDown = function () {
self.verticalSpeed = self.maxVerticalSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Sound effects
// Level selection buttons
// UI elements
// Background elements
// Power-ups
// Obstacles for different environments
// Rocket ship
// Game state variables
var gameState = 'levelSelect'; // 'levelSelect', 'countdown', 'playing', 'gameOver'
var currentLevel = '';
var countdownTimer = 0;
var countdownValue = 5;
var spawnTimer = 0;
var backgroundTimer = 0;
var distance = 0;
// Game objects
var rocket = null;
var obstacles = [];
var powerUps = [];
var backgroundElements = [];
// UI elements
var upButton = null;
var downButton = null;
var spaceButton = null;
var saturnButton = null;
var earthButton = null;
// Score and UI text
var scoreText = new Text2('Score: 0', {
size: 60,
fill: '#FFFFFF'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var countdownText = new Text2('', {
size: 200,
fill: '#FFFF00'
});
countdownText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(countdownText);
var levelText = new Text2('Select Level', {
size: 80,
fill: '#FFFFFF'
});
levelText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(levelText);
// Initialize level selection
function initLevelSelect() {
gameState = 'levelSelect';
// Create level selection buttons
spaceButton = game.addChild(LK.getAsset('spaceButton', {
anchorX: 0.5,
anchorY: 0.5
}));
spaceButton.x = 1024;
spaceButton.y = 1200;
saturnButton = game.addChild(LK.getAsset('saturnButton', {
anchorX: 0.5,
anchorY: 0.5
}));
saturnButton.x = 1024;
saturnButton.y = 1400;
earthButton = game.addChild(LK.getAsset('earthButton', {
anchorX: 0.5,
anchorY: 0.5
}));
earthButton.x = 1024;
earthButton.y = 1600;
// Add button labels
var spaceText = new Text2('SPACE', {
size: 50,
fill: '#FFFFFF'
});
spaceText.anchor.set(0.5, 0.5);
spaceButton.addChild(spaceText);
var saturnText = new Text2('SATURN', {
size: 50,
fill: '#FFFFFF'
});
saturnText.anchor.set(0.5, 0.5);
saturnButton.addChild(saturnText);
var earthText = new Text2('EARTH', {
size: 50,
fill: '#FFFFFF'
});
earthText.anchor.set(0.5, 0.5);
earthButton.addChild(earthText);
levelText.setText('Select Level');
}
// Start countdown sequence
function startCountdown(level) {
currentLevel = level;
gameState = 'countdown';
countdownTimer = 0;
countdownValue = 5;
// Clear level selection
if (spaceButton) {
spaceButton.destroy();
spaceButton = null;
}
if (saturnButton) {
saturnButton.destroy();
saturnButton = null;
}
if (earthButton) {
earthButton.destroy();
earthButton = null;
}
levelText.setText('');
// Set background color based on level
switch (level) {
case 'space':
game.setBackgroundColor(0x000033);
break;
case 'saturn':
game.setBackgroundColor(0x4B0082);
break;
case 'earth':
game.setBackgroundColor(0x87CEEB);
break;
}
}
// Initialize gameplay
function initGameplay() {
gameState = 'playing';
countdownText.setText('');
// Create rocket
rocket = game.addChild(new Rocket());
rocket.x = 300;
rocket.y = 1366;
// Create control buttons
upButton = game.addChild(LK.getAsset('upButton', {
anchorX: 0.5,
anchorY: 0.5
}));
upButton.x = 1800;
upButton.y = 1000;
downButton = game.addChild(LK.getAsset('downButton', {
anchorX: 0.5,
anchorY: 0.5
}));
downButton.x = 1800;
downButton.y = 1600;
// Add button labels
var upText = new Text2('UP', {
size: 40,
fill: '#FFFFFF'
});
upText.anchor.set(0.5, 0.5);
upButton.addChild(upText);
var downText = new Text2('DOWN', {
size: 40,
fill: '#FFFFFF'
});
downText.anchor.set(0.5, 0.5);
downButton.addChild(downText);
// Reset game variables
distance = 0;
spawnTimer = 0;
backgroundTimer = 0;
obstacles = [];
powerUps = [];
backgroundElements = [];
LK.setScore(0);
scoreText.setText('Score: 0');
LK.getSound('rocket').play();
}
// Spawn obstacles based on current level
function spawnObstacle() {
var obstacleType = '';
var yPosition = Math.random() * (2632 - 200) + 100;
switch (currentLevel) {
case 'space':
obstacleType = 'spaceObstacle';
break;
case 'saturn':
obstacleType = 'saturnObstacle';
break;
case 'earth':
obstacleType = 'earthObstacle';
break;
}
var obstacle = game.addChild(new Obstacle(obstacleType));
obstacle.x = 2148;
obstacle.y = yPosition;
obstacles.push(obstacle);
}
// Spawn power-ups
function spawnPowerUp() {
var powerUp = game.addChild(new PowerUp());
powerUp.x = 2148;
powerUp.y = Math.random() * (2632 - 200) + 100;
powerUps.push(powerUp);
}
// Spawn background elements
function spawnBackground() {
var bgType = '';
var yPosition = Math.random() * 2732;
switch (currentLevel) {
case 'space':
bgType = 'star';
break;
case 'saturn':
bgType = 'saturnRing';
break;
case 'earth':
bgType = 'cloud';
break;
}
var bgElement = game.addChild(new BackgroundElement(bgType));
bgElement.x = 2148;
bgElement.y = yPosition;
backgroundElements.push(bgElement);
}
// Button event handlers
game.down = function (x, y, obj) {
if (gameState === 'levelSelect') {
var gamePos = game.toLocal(obj.parent.toGlobal(obj.position));
if (spaceButton && spaceButton.intersects({
x: gamePos.x,
y: gamePos.y,
width: 1,
height: 1
})) {
startCountdown('space');
} else if (saturnButton && saturnButton.intersects({
x: gamePos.x,
y: gamePos.y,
width: 1,
height: 1
})) {
startCountdown('saturn');
} else if (earthButton && earthButton.intersects({
x: gamePos.x,
y: gamePos.y,
width: 1,
height: 1
})) {
startCountdown('earth');
}
} else if (gameState === 'playing') {
var gamePos = game.toLocal(obj.parent.toGlobal(obj.position));
if (upButton && upButton.intersects({
x: gamePos.x,
y: gamePos.y,
width: 1,
height: 1
})) {
rocket.moveUp();
} else if (downButton && downButton.intersects({
x: gamePos.x,
y: gamePos.y,
width: 1,
height: 1
})) {
rocket.moveDown();
}
}
};
// Main game update loop
game.update = function () {
if (gameState === 'countdown') {
countdownTimer++;
if (countdownTimer % 60 === 0) {
// Every second
if (countdownValue > 0) {
countdownText.setText(countdownValue.toString());
LK.getSound('countdown').play();
countdownValue--;
} else {
countdownText.setText('BLAST OFF!');
LK.setTimeout(function () {
initGameplay();
}, 1000);
}
}
} else if (gameState === 'playing') {
distance++;
// Update score based on distance
if (distance % 60 === 0) {
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
}
// Spawn obstacles
var spawnRate = 180; // Base spawn rate
if (currentLevel === 'saturn') spawnRate = 150;
if (currentLevel === 'earth') spawnRate = 120;
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnObstacle();
spawnTimer = 0;
}
// Spawn power-ups occasionally
if (LK.ticks % 300 === 0) {
spawnPowerUp();
}
// Spawn background elements
backgroundTimer++;
if (backgroundTimer >= 120) {
spawnBackground();
backgroundTimer = 0;
}
// Check obstacle collisions
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.x < -100) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
if (rocket && rocket.intersects(obstacle)) {
LK.showGameOver();
return;
}
}
// Check power-up collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.x < -100) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
if (rocket && rocket.intersects(powerUp)) {
LK.setScore(LK.getScore() + 50);
scoreText.setText('Score: ' + LK.getScore());
LK.getSound('collect').play();
powerUp.destroy();
powerUps.splice(i, 1);
}
}
// Clean up background elements
for (var i = backgroundElements.length - 1; i >= 0; i--) {
var bgElement = backgroundElements[i];
if (bgElement.x < -200) {
bgElement.destroy();
backgroundElements.splice(i, 1);
}
}
// Check if rocket went off screen
if (rocket && rocket.x < -100) {
LK.showGameOver();
}
}
};
// Initialize level selection on start
initLevelSelect(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,438 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var BackgroundElement = Container.expand(function (type) {
+ var self = Container.call(this);
+ var bgGraphics = self.attachAsset(type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -2;
+ self.update = function () {
+ self.x += self.speed;
+ };
+ return self;
+});
+var Obstacle = Container.expand(function (type) {
+ var self = Container.call(this);
+ var obstacleGraphics = self.attachAsset(type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -5;
+ self.update = function () {
+ self.x += self.speed;
+ };
+ return self;
+});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ var powerUpGraphics = self.attachAsset('powerUp', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = -5;
+ self.update = function () {
+ self.x += self.speed;
+ // Gentle floating animation
+ self.y += Math.sin(LK.ticks * 0.1) * 0.5;
+ };
+ return self;
+});
+var Rocket = Container.expand(function () {
+ var self = Container.call(this);
+ var rocketGraphics = self.attachAsset('rocket', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3;
+ self.verticalSpeed = 0;
+ self.maxVerticalSpeed = 8;
+ self.acceleration = 0.3;
+ self.deceleration = 0.2;
+ self.update = function () {
+ // Continuous forward movement
+ self.x += self.speed;
+ // Apply vertical movement with deceleration
+ if (self.verticalSpeed > 0) {
+ self.verticalSpeed -= self.deceleration;
+ if (self.verticalSpeed < 0) self.verticalSpeed = 0;
+ } else if (self.verticalSpeed < 0) {
+ self.verticalSpeed += self.deceleration;
+ if (self.verticalSpeed > 0) self.verticalSpeed = 0;
+ }
+ self.y += self.verticalSpeed;
+ // Keep rocket within screen bounds
+ if (self.y < 100) self.y = 100;
+ if (self.y > 2632) self.y = 2632;
+ };
+ self.moveUp = function () {
+ self.verticalSpeed = -self.maxVerticalSpeed;
+ };
+ self.moveDown = function () {
+ self.verticalSpeed = self.maxVerticalSpeed;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x000033
+});
+
+/****
+* Game Code
+****/
+// Sound effects
+// Level selection buttons
+// UI elements
+// Background elements
+// Power-ups
+// Obstacles for different environments
+// Rocket ship
+// Game state variables
+var gameState = 'levelSelect'; // 'levelSelect', 'countdown', 'playing', 'gameOver'
+var currentLevel = '';
+var countdownTimer = 0;
+var countdownValue = 5;
+var spawnTimer = 0;
+var backgroundTimer = 0;
+var distance = 0;
+// Game objects
+var rocket = null;
+var obstacles = [];
+var powerUps = [];
+var backgroundElements = [];
+// UI elements
+var upButton = null;
+var downButton = null;
+var spaceButton = null;
+var saturnButton = null;
+var earthButton = null;
+// Score and UI text
+var scoreText = new Text2('Score: 0', {
+ size: 60,
+ fill: '#FFFFFF'
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+var countdownText = new Text2('', {
+ size: 200,
+ fill: '#FFFF00'
+});
+countdownText.anchor.set(0.5, 0.5);
+LK.gui.center.addChild(countdownText);
+var levelText = new Text2('Select Level', {
+ size: 80,
+ fill: '#FFFFFF'
+});
+levelText.anchor.set(0.5, 0.5);
+LK.gui.center.addChild(levelText);
+// Initialize level selection
+function initLevelSelect() {
+ gameState = 'levelSelect';
+ // Create level selection buttons
+ spaceButton = game.addChild(LK.getAsset('spaceButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ spaceButton.x = 1024;
+ spaceButton.y = 1200;
+ saturnButton = game.addChild(LK.getAsset('saturnButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ saturnButton.x = 1024;
+ saturnButton.y = 1400;
+ earthButton = game.addChild(LK.getAsset('earthButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ earthButton.x = 1024;
+ earthButton.y = 1600;
+ // Add button labels
+ var spaceText = new Text2('SPACE', {
+ size: 50,
+ fill: '#FFFFFF'
+ });
+ spaceText.anchor.set(0.5, 0.5);
+ spaceButton.addChild(spaceText);
+ var saturnText = new Text2('SATURN', {
+ size: 50,
+ fill: '#FFFFFF'
+ });
+ saturnText.anchor.set(0.5, 0.5);
+ saturnButton.addChild(saturnText);
+ var earthText = new Text2('EARTH', {
+ size: 50,
+ fill: '#FFFFFF'
+ });
+ earthText.anchor.set(0.5, 0.5);
+ earthButton.addChild(earthText);
+ levelText.setText('Select Level');
+}
+// Start countdown sequence
+function startCountdown(level) {
+ currentLevel = level;
+ gameState = 'countdown';
+ countdownTimer = 0;
+ countdownValue = 5;
+ // Clear level selection
+ if (spaceButton) {
+ spaceButton.destroy();
+ spaceButton = null;
+ }
+ if (saturnButton) {
+ saturnButton.destroy();
+ saturnButton = null;
+ }
+ if (earthButton) {
+ earthButton.destroy();
+ earthButton = null;
+ }
+ levelText.setText('');
+ // Set background color based on level
+ switch (level) {
+ case 'space':
+ game.setBackgroundColor(0x000033);
+ break;
+ case 'saturn':
+ game.setBackgroundColor(0x4B0082);
+ break;
+ case 'earth':
+ game.setBackgroundColor(0x87CEEB);
+ break;
+ }
+}
+// Initialize gameplay
+function initGameplay() {
+ gameState = 'playing';
+ countdownText.setText('');
+ // Create rocket
+ rocket = game.addChild(new Rocket());
+ rocket.x = 300;
+ rocket.y = 1366;
+ // Create control buttons
+ upButton = game.addChild(LK.getAsset('upButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ upButton.x = 1800;
+ upButton.y = 1000;
+ downButton = game.addChild(LK.getAsset('downButton', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ }));
+ downButton.x = 1800;
+ downButton.y = 1600;
+ // Add button labels
+ var upText = new Text2('UP', {
+ size: 40,
+ fill: '#FFFFFF'
+ });
+ upText.anchor.set(0.5, 0.5);
+ upButton.addChild(upText);
+ var downText = new Text2('DOWN', {
+ size: 40,
+ fill: '#FFFFFF'
+ });
+ downText.anchor.set(0.5, 0.5);
+ downButton.addChild(downText);
+ // Reset game variables
+ distance = 0;
+ spawnTimer = 0;
+ backgroundTimer = 0;
+ obstacles = [];
+ powerUps = [];
+ backgroundElements = [];
+ LK.setScore(0);
+ scoreText.setText('Score: 0');
+ LK.getSound('rocket').play();
+}
+// Spawn obstacles based on current level
+function spawnObstacle() {
+ var obstacleType = '';
+ var yPosition = Math.random() * (2632 - 200) + 100;
+ switch (currentLevel) {
+ case 'space':
+ obstacleType = 'spaceObstacle';
+ break;
+ case 'saturn':
+ obstacleType = 'saturnObstacle';
+ break;
+ case 'earth':
+ obstacleType = 'earthObstacle';
+ break;
+ }
+ var obstacle = game.addChild(new Obstacle(obstacleType));
+ obstacle.x = 2148;
+ obstacle.y = yPosition;
+ obstacles.push(obstacle);
+}
+// Spawn power-ups
+function spawnPowerUp() {
+ var powerUp = game.addChild(new PowerUp());
+ powerUp.x = 2148;
+ powerUp.y = Math.random() * (2632 - 200) + 100;
+ powerUps.push(powerUp);
+}
+// Spawn background elements
+function spawnBackground() {
+ var bgType = '';
+ var yPosition = Math.random() * 2732;
+ switch (currentLevel) {
+ case 'space':
+ bgType = 'star';
+ break;
+ case 'saturn':
+ bgType = 'saturnRing';
+ break;
+ case 'earth':
+ bgType = 'cloud';
+ break;
+ }
+ var bgElement = game.addChild(new BackgroundElement(bgType));
+ bgElement.x = 2148;
+ bgElement.y = yPosition;
+ backgroundElements.push(bgElement);
+}
+// Button event handlers
+game.down = function (x, y, obj) {
+ if (gameState === 'levelSelect') {
+ var gamePos = game.toLocal(obj.parent.toGlobal(obj.position));
+ if (spaceButton && spaceButton.intersects({
+ x: gamePos.x,
+ y: gamePos.y,
+ width: 1,
+ height: 1
+ })) {
+ startCountdown('space');
+ } else if (saturnButton && saturnButton.intersects({
+ x: gamePos.x,
+ y: gamePos.y,
+ width: 1,
+ height: 1
+ })) {
+ startCountdown('saturn');
+ } else if (earthButton && earthButton.intersects({
+ x: gamePos.x,
+ y: gamePos.y,
+ width: 1,
+ height: 1
+ })) {
+ startCountdown('earth');
+ }
+ } else if (gameState === 'playing') {
+ var gamePos = game.toLocal(obj.parent.toGlobal(obj.position));
+ if (upButton && upButton.intersects({
+ x: gamePos.x,
+ y: gamePos.y,
+ width: 1,
+ height: 1
+ })) {
+ rocket.moveUp();
+ } else if (downButton && downButton.intersects({
+ x: gamePos.x,
+ y: gamePos.y,
+ width: 1,
+ height: 1
+ })) {
+ rocket.moveDown();
+ }
+ }
+};
+// Main game update loop
+game.update = function () {
+ if (gameState === 'countdown') {
+ countdownTimer++;
+ if (countdownTimer % 60 === 0) {
+ // Every second
+ if (countdownValue > 0) {
+ countdownText.setText(countdownValue.toString());
+ LK.getSound('countdown').play();
+ countdownValue--;
+ } else {
+ countdownText.setText('BLAST OFF!');
+ LK.setTimeout(function () {
+ initGameplay();
+ }, 1000);
+ }
+ }
+ } else if (gameState === 'playing') {
+ distance++;
+ // Update score based on distance
+ if (distance % 60 === 0) {
+ LK.setScore(LK.getScore() + 10);
+ scoreText.setText('Score: ' + LK.getScore());
+ }
+ // Spawn obstacles
+ var spawnRate = 180; // Base spawn rate
+ if (currentLevel === 'saturn') spawnRate = 150;
+ if (currentLevel === 'earth') spawnRate = 120;
+ spawnTimer++;
+ if (spawnTimer >= spawnRate) {
+ spawnObstacle();
+ spawnTimer = 0;
+ }
+ // Spawn power-ups occasionally
+ if (LK.ticks % 300 === 0) {
+ spawnPowerUp();
+ }
+ // Spawn background elements
+ backgroundTimer++;
+ if (backgroundTimer >= 120) {
+ spawnBackground();
+ backgroundTimer = 0;
+ }
+ // Check obstacle collisions
+ for (var i = obstacles.length - 1; i >= 0; i--) {
+ var obstacle = obstacles[i];
+ if (obstacle.x < -100) {
+ obstacle.destroy();
+ obstacles.splice(i, 1);
+ continue;
+ }
+ if (rocket && rocket.intersects(obstacle)) {
+ LK.showGameOver();
+ return;
+ }
+ }
+ // Check power-up collisions
+ for (var i = powerUps.length - 1; i >= 0; i--) {
+ var powerUp = powerUps[i];
+ if (powerUp.x < -100) {
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ continue;
+ }
+ if (rocket && rocket.intersects(powerUp)) {
+ LK.setScore(LK.getScore() + 50);
+ scoreText.setText('Score: ' + LK.getScore());
+ LK.getSound('collect').play();
+ powerUp.destroy();
+ powerUps.splice(i, 1);
+ }
+ }
+ // Clean up background elements
+ for (var i = backgroundElements.length - 1; i >= 0; i--) {
+ var bgElement = backgroundElements[i];
+ if (bgElement.x < -200) {
+ bgElement.destroy();
+ backgroundElements.splice(i, 1);
+ }
+ }
+ // Check if rocket went off screen
+ if (rocket && rocket.x < -100) {
+ LK.showGameOver();
+ }
+ }
+};
+// Initialize level selection on start
+initLevelSelect();
\ No newline at end of file