finished!
This commit is contained in:
parent
4986e97e2b
commit
ed259baee5
BIN
solve/solve
BIN
solve/solve
Binary file not shown.
293
solve/solve.s
293
solve/solve.s
|
@ -1,10 +1,11 @@
|
|||
; vim: ft=nasm
|
||||
s:
|
||||
|
||||
%macro i_nop 0
|
||||
db 0x00
|
||||
%endmacro
|
||||
%define np i_nop
|
||||
|
||||
|
||||
%macro i_halt 1
|
||||
db 0x01
|
||||
db %1
|
||||
|
@ -42,7 +43,8 @@
|
|||
db 0x50
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db (%3 >> 8) & 0xff
|
||||
db %3 & 0xff
|
||||
%endmacro
|
||||
%define jl i_less
|
||||
|
||||
|
@ -53,10 +55,19 @@
|
|||
db 0x51
|
||||
db %1
|
||||
db %2
|
||||
db %3
|
||||
db (%3 >> 8) & 0xff
|
||||
db %3 & 0xff
|
||||
%endmacro
|
||||
%define le i_leq
|
||||
|
||||
%macro break 0
|
||||
sd disp, 0x00
|
||||
sd disp, 0x01
|
||||
sd disp, 0x02
|
||||
sd disp, 0x03
|
||||
np
|
||||
%endmacro
|
||||
|
||||
%define inp 0
|
||||
%define disp 1
|
||||
%define arith 2
|
||||
|
@ -69,72 +80,324 @@ gt 0x02, inp
|
|||
gt 0x03, inp
|
||||
; [a, b, c, d] -> mem
|
||||
sd tape, 0x00
|
||||
sd tape, 0x01
|
||||
sd tape, 0x02
|
||||
sd tape, 0x01
|
||||
sd tape, 0x03
|
||||
; {a, b, c, d}
|
||||
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x03
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x03, arith
|
||||
; [i[0], i[1], i[2], i[3] + i[0]]
|
||||
; - add i[3] and i[0]
|
||||
|
||||
sd arith, 0x01
|
||||
sd arith, 0x03
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x03, arith
|
||||
; [i[0], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - xor i[1] with i[3] + i[0], pop from arith
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x01
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
; [i[0] + i[1], i[1], i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - add i[0] and i[1], pop from arith
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x02
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x02, arith
|
||||
; [i[0] + i[1], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - xor i[0] + i[1] with i[2], pop from arith
|
||||
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x02
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
; [i[2], i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - xor (i[0] + i[1]) ^ i[2] with i[0] + i[1], pop from arith
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x01
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x01, arith
|
||||
sd arith, 0x01
|
||||
; [i[2], i[2] + i[1], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - add i[2] + i[1], pop from arith | store i[2] + i[1] in arith
|
||||
|
||||
gt 0x01, tape
|
||||
sd arith, 0x01
|
||||
; [i[2], i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - pop i[3] from tape use previous i[1] + i[2] from arith to xor
|
||||
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x01, arith
|
||||
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - use previous i[1] + i[2] from arith to xor and pop
|
||||
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
; [i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - put i[2] in arith, pop i[1] from tape
|
||||
|
||||
sd arith, 0x00
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
; [i[2] + i[1], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - put i[1] in arith, add, pop
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x01
|
||||
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
|
||||
; [i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - xor i[2] + i[1] with (i[2] + i[1]) ^ i[3]
|
||||
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
; [i[2], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - put i[3] in arith, pop i[2] from tape
|
||||
|
||||
sd arith, 0x00
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
|
||||
; [i[2] + i[3], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - put i[2] in arith, add to i[3]
|
||||
|
||||
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
; [i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - put i[2] + i[3] in arith, pop i[0] from tape
|
||||
|
||||
sd arith, 0x00
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x03
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
; [(i[2] + i[3]) ^ i[0], (i[2] + i[1]) ^ i[3], (i[0] + i[1]) ^ i[2], (i[3] + i[0]) ^ i[1]]
|
||||
; - xor in arith
|
||||
|
||||
|
||||
|
||||
sd tape, 0x00
|
||||
sd tape, 0x01
|
||||
sd tape, 0x02
|
||||
sd tape, 0x03
|
||||
gt 0x01, tape
|
||||
gt 0x02, tape
|
||||
gt 0x03, tape
|
||||
gt 0x00, tape
|
||||
|
||||
|
||||
; push all to tape
|
||||
; pop all back into mem in correct spot
|
||||
; stage 1 done
|
||||
|
||||
; :b [a, b, c, d] (, ,)
|
||||
sd tape, 0x01
|
||||
; :b [a, b, c, d] (b, , )
|
||||
sd arith, 0x01
|
||||
; :b [a, 0, c, d] (b, 0, +)
|
||||
ld 0x01, 0x00
|
||||
sd arith, 0x01
|
||||
ld 0x01, 0x01
|
||||
sd arith, 0x01
|
||||
; :b [a, t, c, d] (b, 0, +)
|
||||
sd tape, 0x03
|
||||
gt 0x01, tape
|
||||
; :b t [a, t, c, d] (b, 0, +)
|
||||
sd tape, 0x01
|
||||
; :b t [a, b, c, d] ()
|
||||
gt 0x01, arith
|
||||
|
||||
loop:
|
||||
; :b t c [a * c, b, 0, d] ()
|
||||
sd tape, 0x02
|
||||
sd tape, 0x03 ; :b t c d [a, b, c, d]
|
||||
sd tape, 0x00
|
||||
gt 0x03, tape ; :b t c d [a, b, c, a]
|
||||
|
||||
multip:
|
||||
|
||||
sd arith, 0x02
|
||||
ld 0x02, 0x01
|
||||
sd arith, 0x02
|
||||
ld 0x02, 0x02 ; sub 1 from c
|
||||
sd arith, 0x02
|
||||
gt 0x02, arith
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x03
|
||||
ld 0x00, 0x01 ; a + a
|
||||
sd arith, 0x00
|
||||
gt 0x00, arith
|
||||
sd tape, 0x00 ; :b t c d a+a [a+a, b, c-1, a]
|
||||
|
||||
|
||||
; routine for doing overflowing add
|
||||
; [a, b]
|
||||
; [255 - a, b]
|
||||
; 255 - a < b
|
||||
; a = b - [255 - a]
|
||||
; 255 - a >= b
|
||||
; a = a + b
|
||||
;
|
||||
ld 0x00, 0x01 ; :b t c d a+a [1, b, c-1, a]
|
||||
le 0x02, 0x00, leavemul - s
|
||||
gt 0x00, tape ; put back a + a
|
||||
|
||||
; :b t c d [a+a, b, c-1, a]
|
||||
le 0x00, 0x00, multip - s ; jump to mul
|
||||
|
||||
leavemul:
|
||||
|
||||
gt 0x00, tape
|
||||
gt 0x03, tape
|
||||
gt 0x02, tape
|
||||
; :b t [a * c, b, c, d] ()
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x01
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x01
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
; :b t [a * c + b, b, c, d] ()
|
||||
|
||||
modulo:
|
||||
jl 0x00, 0x03, leavemod - s
|
||||
|
||||
sd arith, 0x00
|
||||
sd arith, 0x03
|
||||
|
||||
sd tape, 0x00
|
||||
ld 0x00, 0x02
|
||||
sd arith, 0x00
|
||||
gt 0x00, tape
|
||||
|
||||
gt 0x00, arith
|
||||
|
||||
le 0x00, 0x00, modulo - s
|
||||
|
||||
leavemod:
|
||||
|
||||
; :b t [(ac + b) % d, b, c, d] ()
|
||||
|
||||
gt 0x01, tape
|
||||
; :b [(ac + b) % d, t, c, d] ()
|
||||
sd arith, 0x01
|
||||
ld 0x01, 0x01
|
||||
; :b [(ac + b) % d, 1, c, d] (t, )
|
||||
sd arith, 0x01
|
||||
ld 0x01, 0x02
|
||||
sd arith, 0x01
|
||||
; :b [(ac + b) % d, 1, c, d] (t, 1, -)
|
||||
gt 0x01, arith
|
||||
; :b [(ac + b) % d, t-1, c, d] ()
|
||||
sd tape, 0x02
|
||||
ld 0x02, 0x00
|
||||
le 0x01, 0x02, finish - s
|
||||
|
||||
gt 0x02, tape
|
||||
; if t - 1 leq 0 -> jump out
|
||||
; else -> continue
|
||||
sd arith, 0x02
|
||||
; :b [(ac + b) % d, t-1, c, d] (c, ,)
|
||||
ld 0x02, 0x00
|
||||
sd arith, 0x02
|
||||
ld 0x02, 0x01
|
||||
sd arith, 0x02
|
||||
; :b [(ac + b) % d, t-1, 0, d] (c, 0, +)
|
||||
gt 0x02, tape
|
||||
; : [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||
sd tape, 0x02
|
||||
; :b [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||
sd tape, 0x01
|
||||
; :b t-1 [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||
sd tape, 0x02
|
||||
; :b t-1 b [(ac + b) % d, t-1, b, d] (c, 0, +)
|
||||
gt 0x02, arith
|
||||
; :b t-1 b [(ac + b) % d, t-1, c, d] ()
|
||||
gt 0x01, tape
|
||||
; :b t-1 [(ac + b) % d, b, c, d] ()
|
||||
le 0x03, 0x03, loop - s
|
||||
; if d leq d -> jump loop
|
||||
|
||||
finish:
|
||||
gt 0x02, tape
|
||||
gt 0x01, tape
|
||||
|
||||
|
||||
|
||||
le 0x00, 0x01, label
|
||||
sd disp, 0x00
|
||||
label:
|
||||
sd disp, 0x01
|
||||
sd disp, 0x02
|
||||
sd disp, 0x03
|
||||
; finish things
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;le 0x00, 0x01, label
|
||||
;sd disp, 0x00
|
||||
;label:
|
||||
; sd disp, 0x01
|
||||
|
|
|
@ -6,19 +6,21 @@ pub trait Device {
|
|||
fn send_byte(&mut self, byte: u8);
|
||||
}
|
||||
|
||||
|
||||
pub struct Reader<'a> {
|
||||
pub reader: &'a mut dyn Read,
|
||||
}
|
||||
|
||||
|
||||
impl Device for Reader<'_> {
|
||||
fn get_byte(&mut self) -> u8 {
|
||||
self.reader.bytes().next().and_then(|result| result.ok()).map(|byte| byte as u8).unwrap()
|
||||
self.reader
|
||||
.bytes()
|
||||
.next()
|
||||
.and_then(|result| result.ok())
|
||||
.map(|byte| byte as u8)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn send_byte(&mut self, _byte: u8) {
|
||||
}
|
||||
fn send_byte(&mut self, _byte: u8) {}
|
||||
}
|
||||
|
||||
pub struct Tape {
|
||||
|
@ -28,13 +30,12 @@ pub struct Tape {
|
|||
|
||||
impl Device for Tape {
|
||||
fn get_byte(&mut self) -> u8 {
|
||||
let i = self.tape[self.index];
|
||||
if self.index == 0 {
|
||||
self.index = 25000;
|
||||
}
|
||||
self.index -= 1;
|
||||
self.index %= 25000;
|
||||
i
|
||||
self.tape[self.index]
|
||||
}
|
||||
|
||||
fn send_byte(&mut self, byte: u8) {
|
||||
|
@ -42,7 +43,6 @@ impl Device for Tape {
|
|||
self.index += 1;
|
||||
self.index %= 25000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct Writer<'a> {
|
||||
|
@ -67,10 +67,10 @@ pub struct Arithmetic {
|
|||
impl Device for Arithmetic {
|
||||
fn get_byte(&mut self) -> u8 {
|
||||
match self.buffer[2] {
|
||||
1 => self.buffer[0] + self.buffer[1],
|
||||
2 => self.buffer[0] - self.buffer[1],
|
||||
1 => self.buffer[0].overflowing_add(self.buffer[1]).0,
|
||||
2 => self.buffer[0].overflowing_sub(self.buffer[1]).0,
|
||||
3 => self.buffer[0] ^ self.buffer[1],
|
||||
_ => 0
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,5 +80,3 @@ impl Device for Arithmetic {
|
|||
self.index %= 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
61
src/main.rs
61
src/main.rs
|
@ -3,18 +3,19 @@
|
|||
mod device;
|
||||
mod vm;
|
||||
|
||||
use device::{Reader, Arithmetic, Tape, Writer};
|
||||
use std::io::Cursor;
|
||||
use device::{Arithmetic, Reader, Tape, Writer};
|
||||
use rand::prelude::random;
|
||||
use std::io::Read;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use vm::{State, vm_run};
|
||||
|
||||
use std::io::Cursor;
|
||||
use std::io::Read;
|
||||
use vm::{vm_run, State};
|
||||
|
||||
fn main() {
|
||||
|
||||
let program: Vec<u8> = io::stdin().bytes().map(|res| res.unwrap_or_else(|_| std::process::exit(1))).collect();
|
||||
|
||||
let program: Vec<u8> = io::stdin()
|
||||
.bytes()
|
||||
.map(|res| res.unwrap_or_else(|_| std::process::exit(1)))
|
||||
.collect();
|
||||
|
||||
for _ in 0..10 {
|
||||
let iv: [u8; 4] = random();
|
||||
|
@ -25,35 +26,53 @@ fn main() {
|
|||
ip: 0usize,
|
||||
mem: [0; 4],
|
||||
program: program.clone(),
|
||||
devices: vec![Box::new(Reader { reader: &mut input } ),
|
||||
Box::new(Writer { writer: &mut output } ),
|
||||
Box::new(Arithmetic { buffer: [0; 3], index: 0usize }),
|
||||
Box::new(Tape { tape: [0; 25000], index: 0usize }),]
|
||||
devices: vec![
|
||||
Box::new(Reader { reader: &mut input }),
|
||||
Box::new(Writer {
|
||||
writer: &mut output,
|
||||
}),
|
||||
Box::new(Arithmetic {
|
||||
buffer: [0; 3],
|
||||
index: 0usize,
|
||||
}),
|
||||
Box::new(Tape {
|
||||
tape: [0; 25000],
|
||||
index: 0usize,
|
||||
}),
|
||||
],
|
||||
};
|
||||
vm_run(state);
|
||||
let ov: [u8; 4] = output.into_inner().try_into().unwrap();
|
||||
println!("{:?}", iv);
|
||||
println!("{:?}", encrypt(iv));
|
||||
println!("{:?}", ov);
|
||||
if ov != encrypt(iv) {
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
println!(
|
||||
"{}",
|
||||
fs::read_to_string("flag.txt").unwrap_or_else(|_| {
|
||||
println!("Couldn't open flag file, please contact an admin if on the server.");
|
||||
std::process::exit(1)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#[inline(never)]
|
||||
fn encrypt(block: [u8; 4]) -> [u8; 4] {
|
||||
let mut block = block;
|
||||
|
||||
#[allow(clippy::clone_on_copy)]
|
||||
let mut b = block.clone();
|
||||
|
||||
let (i, _) = block[0].overflowing_add(block[3]);
|
||||
block[1] ^= i;
|
||||
b[1] ^= i;
|
||||
let (i, _) = block[1].overflowing_add(block[0]);
|
||||
block[2] ^= i;
|
||||
b[2] ^= i;
|
||||
let (i, _) = block[2].overflowing_add(block[1]);
|
||||
block[3] ^= i;
|
||||
b[3] ^= i;
|
||||
let (i, _) = block[3].overflowing_add(block[2]);
|
||||
block[0] ^= i;
|
||||
b[0] ^= i;
|
||||
|
||||
block = b;
|
||||
|
||||
for _ in 0..block[3] {
|
||||
let (mul, _) = block[2].overflowing_mul(block[0]);
|
||||
|
|
23
src/vm.rs
23
src/vm.rs
|
@ -5,7 +5,7 @@ pub struct State<'a> {
|
|||
pub ip: usize,
|
||||
pub mem: [u8; 4],
|
||||
pub program: Vec<u8>,
|
||||
pub devices: Vec<Box<dyn Device + 'a>>
|
||||
pub devices: Vec<Box<dyn Device + 'a>>,
|
||||
}
|
||||
|
||||
impl State<'_> {
|
||||
|
@ -25,10 +25,10 @@ impl State<'_> {
|
|||
|
||||
#[inline(never)]
|
||||
fn next_dword(&mut self) -> u32 {
|
||||
let result = (u32::from(self.program[self.ip]) << 24) |
|
||||
(u32::from(self.program[self.ip + 1]) << 16) |
|
||||
(u32::from(self.program[self.ip + 2]) << 8) |
|
||||
(u32::from(self.program[self.ip + 3]));
|
||||
let result = (u32::from(self.program[self.ip]) << 24)
|
||||
| (u32::from(self.program[self.ip + 1]) << 16)
|
||||
| (u32::from(self.program[self.ip + 2]) << 8)
|
||||
| (u32::from(self.program[self.ip + 3]));
|
||||
self.ip += 4;
|
||||
result
|
||||
}
|
||||
|
@ -43,10 +43,8 @@ pub enum Opcode {
|
|||
Get,
|
||||
Less,
|
||||
LessEq,
|
||||
|
||||
}
|
||||
|
||||
|
||||
impl From<u8> for Opcode {
|
||||
fn from(v: u8) -> Self {
|
||||
match v {
|
||||
|
@ -57,18 +55,16 @@ impl From<u8> for Opcode {
|
|||
0x21 => Opcode::Get,
|
||||
0x50 => Opcode::Less,
|
||||
0x51 => Opcode::LessEq,
|
||||
_ => Opcode::Halt
|
||||
_ => Opcode::Halt,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn vm_run(mut state: State) -> i32 {
|
||||
loop {
|
||||
if state.ip >= state.program.len() {
|
||||
return 1
|
||||
return 1;
|
||||
}
|
||||
|
||||
match Opcode::from(state.program[state.ip]) {
|
||||
Opcode::Nop => {
|
||||
state.ip += 1;
|
||||
|
@ -100,7 +96,7 @@ pub fn vm_run(mut state: State) -> i32 {
|
|||
state.ip += 1;
|
||||
let mem1 = state.mem[state.next_byte() as usize];
|
||||
let mem2 = state.mem[state.next_byte() as usize];
|
||||
let jump = state.next_byte() as usize;
|
||||
let jump = state.next_word() as usize;
|
||||
if mem1 < mem2 {
|
||||
state.ip = jump;
|
||||
}
|
||||
|
@ -109,12 +105,11 @@ pub fn vm_run(mut state: State) -> i32 {
|
|||
state.ip += 1;
|
||||
let mem1 = state.mem[state.next_byte() as usize];
|
||||
let mem2 = state.mem[state.next_byte() as usize];
|
||||
let jump = state.next_byte() as usize;
|
||||
let jump = state.next_word() as usize;
|
||||
if mem1 <= mem2 {
|
||||
state.ip = jump;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user