mirror of
https://github.com/tmate-io/tmate.git
synced 2024-11-30 12:04:38 +01:00
Sync OpenBSD patchset 1143:
Provide common helper function for adding windows and sessions to choose lists and expand %% in command before using it rather than at callback time. From Thomas Adam.
This commit is contained in:
parent
5761712799
commit
7e02d2f459
@ -48,8 +48,9 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
struct window_choose_data *cdata;
|
struct window_choose_data *cdata;
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
u_int idx;
|
char *action, *action_data;
|
||||||
const char *template;
|
const char *template;
|
||||||
|
u_int idx;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if (ctx->curclient == NULL) {
|
||||||
ctx->error(ctx, "must be run interactively");
|
ctx->error(ctx, "must be run interactively");
|
||||||
@ -68,14 +69,14 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
if (args->argc != 0)
|
||||||
|
action = xstrdup(args->argv[0]);
|
||||||
|
else
|
||||||
|
action = xstrdup("paste-buffer -b '%%'");
|
||||||
|
|
||||||
idx = 0;
|
idx = 0;
|
||||||
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
while ((pb = paste_walk_stack(&global_buffers, &idx)) != NULL) {
|
||||||
cdata = window_choose_data_create(ctx);
|
cdata = window_choose_data_create(ctx);
|
||||||
if (args->argc != 0)
|
|
||||||
cdata->action = xstrdup(args->argv[0]);
|
|
||||||
else
|
|
||||||
cdata->action = xstrdup("paste-buffer -b '%%'");
|
|
||||||
|
|
||||||
cdata->idx = idx - 1;
|
cdata->idx = idx - 1;
|
||||||
cdata->client->references++;
|
cdata->client->references++;
|
||||||
|
|
||||||
@ -83,8 +84,13 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
format_add(cdata->ft, "line", "%u", idx - 1);
|
format_add(cdata->ft, "line", "%u", idx - 1);
|
||||||
format_paste_buffer(cdata->ft, pb);
|
format_paste_buffer(cdata->ft, pb);
|
||||||
|
|
||||||
|
xasprintf(&action_data, "%u", idx - 1);
|
||||||
|
cdata->command = cmd_template_replace(action, action_data, 1);
|
||||||
|
xfree(action_data);
|
||||||
|
|
||||||
window_choose_add(wl->window->active, cdata);
|
window_choose_add(wl->window->active, cdata);
|
||||||
}
|
}
|
||||||
|
xfree(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active,
|
||||||
0, cmd_choose_buffer_callback, cmd_choose_buffer_free);
|
0, cmd_choose_buffer_callback, cmd_choose_buffer_free);
|
||||||
@ -100,7 +106,6 @@ cmd_choose_buffer_callback(struct window_choose_data *cdata)
|
|||||||
if (cdata->client->flags & CLIENT_DEAD)
|
if (cdata->client->flags & CLIENT_DEAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xasprintf(&cdata->raw_format, "%u", cdata->idx);
|
|
||||||
window_choose_ctx(cdata);
|
window_choose_ctx(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,8 +119,7 @@ cmd_choose_buffer_free(struct window_choose_data *data)
|
|||||||
|
|
||||||
cdata->client->references--;
|
cdata->client->references--;
|
||||||
|
|
||||||
|
xfree(cdata->command);
|
||||||
xfree(cdata->ft_template);
|
xfree(cdata->ft_template);
|
||||||
xfree(cdata->action);
|
|
||||||
xfree(cdata->raw_format);
|
|
||||||
xfree(cdata);
|
xfree(cdata);
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,7 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct client *c;
|
struct client *c;
|
||||||
const char *template;
|
const char *template;
|
||||||
|
char *action;
|
||||||
u_int i, idx, cur;
|
u_int i, idx, cur;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if (ctx->curclient == NULL) {
|
||||||
@ -70,6 +71,11 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
if ((template = args_get(args, 'F')) == NULL)
|
if ((template = args_get(args, 'F')) == NULL)
|
||||||
template = DEFAULT_CLIENT_TEMPLATE;
|
template = DEFAULT_CLIENT_TEMPLATE;
|
||||||
|
|
||||||
|
if (args->argc != 0)
|
||||||
|
action = xstrdup(args->argv[0]);
|
||||||
|
else
|
||||||
|
action = xstrdup("detach-client -t '%%'");
|
||||||
|
|
||||||
cur = idx = 0;
|
cur = idx = 0;
|
||||||
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
|
||||||
c = ARRAY_ITEM(&clients, i);
|
c = ARRAY_ITEM(&clients, i);
|
||||||
@ -80,11 +86,6 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
cdata = window_choose_data_create(ctx);
|
cdata = window_choose_data_create(ctx);
|
||||||
if (args->argc != 0)
|
|
||||||
cdata->action = xstrdup(args->argv[0]);
|
|
||||||
else
|
|
||||||
cdata->action = xstrdup("detach-client -t '%%'");
|
|
||||||
|
|
||||||
cdata->idx = i;
|
cdata->idx = i;
|
||||||
cdata->client->references++;
|
cdata->client->references++;
|
||||||
|
|
||||||
@ -93,8 +94,11 @@ cmd_choose_client_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
format_session(cdata->ft, c->session);
|
format_session(cdata->ft, c->session);
|
||||||
format_client(cdata->ft, c);
|
format_client(cdata->ft, c);
|
||||||
|
|
||||||
|
cdata->command = cmd_template_replace(action, c->tty.path, 1);
|
||||||
|
|
||||||
window_choose_add(wl->window->active, cdata);
|
window_choose_add(wl->window->active, cdata);
|
||||||
}
|
}
|
||||||
|
xfree(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active,
|
||||||
cur, cmd_choose_client_callback, cmd_choose_client_free);
|
cur, cmd_choose_client_callback, cmd_choose_client_free);
|
||||||
@ -118,7 +122,6 @@ cmd_choose_client_callback(struct window_choose_data *cdata)
|
|||||||
if (c == NULL || c->session == NULL)
|
if (c == NULL || c->session == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xasprintf(&cdata->raw_format, "%s", c->tty.path);
|
|
||||||
window_choose_ctx(cdata);
|
window_choose_ctx(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +134,7 @@ cmd_choose_client_free(struct window_choose_data *cdata)
|
|||||||
cdata->client->references--;
|
cdata->client->references--;
|
||||||
|
|
||||||
xfree(cdata->ft_template);
|
xfree(cdata->ft_template);
|
||||||
xfree(cdata->action);
|
xfree(cdata->command);
|
||||||
format_free(cdata->ft);
|
format_free(cdata->ft);
|
||||||
xfree(cdata);
|
xfree(cdata);
|
||||||
}
|
}
|
||||||
|
@ -45,9 +45,9 @@ int
|
|||||||
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
struct window_choose_data *cdata;
|
|
||||||
struct winlink *wl;
|
struct winlink *wl;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
|
char *action;
|
||||||
const char *template;
|
const char *template;
|
||||||
u_int idx, cur;
|
u_int idx, cur;
|
||||||
|
|
||||||
@ -65,28 +65,21 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
if ((template = args_get(args, 'F')) == NULL)
|
if ((template = args_get(args, 'F')) == NULL)
|
||||||
template = DEFAULT_SESSION_TEMPLATE;
|
template = DEFAULT_SESSION_TEMPLATE;
|
||||||
|
|
||||||
|
if (args->argc != 0)
|
||||||
|
action = xstrdup(args->argv[0]);
|
||||||
|
else
|
||||||
|
action = xstrdup("switch-client -t '%%'");
|
||||||
|
|
||||||
cur = idx = 0;
|
cur = idx = 0;
|
||||||
RB_FOREACH(s, sessions, &sessions) {
|
RB_FOREACH(s, sessions, &sessions) {
|
||||||
if (s == ctx->curclient->session)
|
if (s == ctx->curclient->session)
|
||||||
cur = idx;
|
cur = idx;
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
cdata = window_choose_data_create(ctx);
|
window_choose_add_session(wl->window->active,
|
||||||
if (args->argc != 0)
|
ctx, s, template, action, idx);
|
||||||
cdata->action = xstrdup(args->argv[0]);
|
|
||||||
else
|
|
||||||
cdata->action = xstrdup("switch-client -t '%%'");
|
|
||||||
cdata->idx = s->idx;
|
|
||||||
|
|
||||||
cdata->client->references++;
|
|
||||||
cdata->session->references++;
|
|
||||||
|
|
||||||
cdata->ft_template = xstrdup(template);
|
|
||||||
format_add(cdata->ft, "line", "%u", idx);
|
|
||||||
format_session(cdata->ft, s);
|
|
||||||
|
|
||||||
window_choose_add(wl->window->active, cdata);
|
|
||||||
}
|
}
|
||||||
|
xfree(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active,
|
||||||
cur, cmd_choose_session_callback, cmd_choose_session_free);
|
cur, cmd_choose_session_callback, cmd_choose_session_free);
|
||||||
@ -97,18 +90,11 @@ cmd_choose_session_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
void
|
void
|
||||||
cmd_choose_session_callback(struct window_choose_data *cdata)
|
cmd_choose_session_callback(struct window_choose_data *cdata)
|
||||||
{
|
{
|
||||||
struct session *s;
|
|
||||||
|
|
||||||
if (cdata == NULL)
|
if (cdata == NULL)
|
||||||
return;
|
return;
|
||||||
if (cdata->client->flags & CLIENT_DEAD)
|
if (cdata->client->flags & CLIENT_DEAD)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
s = session_find_by_index(cdata->idx);
|
|
||||||
if (s == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cdata->raw_format = xstrdup(s->name);
|
|
||||||
window_choose_ctx(cdata);
|
window_choose_ctx(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +107,8 @@ cmd_choose_session_free(struct window_choose_data *cdata)
|
|||||||
cdata->client->references--;
|
cdata->client->references--;
|
||||||
cdata->session->references--;
|
cdata->session->references--;
|
||||||
|
|
||||||
|
xfree(cdata->command);
|
||||||
xfree(cdata->ft_template);
|
xfree(cdata->ft_template);
|
||||||
xfree(cdata->action);
|
|
||||||
format_free(cdata->ft);
|
format_free(cdata->ft);
|
||||||
xfree(cdata);
|
xfree(cdata);
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,10 @@ int
|
|||||||
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct args *args = self->args;
|
struct args *args = self->args;
|
||||||
struct window_choose_data *cdata;
|
|
||||||
struct session *s;
|
struct session *s;
|
||||||
struct winlink *wl, *wm;
|
struct winlink *wl, *wm;
|
||||||
const char *template;
|
const char *template;
|
||||||
|
char *action;
|
||||||
u_int idx, cur;
|
u_int idx, cur;
|
||||||
|
|
||||||
if (ctx->curclient == NULL) {
|
if (ctx->curclient == NULL) {
|
||||||
@ -66,30 +66,22 @@ cmd_choose_window_exec(struct cmd *self, struct cmd_ctx *ctx)
|
|||||||
if ((template = args_get(args, 'F')) == NULL)
|
if ((template = args_get(args, 'F')) == NULL)
|
||||||
template = DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\"";
|
template = DEFAULT_WINDOW_TEMPLATE " \"#{pane_title}\"";
|
||||||
|
|
||||||
|
if (args->argc != 0)
|
||||||
|
action = xstrdup(args->argv[0]);
|
||||||
|
else
|
||||||
|
action = xstrdup("select-window -t '%%'");
|
||||||
|
|
||||||
cur = idx = 0;
|
cur = idx = 0;
|
||||||
RB_FOREACH(wm, winlinks, &s->windows) {
|
RB_FOREACH(wm, winlinks, &s->windows) {
|
||||||
if (wm == s->curw)
|
if (wm == s->curw)
|
||||||
cur = idx;
|
cur = idx;
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
cdata = window_choose_data_create(ctx);
|
window_choose_add_window(wl->window->active, ctx, s, wm,
|
||||||
if (args->argc != 0)
|
template, action, idx);
|
||||||
cdata->action = xstrdup(args->argv[0]);
|
|
||||||
else
|
|
||||||
cdata->action = xstrdup("select-window -t '%%'");
|
|
||||||
|
|
||||||
cdata->idx = wm->idx;
|
|
||||||
cdata->client->references++;
|
|
||||||
cdata->session->references++;
|
|
||||||
|
|
||||||
cdata->ft_template = xstrdup(template);
|
|
||||||
format_add(cdata->ft, "line", "%u", idx);
|
|
||||||
format_session(cdata->ft, s);
|
|
||||||
format_winlink(cdata->ft, s, wm);
|
|
||||||
format_window_pane(cdata->ft, wm->window->active);
|
|
||||||
|
|
||||||
window_choose_add(wl->window->active, cdata);
|
|
||||||
}
|
}
|
||||||
|
xfree(action);
|
||||||
|
|
||||||
window_choose_ready(wl->window->active,
|
window_choose_ready(wl->window->active,
|
||||||
cur, cmd_choose_window_callback, cmd_choose_window_free);
|
cur, cmd_choose_window_callback, cmd_choose_window_free);
|
||||||
|
|
||||||
@ -110,7 +102,6 @@ cmd_choose_window_callback(struct window_choose_data *cdata)
|
|||||||
if (!session_alive(s))
|
if (!session_alive(s))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xasprintf(&cdata->raw_format, "%s:%u", s->name, cdata->idx);
|
|
||||||
window_choose_ctx(cdata);
|
window_choose_ctx(cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +115,7 @@ cmd_choose_window_free(struct window_choose_data *cdata)
|
|||||||
cdata->client->references--;
|
cdata->client->references--;
|
||||||
|
|
||||||
xfree(cdata->ft_template);
|
xfree(cdata->ft_template);
|
||||||
xfree(cdata->action);
|
xfree(cdata->command);
|
||||||
format_free(cdata->ft);
|
format_free(cdata->ft);
|
||||||
xfree(cdata);
|
xfree(cdata);
|
||||||
}
|
}
|
||||||
|
14
tmux.h
14
tmux.h
@ -848,8 +848,7 @@ struct window_choose_data {
|
|||||||
struct session *session;
|
struct session *session;
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
char *ft_template;
|
char *ft_template;
|
||||||
char *raw_format;
|
char *command;
|
||||||
char *action;
|
|
||||||
u_int idx;
|
u_int idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2131,16 +2130,19 @@ void window_copy_pageup(struct window_pane *);
|
|||||||
|
|
||||||
/* window-choose.c */
|
/* window-choose.c */
|
||||||
extern const struct window_mode window_choose_mode;
|
extern const struct window_mode window_choose_mode;
|
||||||
void window_choose_vadd(
|
|
||||||
struct window_pane *, int, const char *, va_list);
|
|
||||||
void window_choose_add(struct window_pane *,
|
void window_choose_add(struct window_pane *,
|
||||||
struct window_choose_data *);
|
struct window_choose_data *);
|
||||||
void window_choose_ready(struct window_pane *,
|
void window_choose_ready(struct window_pane *,
|
||||||
u_int, void (*)(struct window_choose_data *),
|
u_int, void (*)(struct window_choose_data *),
|
||||||
void (*)(struct window_choose_data *));
|
void (*)(struct window_choose_data *));
|
||||||
struct window_choose_data *window_choose_data_create(
|
struct window_choose_data *window_choose_data_create(struct cmd_ctx *);
|
||||||
struct cmd_ctx *);
|
|
||||||
void window_choose_ctx(struct window_choose_data *);
|
void window_choose_ctx(struct window_choose_data *);
|
||||||
|
struct window_choose_data *window_choose_add_window(struct window_pane *,
|
||||||
|
struct cmd_ctx *, struct session *, struct winlink *,
|
||||||
|
const char *, char *, u_int);
|
||||||
|
struct window_choose_data *window_choose_add_session(struct window_pane *,
|
||||||
|
struct cmd_ctx *, struct session *, const char *,
|
||||||
|
char *, u_int);
|
||||||
|
|
||||||
/* names.c */
|
/* names.c */
|
||||||
void queue_window_name(struct window *);
|
void queue_window_name(struct window *);
|
||||||
|
@ -133,8 +133,7 @@ window_choose_data_create(struct cmd_ctx *ctx)
|
|||||||
wcd = xmalloc(sizeof *wcd);
|
wcd = xmalloc(sizeof *wcd);
|
||||||
wcd->ft = format_create();
|
wcd->ft = format_create();
|
||||||
wcd->ft_template = NULL;
|
wcd->ft_template = NULL;
|
||||||
wcd->action = NULL;
|
wcd->command = NULL;
|
||||||
wcd->raw_format = NULL;
|
|
||||||
wcd->client = ctx->curclient;
|
wcd->client = ctx->curclient;
|
||||||
wcd->session = ctx->curclient->session;
|
wcd->session = ctx->curclient->session;
|
||||||
wcd->idx = -1;
|
wcd->idx = -1;
|
||||||
@ -482,21 +481,22 @@ window_choose_ctx(struct window_choose_data *cdata)
|
|||||||
{
|
{
|
||||||
struct cmd_ctx ctx;
|
struct cmd_ctx ctx;
|
||||||
struct cmd_list *cmdlist;
|
struct cmd_list *cmdlist;
|
||||||
char *template, *cause;
|
char *cause;
|
||||||
|
|
||||||
template = cmd_template_replace(cdata->action,
|
/* The command template will have already been replaced. But if it's
|
||||||
cdata->raw_format, 1);
|
* NULL, bail here.
|
||||||
|
*/
|
||||||
|
if (cdata->command == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
if (cmd_string_parse(template, &cmdlist, &cause) != 0) {
|
if (cmd_string_parse(cdata->command, &cmdlist, &cause) != 0) {
|
||||||
if (cause != NULL) {
|
if (cause != NULL) {
|
||||||
*cause = toupper((u_char) *cause);
|
*cause = toupper((u_char) *cause);
|
||||||
status_message_set(cdata->client, "%s", cause);
|
status_message_set(cdata->client, "%s", cause);
|
||||||
xfree(cause);
|
xfree(cause);
|
||||||
}
|
}
|
||||||
xfree(template);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xfree(template);
|
|
||||||
|
|
||||||
ctx.msgdata = NULL;
|
ctx.msgdata = NULL;
|
||||||
ctx.curclient = cdata->client;
|
ctx.curclient = cdata->client;
|
||||||
@ -510,3 +510,53 @@ window_choose_ctx(struct window_choose_data *cdata)
|
|||||||
cmd_list_exec(cmdlist, &ctx);
|
cmd_list_exec(cmdlist, &ctx);
|
||||||
cmd_list_free(cmdlist);
|
cmd_list_free(cmdlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct window_choose_data *
|
||||||
|
window_choose_add_session(struct window_pane *wp, struct cmd_ctx *ctx,
|
||||||
|
struct session *s, const char *template, char *action, u_int idx)
|
||||||
|
{
|
||||||
|
struct window_choose_data *wcd;
|
||||||
|
|
||||||
|
wcd = window_choose_data_create(ctx);
|
||||||
|
wcd->idx = s->idx;
|
||||||
|
wcd->command = cmd_template_replace(action, s->name, 1);
|
||||||
|
wcd->ft_template = xstrdup(template);
|
||||||
|
format_add(wcd->ft, "line", "%u", idx);
|
||||||
|
format_session(wcd->ft, s);
|
||||||
|
|
||||||
|
wcd->client->references++;
|
||||||
|
wcd->session->references++;
|
||||||
|
|
||||||
|
window_choose_add(wp, wcd);
|
||||||
|
|
||||||
|
return (wcd);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct window_choose_data *
|
||||||
|
window_choose_add_window(struct window_pane *wp, struct cmd_ctx *ctx,
|
||||||
|
struct session *s, struct winlink *wl, const char *template,
|
||||||
|
char *action, u_int idx)
|
||||||
|
{
|
||||||
|
struct window_choose_data *wcd;
|
||||||
|
char *action_data;
|
||||||
|
|
||||||
|
wcd = window_choose_data_create(ctx);
|
||||||
|
|
||||||
|
xasprintf(&action_data, "%s:%d", s->name, wl->idx);
|
||||||
|
wcd->command = cmd_template_replace(action, action_data, 1);
|
||||||
|
xfree(action_data);
|
||||||
|
|
||||||
|
wcd->idx = wl->idx;
|
||||||
|
wcd->ft_template = xstrdup(template);
|
||||||
|
format_add(wcd->ft, "line", "%u", idx);
|
||||||
|
format_session(wcd->ft, s);
|
||||||
|
format_winlink(wcd->ft, s, wl);
|
||||||
|
format_window_pane(wcd->ft, wl->window->active);
|
||||||
|
|
||||||
|
wcd->client->references++;
|
||||||
|
wcd->session->references++;
|
||||||
|
|
||||||
|
window_choose_add(wp, wcd);
|
||||||
|
|
||||||
|
return (wcd);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user