generated from hheik/bevy-template
Compare commits
No commits in common. "beaab7e97fb40430b3d16e8aa08bffaca6728c5e" and "3ff21d3b836617208b4399dd9fdc681892fc5a92" have entirely different histories.
beaab7e97f
...
3ff21d3b83
|
|
@ -1008,18 +1008,6 @@ dependencies = [
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bevy_prototype_lyon"
|
|
||||||
version = "0.13.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e02ff6a3e8b4867eaed81a2bb2cc0bcddc33150849eefa369b4a170ef337aaa8"
|
|
||||||
dependencies = [
|
|
||||||
"bevy",
|
|
||||||
"lyon_algorithms",
|
|
||||||
"lyon_tessellation",
|
|
||||||
"svgtypes",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bevy_ptr"
|
name = "bevy_ptr"
|
||||||
version = "0.15.1"
|
version = "0.15.1"
|
||||||
|
|
@ -2210,12 +2198,6 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "float_next_after"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
|
@ -2422,7 +2404,6 @@ dependencies = [
|
||||||
"bevy",
|
"bevy",
|
||||||
"bevy-inspector-egui",
|
"bevy-inspector-egui",
|
||||||
"bevy_mod_debugdump",
|
"bevy_mod_debugdump",
|
||||||
"bevy_prototype_lyon",
|
|
||||||
"bevy_rapier2d",
|
"bevy_rapier2d",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
@ -2750,16 +2731,6 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "kurbo"
|
|
||||||
version = "0.11.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec",
|
|
||||||
"smallvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
|
@ -2854,48 +2825,6 @@ version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lyon_algorithms"
|
|
||||||
version = "1.0.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f13c9be19d257c7d37e70608ed858e8eab4b2afcea2e3c9a622e892acbf43c08"
|
|
||||||
dependencies = [
|
|
||||||
"lyon_path",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lyon_geom"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8af69edc087272df438b3ee436c4bb6d7c04aa8af665cfd398feae627dbd8570"
|
|
||||||
dependencies = [
|
|
||||||
"arrayvec",
|
|
||||||
"euclid",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lyon_path"
|
|
||||||
version = "1.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e0b8aec2f58586f6eef237985b9a9b7cb3a3aff4417c575075cf95bf925252e"
|
|
||||||
dependencies = [
|
|
||||||
"lyon_geom",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lyon_tessellation"
|
|
||||||
version = "1.0.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "579d42360a4b09846eff2feef28f538696c7d6c7439bfa65874ff3cbe0951b2c"
|
|
||||||
dependencies = [
|
|
||||||
"float_next_after",
|
|
||||||
"lyon_path",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
|
@ -4176,12 +4105,6 @@ version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "siphasher"
|
|
||||||
version = "1.0.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "skrifa"
|
name = "skrifa"
|
||||||
version = "0.22.3"
|
version = "0.22.3"
|
||||||
|
|
@ -4295,16 +4218,6 @@ version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa"
|
checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "svgtypes"
|
|
||||||
version = "0.15.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc"
|
|
||||||
dependencies = [
|
|
||||||
"kurbo",
|
|
||||||
"siphasher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swash"
|
name = "swash"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ edition = "2021"
|
||||||
bevy = "0.15.1"
|
bevy = "0.15.1"
|
||||||
bevy-inspector-egui = "0.28.1"
|
bevy-inspector-egui = "0.28.1"
|
||||||
bevy_mod_debugdump = "0.12.1"
|
bevy_mod_debugdump = "0.12.1"
|
||||||
bevy_prototype_lyon = "0.13.0"
|
|
||||||
bevy_rapier2d = "0.28.0"
|
bevy_rapier2d = "0.28.0"
|
||||||
num-traits = "0.2.19"
|
num-traits = "0.2.19"
|
||||||
|
|
||||||
|
|
|
||||||
92
src/debug.rs
92
src/debug.rs
|
|
@ -1,5 +1,4 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_prototype_lyon::prelude::*;
|
|
||||||
|
|
||||||
pub struct DebugPlugin;
|
pub struct DebugPlugin;
|
||||||
|
|
||||||
|
|
@ -8,21 +7,14 @@ pub struct DebugSet;
|
||||||
|
|
||||||
impl Plugin for DebugPlugin {
|
impl Plugin for DebugPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.configure_sets(Last, DebugSet.run_if(is_debug_enabled))
|
app.configure_sets(Last, DebugSet.run_if(is_debug_enabled));
|
||||||
.configure_sets(PostUpdate, DebugSet.run_if(is_debug_enabled));
|
|
||||||
|
|
||||||
app.insert_resource(DebugMode::off())
|
app.insert_resource(DebugMode::off())
|
||||||
.insert_resource(DebugDraw::default());
|
.add_plugins((
|
||||||
|
|
||||||
app.add_plugins((
|
|
||||||
bevy_inspector_egui::quick::WorldInspectorPlugin::new().run_if(is_debug_enabled),
|
bevy_inspector_egui::quick::WorldInspectorPlugin::new().run_if(is_debug_enabled),
|
||||||
bevy_rapier2d::prelude::RapierDebugRenderPlugin::default(),
|
bevy_rapier2d::prelude::RapierDebugRenderPlugin::default(),
|
||||||
));
|
))
|
||||||
|
.add_systems(Update, debug_toggle);
|
||||||
app.register_type::<DebugCanvas>()
|
|
||||||
.add_systems(Update, debug_toggle)
|
|
||||||
// TODO: Check if this could be scheduled just before render instead
|
|
||||||
.add_systems(PostUpdate, draw_shapes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,42 +34,6 @@ impl DebugMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Reflect)]
|
|
||||||
pub struct ColoredShape {
|
|
||||||
pub shape: Shape,
|
|
||||||
pub color: Srgba,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Reflect)]
|
|
||||||
pub enum Shape {
|
|
||||||
Line {
|
|
||||||
from: Vec2,
|
|
||||||
to: Vec2,
|
|
||||||
},
|
|
||||||
Polygon {
|
|
||||||
center: Vec2,
|
|
||||||
sides: usize,
|
|
||||||
radius: f32,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Component, Reflect)]
|
|
||||||
#[reflect(Component)]
|
|
||||||
#[require(Transform, Visibility)]
|
|
||||||
pub struct DebugCanvas;
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Resource, Reflect)]
|
|
||||||
#[reflect(Resource)]
|
|
||||||
pub struct DebugDraw {
|
|
||||||
pub draw_queue: Vec<ColoredShape>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DebugDraw {
|
|
||||||
pub fn colored_shape(&mut self, colored_shape: ColoredShape) {
|
|
||||||
self.draw_queue.push(colored_shape);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_debug_enabled(debug_mode: Res<DebugMode>) -> bool {
|
pub fn is_debug_enabled(debug_mode: Res<DebugMode>) -> bool {
|
||||||
debug_mode.enabled
|
debug_mode.enabled
|
||||||
}
|
}
|
||||||
|
|
@ -87,43 +43,3 @@ fn debug_toggle(input: Res<ButtonInput<KeyCode>>, mut debug_mode: ResMut<DebugMo
|
||||||
debug_mode.enabled = !debug_mode.enabled
|
debug_mode.enabled = !debug_mode.enabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_shapes(
|
|
||||||
mut commands: Commands,
|
|
||||||
canvas: Option<Single<Entity, With<DebugCanvas>>>,
|
|
||||||
mut debug_draw: ResMut<DebugDraw>,
|
|
||||||
) {
|
|
||||||
// TODO: Re-use old shapes
|
|
||||||
if let Some(canvas) = canvas.as_ref() {
|
|
||||||
commands.entity(**canvas).despawn_descendants();
|
|
||||||
}
|
|
||||||
let canvas = match canvas {
|
|
||||||
Some(canvas) => *canvas,
|
|
||||||
None => commands
|
|
||||||
.spawn((Name::new("Debug Canvas"), DebugCanvas))
|
|
||||||
.id(),
|
|
||||||
};
|
|
||||||
commands.entity(canvas).with_children(|builder| {
|
|
||||||
for ColoredShape { shape, color } in debug_draw.draw_queue.drain(..) {
|
|
||||||
// TODO
|
|
||||||
let path = match shape {
|
|
||||||
Shape::Line { from, to } => GeometryBuilder::build_as(&shapes::Line(from, to)),
|
|
||||||
Shape::Polygon {
|
|
||||||
center,
|
|
||||||
sides,
|
|
||||||
radius,
|
|
||||||
} => GeometryBuilder::build_as(&shapes::RegularPolygon {
|
|
||||||
center,
|
|
||||||
sides,
|
|
||||||
feature: RegularPolygonFeature::Radius(radius),
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.spawn((
|
|
||||||
ShapeBundle { path, ..default() },
|
|
||||||
Fill::color(Srgba::NONE),
|
|
||||||
Stroke::color(color),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{debug, game_setup, util};
|
use crate::{debug, game_setup, util};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy_prototype_lyon::prelude::*;
|
|
||||||
use bevy_rapier2d::prelude::*;
|
use bevy_rapier2d::prelude::*;
|
||||||
|
|
||||||
mod item;
|
mod item;
|
||||||
|
|
@ -11,7 +10,6 @@ mod work;
|
||||||
pub fn init(app: &mut App) {
|
pub fn init(app: &mut App) {
|
||||||
let app = app.add_plugins((
|
let app = app.add_plugins((
|
||||||
game_setup::GameSetupPlugin,
|
game_setup::GameSetupPlugin,
|
||||||
ShapePlugin,
|
|
||||||
RapierPhysicsPlugin::<NoUserData>::default(),
|
RapierPhysicsPlugin::<NoUserData>::default(),
|
||||||
util::UtilPlugin,
|
util::UtilPlugin,
|
||||||
debug::DebugPlugin,
|
debug::DebugPlugin,
|
||||||
|
|
@ -26,6 +24,5 @@ pub fn init(app: &mut App) {
|
||||||
.register_type::<prefab::Tree>()
|
.register_type::<prefab::Tree>()
|
||||||
.add_systems(Startup, systems::setup_2d)
|
.add_systems(Startup, systems::setup_2d)
|
||||||
.add_systems(Update, (systems::demo_2d, systems::work_select))
|
.add_systems(Update, (systems::demo_2d, systems::work_select))
|
||||||
.add_systems(PostUpdate, item::update_item_sprite)
|
.add_systems(PostUpdate, item::update_item_sprite);
|
||||||
.add_systems(Update, (systems::draw_job_targets).in_set(debug::DebugSet));
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::game::{
|
use crate::game::{item::Item, prefab};
|
||||||
item::{Inventory, Item, ItemStack},
|
|
||||||
prefab,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn setup_2d(mut commands: Commands) {
|
pub fn setup_2d(mut commands: Commands) {
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
|
|
@ -12,23 +9,13 @@ pub fn setup_2d(mut commands: Commands) {
|
||||||
Transform::from_xyz(0.0, 0.0, 10.0),
|
Transform::from_xyz(0.0, 0.0, 10.0),
|
||||||
));
|
));
|
||||||
|
|
||||||
commands.spawn((
|
commands.spawn((Transform::from_xyz(-200.0, 0.0, 0.0), prefab::Glorb));
|
||||||
Transform::from_xyz(-300.0, 0.0, 0.0),
|
|
||||||
prefab::Glorb,
|
|
||||||
Inventory {
|
|
||||||
items: vec![ItemStack {
|
|
||||||
item: Item::Wood,
|
|
||||||
count: 1,
|
|
||||||
}],
|
|
||||||
capacity: Some(1),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
commands.spawn((Transform::from_xyz(-200.0, 100.0, 0.0), prefab::Glorb));
|
commands.spawn((Transform::from_xyz(-200.0, 100.0, 0.0), prefab::Glorb));
|
||||||
commands.spawn((Transform::from_xyz(-200.0, -100.0, 0.0), prefab::Glorb));
|
commands.spawn((Transform::from_xyz(-200.0, -100.0, 0.0), prefab::Glorb));
|
||||||
|
|
||||||
commands.spawn((Transform::from_xyz(200.0, 0.0, 0.0), prefab::Tree));
|
commands.spawn((Transform::from_xyz(200.0, 0.0, 0.0), prefab::Tree));
|
||||||
|
|
||||||
// commands.spawn((Name::from("Wood"), Item::Wood));
|
commands.spawn((Name::from("Wood"), Item::Wood));
|
||||||
|
|
||||||
commands.spawn((Transform::from_xyz(-200.0, -150.0, 0.0), prefab::Chest));
|
commands.spawn((Transform::from_xyz(-200.0, -150.0, 0.0), prefab::Chest));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
use bevy::{color::palettes::css, prelude::*};
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::game::{
|
||||||
debug::{ColoredShape, DebugDraw, Shape},
|
|
||||||
game::{
|
|
||||||
item::{Inventory, ItemSource, Stockpile},
|
item::{Inventory, ItemSource, Stockpile},
|
||||||
work::{Task, WorkType, Worker},
|
work::{Task, WorkType, Worker},
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn work_select(
|
pub fn work_select(
|
||||||
|
|
@ -29,7 +26,7 @@ pub fn work_select(
|
||||||
let stockpile_dist_squared = worker_transform
|
let stockpile_dist_squared = worker_transform
|
||||||
.translation()
|
.translation()
|
||||||
.distance_squared(stockpile_transform.translation());
|
.distance_squared(stockpile_transform.translation());
|
||||||
if task_by_distance.is_none_or(|(_, closest_task_dist)| {
|
if task_by_distance.map_or(true, |(_, closest_task_dist)| {
|
||||||
stockpile_dist_squared < closest_task_dist
|
stockpile_dist_squared < closest_task_dist
|
||||||
}) {
|
}) {
|
||||||
task_by_distance = Some((
|
task_by_distance = Some((
|
||||||
|
|
@ -55,9 +52,9 @@ pub fn work_select(
|
||||||
let source_dist_squared = worker_transform
|
let source_dist_squared = worker_transform
|
||||||
.translation()
|
.translation()
|
||||||
.distance_squared(item_source_transform.translation());
|
.distance_squared(item_source_transform.translation());
|
||||||
if task_by_distance
|
if task_by_distance.map_or(true, |(_, closest_task_dist)| {
|
||||||
.is_none_or(|(_, closest_task_dist)| source_dist_squared < closest_task_dist)
|
source_dist_squared < closest_task_dist
|
||||||
{
|
}) {
|
||||||
task_by_distance = Some((
|
task_by_distance = Some((
|
||||||
Task {
|
Task {
|
||||||
target: item_source_entity,
|
target: item_source_entity,
|
||||||
|
|
@ -73,63 +70,3 @@ pub fn work_select(
|
||||||
worker.0 = task_by_distance.map(|(task, _)| task);
|
worker.0 = task_by_distance.map(|(task, _)| task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Example of DebugDraw usage
|
|
||||||
pub fn draw_job_targets(
|
|
||||||
mut debug_draw: ResMut<DebugDraw>,
|
|
||||||
worker_query: Query<(Entity, &Worker)>,
|
|
||||||
global_query: Query<&GlobalTransform>,
|
|
||||||
) {
|
|
||||||
for (worker_entity, worker) in worker_query.iter() {
|
|
||||||
let worker_global = global_query.get(worker_entity).unwrap();
|
|
||||||
let colored_shapes = match worker.0 {
|
|
||||||
Some(task) => match task.work_type {
|
|
||||||
WorkType::Gather => vec![
|
|
||||||
ColoredShape {
|
|
||||||
shape: Shape::Polygon {
|
|
||||||
center: worker_global.translation().xy(),
|
|
||||||
sides: 3,
|
|
||||||
radius: 16.,
|
|
||||||
},
|
|
||||||
color: css::GREEN,
|
|
||||||
},
|
|
||||||
ColoredShape {
|
|
||||||
shape: Shape::Line {
|
|
||||||
from: worker_global.translation().xy(),
|
|
||||||
to: global_query.get(task.target).unwrap().translation().xy(),
|
|
||||||
},
|
|
||||||
color: css::GREEN,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
WorkType::Store(_) => vec![
|
|
||||||
ColoredShape {
|
|
||||||
shape: Shape::Polygon {
|
|
||||||
center: worker_global.translation().xy(),
|
|
||||||
sides: 3,
|
|
||||||
radius: 16.,
|
|
||||||
},
|
|
||||||
color: css::YELLOW,
|
|
||||||
},
|
|
||||||
ColoredShape {
|
|
||||||
shape: Shape::Line {
|
|
||||||
from: worker_global.translation().xy(),
|
|
||||||
to: global_query.get(task.target).unwrap().translation().xy(),
|
|
||||||
},
|
|
||||||
color: css::YELLOW,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
None => vec![ColoredShape {
|
|
||||||
shape: Shape::Polygon {
|
|
||||||
center: worker_global.translation().xy(),
|
|
||||||
sides: 3,
|
|
||||||
radius: 16.,
|
|
||||||
},
|
|
||||||
color: css::RED,
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
for colored_shape in colored_shapes {
|
|
||||||
debug_draw.colored_shape(colored_shape);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue