Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
game-stydy
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
谌继荃
game-stydy
Commits
c19ec7c9
Commit
c19ec7c9
authored
Nov 29, 2021
by
谌继荃
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初始化项目
parent
6a30f9f6
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
784 additions
and
734 deletions
+784
-734
bundle.js
dist/bundle.js
+95
-95
package.json
package.json
+13
-13
bundle.js
public/bundle.js
+95
-95
index.html
public/index.html
+40
-40
DragDropEvent.ts
src/dragdrop/DragDropEvent.ts
+3
-3
DragDropManager.ts
src/dragdrop/DragDropManager.ts
+41
-41
DragDropable.ts
src/dragdrop/DragDropable.ts
+47
-47
Movable.ts
src/lib/Movable.ts
+26
-15
MovableManager.ts
src/lib/MovableManager.ts
+124
-115
Vector2.ts
src/lib/Vector2.ts
+9
-9
main.ts
src/main.ts
+30
-30
Background.ts
src/planewar/Background.ts
+42
-42
Enemy.ts
src/planewar/Enemy.ts
+48
-39
EnemyFactory.ts
src/planewar/EnemyFactory.ts
+29
-25
Hero.ts
src/planewar/Hero.ts
+45
-35
addGame.ts
src/planewar/addGame.ts
+34
-28
Bullet.ts
src/weapon/Bullet.ts
+8
-8
IWeaponHost.ts
src/weapon/IWeaponHost.ts
+10
-9
Weapon.ts
src/weapon/Weapon.ts
+45
-45
No files found.
dist/bundle.js
View file @
c19ec7c9
package.json
View file @
c19ec7c9
public/bundle.js
View file @
c19ec7c9
public/index.html
View file @
c19ec7c9
src/dragdrop/DragDropEvent.ts
View file @
c19ec7c9
src/dragdrop/DragDropManager.ts
View file @
c19ec7c9
src/dragdrop/DragDropable.ts
View file @
c19ec7c9
src/lib/Movable.ts
View file @
c19ec7c9
...
@@ -5,10 +5,21 @@ export default class Movable extends FYGE.Sprite {
...
@@ -5,10 +5,21 @@ export default class Movable extends FYGE.Sprite {
return
true
;
return
true
;
}
}
private
_velocity
:
Vector2
;
private
_velocity
:
Vector2
;
set
velocity
(
val
:
Vector2
)
{
set
velocity
(
val
:
Vector2
)
{
this
.
_velocity
=
val
}
this
.
_velocity
=
val
;
}
get
velocity
()
{
return
this
.
_velocity
;
}
private
_acceleration
:
Vector2
;
set
acceleration
(
val
:
Vector2
)
{
this
.
_acceleration
=
val
;
}
step
()
{
step
()
{
this
.
_acceleration
=
this
.
_acceleration
||
new
Vector2
(
0
,
0
);
this
.
_velocity
.
x
+=
this
.
_acceleration
.
x
;
this
.
_velocity
.
y
+=
this
.
_acceleration
.
y
;
this
.
y
+=
this
.
_velocity
.
y
;
this
.
y
+=
this
.
_velocity
.
y
;
this
.
x
+=
this
.
_velocity
.
x
;
this
.
x
+=
this
.
_velocity
.
x
;
}
}
...
...
src/lib/MovableManager.ts
View file @
c19ec7c9
...
@@ -5,11 +5,13 @@ import Movable from "./Movable";
...
@@ -5,11 +5,13 @@ import Movable from "./Movable";
export
default
class
MovableManager
extends
FYGE
.
EventDispatcher
{
export
default
class
MovableManager
extends
FYGE
.
EventDispatcher
{
private
_stage
:
FYGE
.
Stage
;
private
_stage
:
FYGE
.
Stage
;
public
Score
:
0
;
private
_movableList
:
Movable
[]
=
[];
private
_movableList
:
Movable
[]
=
[];
hero
:
Hero
;
hero
:
Hero
;
constructor
(
stage
:
FYGE
.
Stage
)
{
constructor
(
stage
:
FYGE
.
Stage
)
{
super
();
super
();
this
.
_stage
=
stage
;
this
.
_stage
=
stage
;
this
.
Score
=
0
;
this
.
_stage
.
addEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
this
.
onEnterFrame
);
this
.
_stage
.
addEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
this
.
onEnterFrame
);
}
}
...
@@ -20,16 +22,17 @@ export default class MovableManager extends FYGE.EventDispatcher {
...
@@ -20,16 +22,17 @@ export default class MovableManager extends FYGE.EventDispatcher {
this
.
checkHitByBullet
();
this
.
checkHitByBullet
();
this
.
checkHitByEnemy
();
this
.
checkHitByEnemy
();
// console.log('移动对象的数量:', this._movableList.length)
// console.log('移动对象的数量:', this._movableList.length)
}
};
checkHitByEnemy
()
{
checkHitByEnemy
()
{
const
enemyList
=
this
.
_movableList
.
filter
(
i
=>
i
instanceof
Enemy
);
const
enemyList
=
this
.
_movableList
.
filter
((
i
)
=>
i
instanceof
Enemy
);
for
(
let
i
=
0
;
i
<
enemyList
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
enemyList
.
length
;
i
++
)
{
const
oneEnemy
=
enemyList
[
i
];
const
oneEnemy
=
enemyList
[
i
];
if
(
this
.
checkHit
(
oneEnemy
,
this
.
hero
))
{
if
(
this
.
checkHit
(
oneEnemy
,
this
.
hero
))
{
console
.
log
(
'被敌机碰撞了,游戏结束了'
);
console
.
log
(
"被敌机碰撞了,游戏结束了"
);
this
.
gameOver
()
// this.Score = 0;
this
.
gameOver
();
return
;
return
;
}
}
}
}
...
@@ -37,31 +40,38 @@ export default class MovableManager extends FYGE.EventDispatcher {
...
@@ -37,31 +40,38 @@ export default class MovableManager extends FYGE.EventDispatcher {
private
gameOver
()
{
private
gameOver
()
{
this
.
_stage
.
removeEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
this
.
onEnterFrame
);
this
.
_stage
.
removeEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
this
.
onEnterFrame
);
this
.
dispatchEvent
(
'gameover'
);
this
.
dispatchEvent
(
"gameover"
);
}
}
checkHitByBullet
()
{
checkHitByBullet
()
{
const
enemyBulletList
=
this
.
_movableList
.
filter
(
i
=>
i
instanceof
Bullet
&&
i
.
host
instanceof
Enemy
);
const
enemyBulletList
=
this
.
_movableList
.
filter
(
(
i
)
=>
i
instanceof
Bullet
&&
i
.
host
instanceof
Enemy
);
for
(
let
j
=
0
;
j
<
enemyBulletList
.
length
;
j
++
)
{
for
(
let
j
=
0
;
j
<
enemyBulletList
.
length
;
j
++
)
{
const
bullet
=
enemyBulletList
[
j
];
const
bullet
=
enemyBulletList
[
j
];
if
(
this
.
checkHit
(
this
.
hero
,
bullet
))
{
if
(
this
.
checkHit
(
this
.
hero
,
bullet
))
{
console
.
log
(
'被子弹碰撞了,游戏结束了'
);
console
.
log
(
"被子弹碰撞了,游戏结束了"
);
this
.
gameOver
()
// this.Score = 0;
this
.
gameOver
();
return
;
return
;
}
}
}
}
}
}
private
checkHitEnemy
()
{
private
checkHitEnemy
()
{
const
heroBulletList
=
this
.
_movableList
.
filter
(
i
=>
i
instanceof
Bullet
&&
i
.
host
instanceof
Hero
);
const
heroBulletList
=
this
.
_movableList
.
filter
(
const
enemyList
=
this
.
_movableList
.
filter
(
i
=>
i
instanceof
Enemy
);
(
i
)
=>
i
instanceof
Bullet
&&
i
.
host
instanceof
Hero
);
const
enemyList
=
this
.
_movableList
.
filter
((
i
)
=>
i
instanceof
Enemy
);
for
(
let
i
=
0
;
i
<
enemyList
.
length
;
i
++
)
{
for
(
let
i
=
0
;
i
<
enemyList
.
length
;
i
++
)
{
const
oneEnemy
=
enemyList
[
i
];
const
oneEnemy
=
enemyList
[
i
];
for
(
let
j
=
0
;
j
<
heroBulletList
.
length
;
j
++
)
{
for
(
let
j
=
0
;
j
<
heroBulletList
.
length
;
j
++
)
{
const
onHeroBullet
=
heroBulletList
[
j
];
const
onHeroBullet
=
heroBulletList
[
j
];
if
(
this
.
checkHit
(
oneEnemy
,
onHeroBullet
))
{
if
(
this
.
checkHit
(
oneEnemy
,
onHeroBullet
))
{
this
.
Score
+=
10
;
this
.
remove
(
oneEnemy
);
this
.
remove
(
oneEnemy
);
this
.
remove
(
onHeroBullet
);
this
.
remove
(
onHeroBullet
);
console
.
log
(
"this.Score"
,
this
.
Score
);
return
;
return
;
}
}
}
}
...
@@ -99,7 +109,7 @@ export default class MovableManager extends FYGE.EventDispatcher {
...
@@ -99,7 +109,7 @@ export default class MovableManager extends FYGE.EventDispatcher {
}
}
private
step
()
{
private
step
()
{
this
.
_movableList
.
forEach
(
item
=>
item
.
step
());
this
.
_movableList
.
forEach
((
item
)
=>
item
.
step
());
}
}
add
(
item
:
Movable
)
{
add
(
item
:
Movable
)
{
...
@@ -111,5 +121,4 @@ export default class MovableManager extends FYGE.EventDispatcher {
...
@@ -111,5 +121,4 @@ export default class MovableManager extends FYGE.EventDispatcher {
this
.
_movableList
.
splice
(
index
,
1
);
this
.
_movableList
.
splice
(
index
,
1
);
item
.
parent
&&
item
.
parent
.
removeChild
(
item
);
item
.
parent
&&
item
.
parent
.
removeChild
(
item
);
}
}
}
}
src/lib/Vector2.ts
View file @
c19ec7c9
src/main.ts
View file @
c19ec7c9
src/planewar/Background.ts
View file @
c19ec7c9
...
@@ -7,7 +7,7 @@ class BackgroundItem extends Movable {
...
@@ -7,7 +7,7 @@ class BackgroundItem extends Movable {
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
"//yun.duiba.com.cn/aurora/assets/bd7b3b10169265123e52d02acf8739db5ff59b3d.png"
"//yun.duiba.com.cn/aurora/assets/bd7b3b10169265123e52d02acf8739db5ff59b3d.png"
);
);
this
.
velocity
=
new
Vector2
(
0
,
10
);
this
.
velocity
=
new
Vector2
(
0
,
5
);
}
}
getCanRemove
()
{
getCanRemove
()
{
return
false
;
return
false
;
...
@@ -29,8 +29,8 @@ export default class Background {
...
@@ -29,8 +29,8 @@ export default class Background {
bg2
.
y
=
height
;
bg2
.
y
=
height
;
stage
.
addEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
()
=>
{
stage
.
addEventListener
(
FYGE
.
Event
.
ENTER_FRAME
,
()
=>
{
console
.
log
(
"bg.y"
,
bg
.
y
);
// console.log("bg.y", bg.y);
console
.
log
(
"bg2.y"
,
bg2
.
y
);
// console.log("bg2.y", bg2.y);
if
(
bg
.
y
>
height
)
{
if
(
bg
.
y
>
height
)
{
bg
.
y
=
bg2
.
y
-
height
;
bg
.
y
=
bg2
.
y
-
height
;
}
}
...
...
src/planewar/Enemy.ts
View file @
c19ec7c9
...
@@ -4,7 +4,6 @@ import Vector2 from "../lib/Vector2";
...
@@ -4,7 +4,6 @@ import Vector2 from "../lib/Vector2";
import
{
IWeaponHost
}
from
"../weapon/IWeaponHost"
;
import
{
IWeaponHost
}
from
"../weapon/IWeaponHost"
;
import
Weapon
from
"../weapon/Weapon"
;
import
Weapon
from
"../weapon/Weapon"
;
export
default
class
Enemy
extends
Movable
implements
IWeaponHost
{
export
default
class
Enemy
extends
Movable
implements
IWeaponHost
{
movableManager
:
MovableManager
;
movableManager
:
MovableManager
;
constructor
(
movableManager
:
MovableManager
)
{
constructor
(
movableManager
:
MovableManager
)
{
...
@@ -13,7 +12,9 @@ export default class Enemy extends Movable implements IWeaponHost {
...
@@ -13,7 +12,9 @@ export default class Enemy extends Movable implements IWeaponHost {
movableManager
.
add
(
this
);
movableManager
.
add
(
this
);
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
'//yun.duiba.com.cn/aurora/assets/26e1539bb9c5961c693f05186b086c8e04f2f6a2.png'
)
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
"//yun.duiba.com.cn/aurora/assets/26e1539bb9c5961c693f05186b086c8e04f2f6a2.png"
);
const
weapon
=
new
Weapon
(
this
);
const
weapon
=
new
Weapon
(
this
);
...
@@ -26,14 +27,22 @@ export default class Enemy extends Movable implements IWeaponHost {
...
@@ -26,14 +27,22 @@ export default class Enemy extends Movable implements IWeaponHost {
this
.
addEventListener
(
FYGE
.
Event
.
REMOVED_FROM_STAGE
,
()
=>
{
this
.
addEventListener
(
FYGE
.
Event
.
REMOVED_FROM_STAGE
,
()
=>
{
// console.log('敌人消失了')
// console.log('敌人消失了')
weapon
.
destroy
();
weapon
.
destroy
();
})
});
}
}
getShootInterval
()
{
return
100
}
getShootInterval
()
{
return
50
;
}
getShootVelocity
()
{
return
new
Vector2
(
0
,
10
)
}
getShootVelocity
()
{
return
new
Vector2
(
0
,
10
);
}
getShootAcceleration
()
{
return
new
Vector2
(
0
,
0
);
}
getShootPoint
()
{
getShootPoint
()
{
return
new
FYGE
.
Point
(
this
.
x
+
this
.
width
/
2
,
this
.
y
+
this
.
height
)
return
new
FYGE
.
Point
(
this
.
x
+
this
.
width
/
2
,
this
.
y
+
this
.
height
);
}
}
}
}
src/planewar/EnemyFactory.ts
View file @
c19ec7c9
...
@@ -5,19 +5,23 @@ import Enemy from "./Enemy";
...
@@ -5,19 +5,23 @@ import Enemy from "./Enemy";
export
default
class
EnemyFactory
{
export
default
class
EnemyFactory
{
private
_timer
;
private
_timer
;
private
_stage
:
FYGE
.
Stage
;
private
_stage
:
FYGE
.
Stage
;
movableManager
:
MovableManager
movableManager
:
MovableManager
;
constructor
(
stage
:
FYGE
.
Stage
,
movableManager
:
MovableManager
)
{
constructor
(
stage
:
FYGE
.
Stage
,
movableManager
:
MovableManager
)
{
this
.
movableManager
=
movableManager
;
this
.
movableManager
=
movableManager
;
this
.
_stage
=
stage
;
this
.
_stage
=
stage
;
this
.
_timer
=
setInterval
(
this
.
onTimer
,
1000
)
this
.
_timer
=
setInterval
(
this
.
onTimer
,
1000
);
}
}
onTimer
=
()
=>
{
onTimer
=
()
=>
{
const
enemy
=
this
.
_stage
.
addChild
(
new
Enemy
(
this
.
movableManager
));
const
enemy
=
this
.
_stage
.
addChild
(
new
Enemy
(
this
.
movableManager
));
enemy
.
position
.
set
(
Math
.
random
()
*
300
+
200
,
0
);
enemy
.
position
.
set
(
Math
.
random
()
*
300
+
200
,
0
);
enemy
.
velocity
=
new
Vector2
((
Math
.
random
()
-
0.5
)
*
2
,
Math
.
random
()
*
5
+
2
);;
enemy
.
velocity
=
new
Vector2
(
}
(
Math
.
random
()
-
0.5
)
*
2
,
Math
.
random
()
*
5
+
2
);
enemy
.
acceleration
=
new
Vector2
(
0
,
0.1
);
};
destroy
()
{
destroy
()
{
clearInterval
(
this
.
_timer
);
clearInterval
(
this
.
_timer
);
...
...
src/planewar/Hero.ts
View file @
c19ec7c9
...
@@ -4,15 +4,15 @@ import Vector2 from "../lib/Vector2";
...
@@ -4,15 +4,15 @@ import Vector2 from "../lib/Vector2";
import
{
IWeaponHost
}
from
"../weapon/IWeaponHost"
;
import
{
IWeaponHost
}
from
"../weapon/IWeaponHost"
;
import
Weapon
from
"../weapon/Weapon"
;
import
Weapon
from
"../weapon/Weapon"
;
export
default
class
Hero
extends
DragDropable
implements
IWeaponHost
{
export
default
class
Hero
extends
DragDropable
implements
IWeaponHost
{
movableManager
:
MovableManager
;
movableManager
:
MovableManager
;
constructor
(
movableManager
)
{
constructor
(
movableManager
)
{
super
();
super
();
this
.
movableManager
=
movableManager
;
this
.
movableManager
=
movableManager
;
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
'//yun.duiba.com.cn/spark/assets/hero_fly1.f292cb1c04589c6ee395fe29538d5385540755f7.png'
);
this
.
texture
=
FYGE
.
Texture
.
fromUrl
(
"//yun.duiba.com.cn/spark/assets/hero_fly1.f292cb1c04589c6ee395fe29538d5385540755f7.png"
);
const
weapon
=
new
Weapon
(
this
);
const
weapon
=
new
Weapon
(
this
);
...
@@ -22,14 +22,24 @@ export default class Hero extends DragDropable implements IWeaponHost {
...
@@ -22,14 +22,24 @@ export default class Hero extends DragDropable implements IWeaponHost {
// bg.endFill()
// bg.endFill()
// this.addChild(bg)
// this.addChild(bg)
}
}
getShootInterval
(){
return
50
}
getShootInterval
()
{
getShootVelocity
(){
return
new
Vector2
(
0
,
-
20
)}
return
50
;
}
getShootVelocity
()
{
return
new
Vector2
(
0
,
-
20
);
}
getShootPoint
()
{
getShootPoint
()
{
return
new
FYGE
.
Point
(
this
.
x
+
this
.
width
/
2
,
this
.
y
)
return
new
FYGE
.
Point
(
this
.
x
+
this
.
width
/
2
,
this
.
y
);
}
}
getDropPoint
()
{
return
{}
}
getShootAcceleration
()
{
return
new
Vector2
(
0
,
0
);
}
getDropPoint
()
{
return
{};
}
onDragEnd
()
{
}
onDragEnd
()
{}
}
}
src/planewar/addGame.ts
View file @
c19ec7c9
...
@@ -11,7 +11,11 @@ export function addGame(stage: FYGE.Stage) {
...
@@ -11,7 +11,11 @@ export function addGame(stage: FYGE.Stage) {
const
background
=
new
Background
(
stage
,
movableManager
);
const
background
=
new
Background
(
stage
,
movableManager
);
const
hero
=
stage
.
addChild
(
new
Hero
(
movableManager
));
const
hero
=
stage
.
addChild
(
new
Hero
(
movableManager
));
// const hero2 = stage.addChild(new Hero(movableManager));
// const hero3 = stage.addChild(new Hero(movableManager));
hero
.
position
.
set
(
300
,
1000
);
hero
.
position
.
set
(
300
,
1000
);
// hero2.position.set(250, 1000);
// hero3.position.set(350, 1000);
const
enemyFactory
=
new
EnemyFactory
(
stage
,
movableManager
);
const
enemyFactory
=
new
EnemyFactory
(
stage
,
movableManager
);
...
@@ -21,6 +25,8 @@ export function addGame(stage: FYGE.Stage) {
...
@@ -21,6 +25,8 @@ export function addGame(stage: FYGE.Stage) {
function
onGamOver
()
{
function
onGamOver
()
{
alert
(
"gameOver"
);
alert
(
"gameOver"
);
console
.
log
(
"Score"
,
movableManager
.
Score
);
dragDropManager
.
remove
(
hero
);
dragDropManager
.
remove
(
hero
);
enemyFactory
.
destroy
();
enemyFactory
.
destroy
();
}
}
...
...
src/weapon/Bullet.ts
View file @
c19ec7c9
src/weapon/IWeaponHost.ts
View file @
c19ec7c9
...
@@ -5,5 +5,6 @@ export interface IWeaponHost extends FYGE.Sprite {
...
@@ -5,5 +5,6 @@ export interface IWeaponHost extends FYGE.Sprite {
movableManager
:
MovableManager
;
movableManager
:
MovableManager
;
getShootPoint
():
FYGE
.
Point
;
getShootPoint
():
FYGE
.
Point
;
getShootVelocity
():
Vector2
;
getShootVelocity
():
Vector2
;
getShootAcceleration
():
Vector2
;
getShootInterval
();
getShootInterval
();
}
}
src/weapon/Weapon.ts
View file @
c19ec7c9
...
@@ -3,7 +3,7 @@ import Bullet from "./Bullet";
...
@@ -3,7 +3,7 @@ import Bullet from "./Bullet";
import
{
IWeaponHost
}
from
"./IWeaponHost"
;
import
{
IWeaponHost
}
from
"./IWeaponHost"
;
export
default
class
Weapon
{
export
default
class
Weapon
{
onCreateBullet
:
Function
onCreateBullet
:
Function
;
_timer
;
_timer
;
_count
;
_count
;
_host
:
IWeaponHost
;
_host
:
IWeaponHost
;
...
@@ -23,7 +23,7 @@ export default class Weapon {
...
@@ -23,7 +23,7 @@ export default class Weapon {
this
.
createBullet
();
this
.
createBullet
();
this
.
reset
();
this
.
reset
();
}
}
}
};
canCreateBullet
()
{
canCreateBullet
()
{
return
this
.
_count
>=
this
.
_host
.
getShootInterval
();
return
this
.
_count
>=
this
.
_host
.
getShootInterval
();
}
}
...
@@ -33,11 +33,11 @@ export default class Weapon {
...
@@ -33,11 +33,11 @@ export default class Weapon {
const
bullet
:
Bullet
=
this
.
_host
.
parent
.
addChild
(
new
Bullet
());
const
bullet
:
Bullet
=
this
.
_host
.
parent
.
addChild
(
new
Bullet
());
bullet
.
host
=
this
.
_host
;
bullet
.
host
=
this
.
_host
;
bullet
.
velocity
=
this
.
_host
.
getShootVelocity
();
bullet
.
velocity
=
this
.
_host
.
getShootVelocity
();
bullet
.
acceleration
=
this
.
_host
.
getShootAcceleration
();
const
shootPoint
=
this
.
_host
.
getShootPoint
();
const
shootPoint
=
this
.
_host
.
getShootPoint
();
bullet
.
position
.
set
(
shootPoint
.
x
,
shootPoint
.
y
);
bullet
.
position
.
set
(
shootPoint
.
x
,
shootPoint
.
y
);
this
.
_host
.
movableManager
.
add
(
bullet
);
this
.
_host
.
movableManager
.
add
(
bullet
);
}
};
destroy
()
{
destroy
()
{
clearInterval
(
this
.
_timer
);
clearInterval
(
this
.
_timer
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment