New Programs

- lib with useful stuff
- other things that could help
- graphics...
develop
Trivernis 6 years ago
parent 2725cdedbc
commit 697e0c0f37

@ -1,16 +1,17 @@
program login;
uses
md5, crt;
md5, crt,
utils in '../lib/utils.pas';
type
CONNECTION = record
hotel : string;
hotel : string[10];
distance : integer;
end;
HOTEL = record
name : string;
name : string[10];
conn : CONNECTION;
end;
@ -28,13 +29,6 @@ users: array [0..4] of USER = (
(un: 'user4'; pw: '4101bef8794fed986e95dfb54850c68b'; l: false),
(un: 'root'; pw: '63a9f0ea7bb98050796b649e85481845'; l: false)
);
hotels: array [0..4] of HOTEL = (
(name: 'Hotel 1'; conn: (hotel: 'Hotel 2'; distance: 11)),
(name: 'Hotel 2'; conn: (hotel: 'Hotel 3'; distance: 5)),
(name: 'Hotel 3'; conn: (hotel: 'Hotel 4'; distance: 11)),
(name: 'Hotel 4'; conn: (hotel: 'Hotel 5'; distance: 5)),
(name: 'Hotel 5'; conn: (hotel: ''; distance: 0))
);
var
readinput: string;
@ -42,87 +36,93 @@ var
correct: boolean;
usersuccess: boolean = false;
time: real;
hotels_f: File of HOTEL;
function distance_sum(hnum1, hnum2 :integer) : integer;
{ Calculate the total distance sum. }
function get_hotel_by_name(hname: String) : HOTEL;
{ Read the hotels from the file and find the one with the right name }
var
distance_total : integer = 0;
i : integer;
htemp : HOTEL;
begin
if (hnum1 > hnum2) then
for i := (hnum1-2) downto (hnum2-1) do
distance_total := distance_total + hotels[i].conn.distance
else
for i := (hnum1-1) to (hnum2-2) do
distance_total := distance_total + hotels[i].conn.distance;
distance_sum := distance_total;
Reset(hotels_f);
while not EOF(hotels_f) do
begin
Read(hotels_f, htemp);
if htemp.name = hname then
begin
get_hotel_by_name := htemp;
Break;
end;
end;
end;
procedure calc_time(disttot : integer);
{ Calculate the time needed for the way and print it. }
function get_total_length : integer;
{ Calculates the total lenght between two hotels }
var
velocity : integer;
htemp: HOTEL;
begin
Write('Velocity (km/h): ');
ReadLn(velocity);
time := (disttot / velocity);
WriteLn('Estimated Time: ', time: 10: 2, ' hours');
Reset(hotels_f);
get_total_length := 0;
while not EOF(hotels_f) do
begin
Read(hotels_f, htemp);
get_total_length := get_total_length + htemp.conn.distance;
end;
end;
procedure printway(hnum1, hnum2 : integer);
{ Print the whole way to the console. }
function get_path_length (hotel1, hotel2 : String) : Integer;
var
htemp: HOTEL;
next_name: String;
i : integer;
begin
Writeln('Tour:');
if hnum1 > hnum2 then
for i := hnum1 downto hnum2 do
begin
if (i <> hnum1) then
Write(' -> ');
Write(hotels[i-1].name)
end
else
for i := hnum1 to hnum2 do
begin
if (i <> hnum1) then
Write(' -> ');
Write(hotels[i-1].name)
htemp := get_hotel_by_name(hotel1);
next_name := htemp.conn.hotel;
get_path_length := 0;
get_path_length := get_path_length + htemp.conn.distance;
i := 0;
Writeln(next_name, ' ',hotel2);
while not (next_name = hotel2) do
begin
i += 1;
htemp := get_hotel_by_name(next_name);
next_name := htemp.conn.hotel;
get_path_length := get_path_length + htemp.conn.distance;
if i > 1000 then
begin
get_path_length := -1;
Break;
end;
Writeln;
end;
end;
procedure calcway;
{ Calculate the sum of all distances and call functions
that use this value. }
var
i, distance_total : integer;
h1, h2: HOTEL;
rin : String;
begin
distance_total := 0;
for i := 0 to 4 do
begin
distance_total += hotels[i].conn.distance
end;
distance_total := get_total_length;
Writeln('Total tour length: ', distance_total, ' km');
Write('First Hotel Number: ');
ReadLn(hnum1);
Write('First Hotel Name: ');
ReadLn(rin);
h1 := get_hotel_by_name(rin);
Writeln;
Write('Second Hotel Number: ');
ReadLn(hnum2);
printway(hnum1, hnum2);
If ((hnum1 <= 5) and (hnum2 <= 5)) then
begin
distance_total := distance_sum(hnum1, hnum2);
Writeln('Distance between hotels is ', distance_total, ' km');
calc_time(distance_total);
end;
ReadLn(rin);
h2 := get_hotel_by_name(rin);
Writeln(get_path_length(h1.name, h2.name));
end;
procedure hotelmain;
{ Calculates the total distance between hotels based on the hotel number input.
(Only numbers accepted!). After printing the total distance a velocity can be
input to calculate the estimated time. }
procedure hotelmain;
var
i : integer;
exit : boolean = false;
@ -199,6 +199,7 @@ begin
Writeln('Tourplanner');
Writeln('Written by J.Riegel.');
TextColor(White);
Assign(hotels_f, 'hotels.bin');
{ endless loop/main loop of the program. Exit with CTRL-C }
while true do

@ -0,0 +1,131 @@
program hellofile;
const
dir = 'C:/Users/dev/Documents/Pascal/file_test/';
procedure write_txt;
var
txtfile: TextFile;
i: Integer;
begin
Assign(txtfile, dir+'Hello');
Rewrite(txtfile);
for i := 0 to 9 do
WriteLn(txtfile, 'Hello');
Close(txtfile);
end;
procedure write_int;
var
intfile: File of Integer;
i: Integer;
begin
Assign(intfile, dir+'intense');
Rewrite(intfile);
for i := 0 to 9 do
Write(intfile, i);
Close(intfile);
end;
procedure read_int;
var
intfile: File of Integer;
i, res: Integer;
begin
Assign(intfile, dir+'intense');
Reset(intfile);
for i := 0 to 9 do
begin
Read(intfile, res);
WriteLn(res);
end;
Close(intfile);
end;
procedure write_bool;
var
boolfile: File of Boolean;
i: Integer;
begin
Assign(boolfile, dir+'bool');
Rewrite(boolfile);
for i := 0 to 4 do
Write(boolfile, true);
Write(boolfile, false);
Close(boolfile);
end;
procedure write_int64;
var
intfile: File of int64;
i: Integer;
begin
Assign(intfile, dir+'more_intense');
Rewrite(intfile);
for i := 0 to 9 do
Write(intfile, i);
Close(intfile);
end;
procedure write_real;
var
f: File of real;
i: Integer;
begin
Assign(f, dir+'reallife');
Rewrite(f);
for i := 0 to 9 do
Write(f, real(i/2));
Close(f);
end;
procedure write_very_int;
var
f: File of Integer;
i: Integer;
begin
Assign(f, dir+'veryint');
Rewrite(f);
for i := -256 to 255 do
Write(f, i);
Close(f);
end;
procedure read_very_int;
var
f: File of Integer;
i, res: Integer;
begin
Assign(f, dir+'veryint');
Reset(f);
for i := -256 to 255 do
begin
Read(f, res);
WriteLn(res);
end;
Close(f);
end;
procedure write_string;
var
f: File of String[10];
i: Integer;
begin
Assign(f, dir+'tstring');
Rewrite(f);
for i := 0 to 9 do
Write(f, 'tkdiekdhdk');
Close(f);
end;
begin
write_txt;
write_int;
write_bool;
write_int64;
write_real;
write_very_int;
write_string;
read_int;
read_very_int;
end.

@ -0,0 +1,40 @@
program lotto;
type
Ziehung = record
Datum: String;
Nums: Array[0..6] of Integer;
end;
var
f: File of Ziehung;
procedure gen_data();
var
dates: Array[0..3] of String = (
'10.10.10',
'11.11.11',
'12.12.12',
'13.12.13');
i, j: Integer;
z: Ziehung;
begin
Randomize;
Rewrite(f);
Seek(f, FileSize(f));
for i := 0 to 3 do
begin
for j := 0 to 6 do
begin
z.Nums[i] := Random(9);
end;
z.Datum := dates[i];
Write(f, z);
end;
end;
begin
Assign(f, 'ziehung');
gen_data;
end.

@ -0,0 +1,38 @@
program lotto2;
type
Ziehung = record
Datum: String;
Nums: Array[0..6] of Integer;
end;
var
f: File of Ziehung;
sin: String;
procedure get_for_date(date: String);
var
z: Ziehung;
i: Integer;
begin
while not EOF(f) do
begin
Read(f, z);
if (z.Datum = date) then
begin
Writeln('Results for ', date);
for i := 0 to 6 do
Write(z.Nums[i], ' ');
Writeln;
end;
end;
end;
begin
Assign(f, 'ziehung');
Reset(f);
Write('Date: ');
ReadLn(sin);
get_for_date(sin);
Close(f);
end.

@ -0,0 +1,112 @@
unit linkedlist;
interface
type
link = ^node;
node = record
prev : link;
next : link;
value : pointer;
end;
list_obj = record
alement : link;
zlement : link;
end;
function list_init : list_obj;
function list_get(li : list_obj; i : Integer) : pointer;
procedure list_push(li : list_obj; p : pointer);
function list_pop(li : list_obj) : pointer;
function list_length(li : list_obj) : Integer;
function list_first(li : list_obj) : pointer;
function list_empty(li : list_obj) : Boolean;
implementation
function list_init: list_obj;
begin
list_init.alement := GetMem(SizeOf(node));
list_init.zlement := GetMem(SizeOf(node));
list_init.zlement^.prev := list_init.alement;
list_init.zlement^.next := list_init.zlement;
list_init.alement^.next := list_init.zlement;
list_init.alement^.prev := list_init.alement;
end;
function list_get(li: list_obj; i: Integer) : pointer;
var
j : Integer;
r : link;
begin
list_get := nil;
if list_length(li) > i then
begin
r := li.alement;
for j := 0 to i do
begin
r := r^.next;
end;
list_get := r^.value;
end;
end;
procedure list_push(li: list_obj; p: pointer);
var
t : link;
begin
t := GetMem(SizeOf(node));
t^.next := li.zlement;
t^.value := p;
t^.prev := li.zlement^.prev;
li.zlement^.prev^.next := t;
li.zlement^.prev := t;
end;
function list_pop(li : list_obj) : pointer;
var
t : link;
begin
t := li.zlement^.prev;
li.zlement^.prev := t^.prev;
li.zlement^.prev^.next := li.zlement;
list_pop := t^.value;
FreeMem(t);
end;
function list_length(li : list_obj) : Integer;
var
i : Integer;
t : link;
begin
i := 0;
t := li.alement;
while t^.next <> li.zlement do
begin
t := t^.next;
i := i + 1;
end;
list_length := i;
end;
function list_first(li : list_obj) : pointer;
var
t : link;
begin
t := li.alement^.next;
li.alement^.next := t^.next;
t^.next^.prev := li.alement;
list_first := t^.value;
FreeMem(t);
end;
function list_empty(li : list_obj) : Boolean;
begin
if li.alement^.next = li.zlement then
list_empty := True
else
list_empty := False;
end;
begin
{ Main Body }
end.

@ -0,0 +1,75 @@
unit queue;
interface
type
fixed_string = String[20];
link = ^node;
node = record
data : fixed_string;
next : link;
prev : link
end;
queue_obj = record
alement : link;
zlement : link;
end;
procedure enqueue(q : queue_obj; v: fixed_string);
function dequeue(q : queue_obj) : fixed_string;
function is_empty(q : queue_obj) : Boolean;
function init_queue: queue_obj;
implementation
procedure enqueue(q : queue_obj; v: fixed_string);
var
t : link;
begin
t := GetMem(SizeOf(node));
t^.data := v;
t^.prev := q.zlement^.prev;
t^.prev^.next := t;
q.zlement^.prev := t;
t^.next := q.zlement;
end;
function dequeue(q : queue_obj): fixed_string;
var
t: link;
begin
if is_empty(q) = false then
begin
t := q.alement^.next;
dequeue := t^.data;
q.alement^.next := t^.next;
FreeMem(t);
end;
end;
function is_empty(q : queue_obj): Boolean;
begin
if q.zlement^.prev = q.alement then
is_empty := true
else
is_empty := false;
if q.alement^.next = q.zlement then
is_empty := true;
end;
function init_queue: queue_obj;
var
q : queue_obj;
begin
q.alement := GetMem(SizeOf(node));
q.zlement := GetMem(SizeOf(node));
q.alement^.next := q.zlement;
q.alement^.prev := q.alement;
q.zlement^.next := q.zlement;
q.zlement^.prev := q.alement;
init_queue := q;
end;
begin
{ Main Body }
end.

@ -0,0 +1,72 @@
unit stack;
interface
type
link = ^node;
fixed_string = String[20];
node = record
data : fixed_string;
next : link
end;
stack_obj = record
alement : link;
zlement : link
end;
procedure push(s: stack_obj;v: fixed_string);
function pop(s: stack_obj) : fixed_string;
function top(s: stack_obj) : fixed_string;
function is_empty(s: stack_obj) : Boolean;
function init_stack : stack_obj;
implementation
procedure push(s: stack_obj; v: fixed_string);
var
t : link;
begin
t := GetMem(SizeOf(node));
t^.data := v;
t^.next := s.alement^.next;
s.alement^.next := t;
end;
function pop(s: stack_obj): fixed_string;
var
t: link;
begin
if is_empty(s) = false then
begin
t := s.alement^.next;
s.alement^.next := t^.next;
pop := t^.data;
FreeMem(t);
end;
end;
function top(s: stack_obj): fixed_string;
begin
top := s.alement^.next^.data;
end;
function is_empty(s: stack_obj): Boolean;
begin
if s.alement^.next = s.zlement then
is_empty := true
else
is_empty := false;
end;
function init_stack: stack_obj;
var
s : stack_obj;
begin
s.alement := GetMem(SizeOf(node));
s.zlement := GetMem(SizeOf(node));
s.alement^.next := s.zlement;
s.zlement^.next := s.zlement;
init_stack := s;
end;
begin
{ Main Body }
end.

@ -0,0 +1,66 @@
unit utils;
interface
procedure calc_time(disttot : integer);
procedure graph_init;
procedure draw_hotel(x, y, scale : integer; hlabel: String);
function getXSize : Integer;
function getYSize : Integer;
procedure draw_way(xs, ys, xt, yt, scale : Integer);
implementation
uses
crt,
Graph;
procedure calc_time(disttot : integer);
{ Calculate the time needed for the way and print it. }
var
velocity : integer;
time : extended;
begin
Write('Velocity (km/h): ');
ReadLn(velocity);
time := (disttot / velocity);
WriteLn('Estimated Time: ', time: 10: 2, ' hours');
end;
procedure draw_hotel(x, y, scale : integer; hlabel: String);
begin
MoveTo(x, y);
OutTextXY((2*scale+x-20*scale), (y-20*scale), hlabel);
MoveRel(20*scale, 0);
LineRel(0, -40*scale);
LineRel(-20*scale, -20*scale);
LineRel(-20*scale, 20*scale);
LineRel(0, 40*scale);
LineRel(40*scale, 0);
MoveTo(x, y);
end;
procedure draw_way(xs, ys, xt, yt, scale : Integer);
begin
Line(xs, ys, xt, yt);
end;
procedure graph_init;
var
gdriver, gmode : Integer;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
end;
function getXSize : Integer;
begin
getXSize := GetMaxX;
end;
function getYSize : Integer;
begin
getYSize := GetMaxY;
end;
begin
end.

@ -0,0 +1,34 @@
program baloon;
uses
crt,
Graph;
procedure draw_ba(x, y : Integer; color : word);
begin
SetColor(color);
SetFillStyle(1, color);
Circle(x, y, 100);
FloodFill(x, y, color);
end;
var
gdriver,
gmode,
xsize,
ysize : Integer;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
xsize := GetMaxX;
ysize := GetMaxY;
MoveTo(Round(xsize/2), Round(ysize/2));
draw_ba(Round(xsize/2), Round(ysize/2), green);
draw_ba(Round(xsize/2)-60, Round(ysize/2)+60, red);
draw_ba(Round(xsize/2)+40, Round(ysize/2), blue);
draw_ba(Round(xsize/2), Round(ysize/2)-100, yellow);
draw_ba(Round(xsize/2)-100, Round(ysize/2)-80, green);
ReadKey;
CloseGraph;
end.

@ -4,18 +4,19 @@ uses dateutils, sysutils;
type
tup = record
num : integer;
sq : integer;
num : longint;
sq : longint;
end;
var
a : array[0..10000] of tup;
a : array[0..20000] of tup;
procedure fill_array;
{ Fills the array with ints and their squares. }
var
i: integer;
i: longint;
begin
for i := 0 to 10000 do
for i := 0 to 20000 do
begin
a[i].num := i;
a[i].sq := i*i;
@ -23,26 +24,31 @@ begin
end;
procedure do_something(arr: array of tup);
{ Alters one element of the array passed by value }
begin
arr[0].num := 1;
end;
procedure do_something_ref(var arr: array of tup);
{ Alters one element of the array passed by reference. }
begin
arr[2].num := 1;
arr[0].num := 1;
end;
procedure measurement;
{ Measures the time it takes for calling a function with
an big array as argument by reference vs by value a million
times. }
var
i : integer;
i : longint;
time : TdateTime;
begin
time := Timeof(NOW);
for i := 1 to 10000 do
for i := 1 to 1000000 do
do_something(a);
WriteLn('By Value', MilliSecondSpan(time, Timeof(now)):4);
time := Timeof(NOW);
for i := 1 to 10000 do
for i := 1 to 1000000 do
do_something_ref(a);
WriteLn('By Reference: ', MilliSecondSpan(time, Timeof(now)):4);
end;

@ -0,0 +1,29 @@
program egg;
uses
crt,
Graph;
var
gdriver,
gmode,
xsize,
ysize, x, y, i : Integer;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
SetColor(White);
xsize := GetMaxX;
ysize := GetMaxY;
MoveTo(Round(xsize/2), Round(ysize/2));
Ellipse(Round(xsize/2), Round(ysize/2), 0, 360, 100, 160);
SetColor(Black);
Ellipse(Round(xsize/2), Round(ysize/2), 0, 180, 100, 160);
SetColor(White);
Ellipse(Round(xsize/2), Round(ysize/2), 0, 180, 100, 110);
SetFillStyle(1, White);
FloodFill(Round(xsize/2), Round(ysize/2), White);
ReadKey;
CloseGraph;
end.

@ -0,0 +1,22 @@
program ellipsegraph;
uses
crt,
Graph;
var
gdriver,
gmode,
xsize,
ysize : Integer;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
SetColor(green);
xsize := GetMaxX;
ysize := GetMaxY;
FillEllipse(Round(xsize/2), Round(ysize/2), 500, 100);
ReadKey;
CloseGraph;
end.

@ -0,0 +1,23 @@
program fib;
procedure fibit;
var
a, b, c: QWord;
i : Integer;
begin
a := 1;
b := 1;
c := 1;
for i := 0 to 90 do
begin
c := b;
b := a + b;
a := c;
WriteLn(b);
end;
end;
begin
fibit;
end.

@ -0,0 +1,29 @@
program housegraphics;
uses
crt,
Graph;
var
gdriver, gmode, xsize, ysize, scale : Integer;
begin
scale := 5;
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
SetColor(green);
xsize := GetMaxX;
ysize := GetMaxY;
MoveTo(Round(xsize/2), Round(ysize/2));
MoveRel(20*scale, 0);
LineRel(0, -40*scale);
LineRel(-20*scale, -20*scale);
LineRel(-20*scale, 20*scale);
LineRel(0, 40*scale);
LineRel(40*scale, -40*scale);
LineRel(-40*scale, 0);
LineRel(40*scale, 40*scale);
LineRel(-40*scale, 0);
ReadKey();
CloseGraph();
end.

@ -0,0 +1,45 @@
program linkedtest;
uses
linkedlist in '../lib/linkedlist.pas';
type
fixedstr = String;
strptr = ^fixedstr;
function val_gen(val : fixedstr) : strptr;
begin
val_gen := GetMem(SizeOf(fixedstr));
val_gen^ := val;
end;
function val_get(ptr : pointer) : fixedstr;
var
t_ptr : strptr;
begin
t_ptr := strptr(ptr);
val_get := t_ptr^;
FreeMem(t_ptr);
end;
var
li : list_obj;
i : Integer;
begin
li := list_init;
list_push(li, val_gen('Hello World'));
list_push(li, val_gen('This is the pointers value'));
list_push(li, val_gen('A third string'));
list_push(li, val_gen('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'));
list_push(li, val_gen('Stringent'));
list_push(li, val_gen('Whatisthis'));
list_push(li, val_gen('No fun anymore.'));
list_push(li, val_gen('AA'));
list_push(li, val_gen('Stackedey-Stack-Stack'));
WriteLn();
for i := 0 to list_length(li)-1 do
WriteLn(strptr(list_get(li, i))^);
WriteLn();
WriteLn('list_length: ', list_length(li));
end.

@ -0,0 +1,31 @@
program points;
uses
crt,
Graph;
var
gdriver,
gmode,
xsize,
ysize,
width,
i, j, k : Integer;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
SetColor(green);
xsize := GetMaxX;
ysize := GetMaxY;
width := Round(xsize/GetMaxColor());
MoveTo(Round(xsize/2), Round(ysize/2));
for i := 0 to Round(xsize/width) do
for k := 0 to width do
for j := 0 to ysize do
begin
PutPixel((i*width)+k, j, i);
end;
ReadKey();
CloseGraph();
end.

@ -0,0 +1,24 @@
program queuetest;
uses
queue in '../lib/queue.pas';
var
qu, qe : queue_obj;
begin
qu := init_queue;
qe := init_queue;
enqueue(qu, 'Hello');
enqueue(qu, 'World');
enqueue(qu, 'How');
enqueue(qe, 'Another queue');
enqueue(qu, 'Are');
enqueue(qu, 'You');
enqueue(qu, '?');
while is_empty(qu) = false do
begin
WriteLn(dequeue(qu));
end;
WriteLn(dequeue(qe));
end.

@ -0,0 +1,8 @@
program recordtest;
var
iptr : ^Integer;
begin
while True do
new(iptr);
end.

@ -0,0 +1,39 @@
program ellipsegraph;
uses
crt,
Graph;
var
gdriver,
gmode,
xsize,
ysize, x, y, i : Integer;
procedure draw_spiral(color: word; rotation: Integer);
var
i : Integer;
begin
for i := 0 to 1500 do
begin
x := Round(xsize/2)+Round(i*sin(2*i+rotation)/2);
y := Round(ysize/2)+Round(i*cos(2*i+rotation)/2);
PutPixel(x, y, color);
end;
end;
begin
DetectGraph(gdriver, gmode);
InitGraph(gdriver, gmode, '');
SetColor(green);
xsize := GetMaxX;
ysize := GetMaxY;
MoveTo(Round(xsize/2), Round(ysize/2));
while True do
begin
for i := 0 to 360 do
draw_spiral(i, Round(i/2));
end;
ReadKey;
CloseGraph;
end.

@ -0,0 +1,25 @@
program stacktest;
uses
stack in '../lib/stack.pas';
var
st, st1 : stack_obj;
begin
st := init_stack;
st1 := init_stack;
push(st, 'Hello');
push(st1, 'New stack');
push(st, 'World');
push(st1, 'With new values');
push(st, 'How');
push(st, 'Are');
push(st, 'You');
push(st, '?');
while is_empty(st) = false do
begin
WriteLn(pop(st));
end;
WriteLn(pop(st1));
end.

@ -0,0 +1,13 @@
program utilstest;
uses
crt,
Graph,
utils in '../lib/utils.pas';
begin
graph_init;
draw_hotel(getXSize >> 1, getYSize >> 1, 1, 'H1');
draw_way(60, 60, 200, 200, 1);
ReadKey;
end.
Loading…
Cancel
Save