2002-05-18 11:39:32 +00:00
|
|
|
/***************************************************************************
|
2005-09-02 05:39:09 +00:00
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
2002-05-18 11:39:32 +00:00
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002 by Robert Hak <rhak at ramapo.edu>
|
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-05-18 11:39:32 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2005-09-02 05:39:09 +00:00
|
|
|
#include "plugin.h"
|
2008-11-20 11:27:31 +00:00
|
|
|
#include "lib/helper.h"
|
2002-05-18 11:39:32 +00:00
|
|
|
|
2010-08-24 14:30:46 +00:00
|
|
|
|
2006-01-15 18:20:18 +00:00
|
|
|
|
2008-05-20 20:55:14 +00:00
|
|
|
static const char* const credits[] = {
|
2002-10-15 07:50:52 +00:00
|
|
|
#include "credits.raw" /* generated list of names from docs/CREDITS */
|
2002-05-18 11:39:32 +00:00
|
|
|
};
|
|
|
|
|
2008-05-21 07:08:27 +00:00
|
|
|
static bool stop_autoscroll(int action)
|
|
|
|
{
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case ACTION_STD_CANCEL:
|
|
|
|
case ACTION_STD_OK:
|
|
|
|
case ACTION_STD_NEXT:
|
|
|
|
case ACTION_STD_NEXTREPEAT:
|
|
|
|
case ACTION_STD_PREV:
|
|
|
|
case ACTION_STD_PREVREPEAT:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-05-20 20:55:14 +00:00
|
|
|
static int update_rowpos(int action, int cur_pos, int rows_per_screen, int tot_rows)
|
2007-09-03 00:36:20 +00:00
|
|
|
{
|
|
|
|
switch(action)
|
|
|
|
{
|
2007-10-15 08:25:29 +00:00
|
|
|
case ACTION_STD_PREV:
|
|
|
|
case ACTION_STD_PREVREPEAT:
|
2007-09-03 00:36:20 +00:00
|
|
|
cur_pos--;
|
|
|
|
break;
|
2007-10-15 08:25:29 +00:00
|
|
|
case ACTION_STD_NEXT:
|
|
|
|
case ACTION_STD_NEXTREPEAT:
|
2007-09-03 00:36:20 +00:00
|
|
|
cur_pos++;
|
|
|
|
break;
|
2021-12-07 20:48:33 +00:00
|
|
|
}
|
2007-09-03 00:36:20 +00:00
|
|
|
|
|
|
|
if(cur_pos > tot_rows - rows_per_screen)
|
|
|
|
cur_pos = 0;
|
|
|
|
if(cur_pos < 0)
|
|
|
|
cur_pos = tot_rows - rows_per_screen;
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
return cur_pos;
|
|
|
|
}
|
|
|
|
|
2008-05-20 20:55:14 +00:00
|
|
|
static void roll_credits(void)
|
2002-09-05 17:58:27 +00:00
|
|
|
{
|
2007-09-03 00:36:20 +00:00
|
|
|
/* to do: use target defines iso keypads to set animation timings */
|
2020-07-15 23:40:55 +00:00
|
|
|
#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
2006-05-29 10:21:22 +00:00
|
|
|
#define PAUSE_TIME 0
|
|
|
|
#define ANIM_SPEED 100
|
|
|
|
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|
|
|
|
#define PAUSE_TIME 0
|
|
|
|
#define ANIM_SPEED 35
|
2006-08-09 13:25:19 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
|
|
|
#define PAUSE_TIME 0
|
|
|
|
#define ANIM_SPEED 100
|
2006-05-29 10:21:22 +00:00
|
|
|
#else
|
|
|
|
#define PAUSE_TIME 1
|
|
|
|
#define ANIM_SPEED 40
|
|
|
|
#endif
|
2002-09-05 17:58:27 +00:00
|
|
|
|
2006-05-29 10:21:22 +00:00
|
|
|
#define NUM_VISIBLE_LINES (LCD_HEIGHT/font_h - 1)
|
|
|
|
#define CREDITS_TARGETPOS ((LCD_WIDTH/2)-(credits_w/2))
|
2002-09-05 17:58:27 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
int i=0, j=0, namepos=0, offset_dummy;
|
2006-05-29 10:21:22 +00:00
|
|
|
int name_w, name_h, name_targetpos=1, font_h;
|
|
|
|
int credits_w, credits_pos;
|
|
|
|
int numnames = (sizeof(credits)/sizeof(char*));
|
2007-09-06 22:32:46 +00:00
|
|
|
char name[40], elapsednames[32];
|
2007-09-03 00:36:20 +00:00
|
|
|
int action = ACTION_NONE;
|
|
|
|
|
|
|
|
/* control if scrolling is automatic (with animation) or manual */
|
|
|
|
bool manual_scroll = false;
|
2003-03-17 21:16:23 +00:00
|
|
|
|
2005-09-02 05:39:09 +00:00
|
|
|
rb->lcd_setfont(FONT_UI);
|
2006-05-29 10:21:22 +00:00
|
|
|
rb->lcd_clear_display();
|
|
|
|
rb->lcd_update();
|
2005-09-02 05:39:09 +00:00
|
|
|
|
2006-05-29 10:21:22 +00:00
|
|
|
rb->lcd_getstringsize("A", NULL, &font_h);
|
2002-09-05 17:58:27 +00:00
|
|
|
|
2006-05-29 10:21:22 +00:00
|
|
|
/* snprintf "credits" text, and save the width and height */
|
|
|
|
rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
|
|
|
|
j+1, numnames);
|
|
|
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
|
|
|
|
|
|
|
/* fly in "credits" text from the left */
|
|
|
|
for(credits_pos = 0 - credits_w; credits_pos <= CREDITS_TARGETPOS;
|
|
|
|
credits_pos += (CREDITS_TARGETPOS-credits_pos + 14) / 7)
|
|
|
|
{
|
2005-09-02 05:39:09 +00:00
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
2006-05-29 10:21:22 +00:00
|
|
|
rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h);
|
2005-09-02 05:39:09 +00:00
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
2006-05-29 10:21:22 +00:00
|
|
|
rb->lcd_putsxy(credits_pos, 0, elapsednames);
|
|
|
|
rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h);
|
|
|
|
rb->sleep(HZ/ANIM_SPEED);
|
|
|
|
}
|
2002-09-24 18:04:15 +00:00
|
|
|
|
2006-05-29 10:21:22 +00:00
|
|
|
/* first screen's worth of lines fly in */
|
|
|
|
for(i=0; i<NUM_VISIBLE_LINES; i++)
|
|
|
|
{
|
|
|
|
rb->snprintf(name, sizeof(name), "%s", credits[i]);
|
|
|
|
rb->lcd_getstringsize(name, &name_w, &name_h);
|
|
|
|
|
|
|
|
rb->snprintf(elapsednames, sizeof(elapsednames), "[Credits] %d/%d",
|
|
|
|
i+1, numnames);
|
|
|
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
|
|
|
rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w, font_h);
|
2002-09-24 18:04:15 +00:00
|
|
|
|
2006-05-29 10:21:22 +00:00
|
|
|
for(namepos = 0-name_w; namepos <= name_targetpos;
|
|
|
|
namepos += (name_targetpos - namepos + 14) / 7)
|
|
|
|
{
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
2007-09-03 00:36:20 +00:00
|
|
|
/* clear any trails left behind */
|
|
|
|
rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
2006-05-29 10:21:22 +00:00
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
|
|
rb->lcd_putsxy(namepos, font_h*(i+1), name);
|
|
|
|
rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
2002-09-24 18:04:15 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* exit on abort, switch to manual on up/down */
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
2006-05-29 10:21:22 +00:00
|
|
|
}
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
2006-05-29 10:21:22 +00:00
|
|
|
}
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* process user actions (if any) */
|
2007-10-15 08:25:29 +00:00
|
|
|
if(ACTION_STD_CANCEL == action)
|
2006-05-29 10:21:22 +00:00
|
|
|
return;
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
manual_scroll = true; /* up/down - abort was catched above */
|
|
|
|
|
|
|
|
if(!manual_scroll)
|
|
|
|
{
|
|
|
|
j+= i;
|
|
|
|
|
|
|
|
/* pause for a bit if needed */
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ*PAUSE_TIME);
|
|
|
|
if(ACTION_STD_CANCEL == action)
|
2007-09-03 00:36:20 +00:00
|
|
|
return;
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
manual_scroll = true;
|
|
|
|
}
|
2006-05-29 10:21:22 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
if(!manual_scroll)
|
|
|
|
{
|
|
|
|
while(j < numnames)
|
2006-05-29 10:21:22 +00:00
|
|
|
{
|
2007-09-03 00:36:20 +00:00
|
|
|
/* just a screen's worth at a time */
|
|
|
|
for(i=0; i<NUM_VISIBLE_LINES; i++)
|
2007-08-30 19:55:54 +00:00
|
|
|
{
|
2007-09-03 00:36:20 +00:00
|
|
|
if(j+i >= numnames)
|
|
|
|
break;
|
|
|
|
offset_dummy=1;
|
2006-05-29 10:21:22 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->snprintf(name, sizeof(name), "%s",
|
|
|
|
credits[j+i-NUM_VISIBLE_LINES]);
|
|
|
|
rb->lcd_getstringsize(name, &name_w, &name_h);
|
|
|
|
|
|
|
|
/* fly out an existing line.. */
|
|
|
|
while(namepos<LCD_WIDTH+offset_dummy)
|
2007-08-30 19:55:54 +00:00
|
|
|
{
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
2007-09-03 00:36:20 +00:00
|
|
|
/* clear trails */
|
|
|
|
rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
2007-08-30 19:55:54 +00:00
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->lcd_putsxy(namepos, font_h*(i+1), name);
|
|
|
|
rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* exit on keypress, react to scrolling */
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
namepos += offset_dummy;
|
|
|
|
offset_dummy++;
|
|
|
|
} /* while(namepos<LCD_WIDTH+offset_dummy) */
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-08-30 19:55:54 +00:00
|
|
|
break;
|
2007-09-03 00:36:20 +00:00
|
|
|
|
|
|
|
rb->snprintf(name, sizeof(name), "%s", credits[j+i]);
|
|
|
|
rb->lcd_getstringsize(name, &name_w, &name_h);
|
|
|
|
|
|
|
|
rb->snprintf(elapsednames, sizeof(elapsednames),
|
|
|
|
"[Credits] %d/%d", j+i+1, numnames);
|
|
|
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
|
|
|
rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
|
|
|
|
if (j+i < NUM_VISIBLE_LINES) /* takes care of trail on loop */
|
|
|
|
rb->lcd_update_rect(0, 0, LCD_WIDTH, font_h);
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
for(namepos = 0-name_w; namepos <= name_targetpos;
|
|
|
|
namepos += (name_targetpos - namepos + 14) / 7)
|
|
|
|
{
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
|
|
|
rb->lcd_fillrect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
|
|
rb->lcd_putsxy(namepos, font_h*(i+1), name);
|
|
|
|
rb->lcd_update_rect(0, font_h*(i+1), LCD_WIDTH, font_h);
|
|
|
|
rb->lcd_update_rect(CREDITS_TARGETPOS, 0, credits_w,font_h);
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* stop on keypress */
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ/ANIM_SPEED);
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
2007-08-30 19:55:54 +00:00
|
|
|
}
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
|
|
|
namepos = name_targetpos;
|
|
|
|
} /* for(i=0; i<NUM_VISIBLE_LINES; i++) */
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ*PAUSE_TIME);
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
break;
|
2002-09-05 17:58:27 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
j+=i; /* no user intervention, draw the next screen-full */
|
|
|
|
} /* while(j < numnames) */
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* handle the keypress that we intercepted during autoscroll */
|
2007-10-15 08:25:29 +00:00
|
|
|
if(ACTION_STD_CANCEL == action)
|
2006-05-29 10:21:22 +00:00
|
|
|
return;
|
2008-05-20 20:55:14 +00:00
|
|
|
if(stop_autoscroll(action))
|
2007-09-03 00:36:20 +00:00
|
|
|
manual_scroll = true;
|
|
|
|
} /* if(!manual_scroll) */
|
2007-08-30 19:55:54 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
if(manual_scroll)
|
|
|
|
{
|
|
|
|
/* user went into manual scrolling, handle it here */
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
2007-10-15 08:25:29 +00:00
|
|
|
while(ACTION_STD_CANCEL != action)
|
2007-09-03 00:36:20 +00:00
|
|
|
{
|
|
|
|
rb->lcd_clear_display();
|
|
|
|
rb->snprintf(elapsednames, sizeof(elapsednames),
|
2007-09-06 22:32:46 +00:00
|
|
|
"[Credits] %d-%d/%d", j+1,
|
|
|
|
j+NUM_VISIBLE_LINES, numnames);
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->lcd_getstringsize(elapsednames, &credits_w, NULL);
|
|
|
|
rb->lcd_putsxy(CREDITS_TARGETPOS, 0, elapsednames);
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
for(i=0; i<NUM_VISIBLE_LINES; i++)
|
2010-08-28 21:46:45 +00:00
|
|
|
rb->lcd_putsxyf(0, font_h*(i+1), "%s", credits[j+i]);
|
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->lcd_update();
|
2008-12-13 07:36:44 +00:00
|
|
|
|
|
|
|
rb->yield();
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-09-03 00:36:20 +00:00
|
|
|
/* wait for user action */
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, TIMEOUT_BLOCK);
|
|
|
|
if(ACTION_STD_CANCEL == action)
|
2007-09-03 00:36:20 +00:00
|
|
|
return;
|
|
|
|
j = update_rowpos(action, j, NUM_VISIBLE_LINES, numnames);
|
|
|
|
}
|
|
|
|
return; /* exit without animation */
|
|
|
|
}
|
2021-12-07 20:48:33 +00:00
|
|
|
|
2007-10-15 08:25:29 +00:00
|
|
|
action = rb->get_action(CONTEXT_LIST, HZ*3);
|
|
|
|
if(ACTION_STD_CANCEL == action)
|
2006-05-29 10:21:22 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
offset_dummy = 1;
|
|
|
|
|
|
|
|
/* now make the text exit to the right */
|
2007-09-03 00:36:20 +00:00
|
|
|
for(credits_pos = (LCD_WIDTH/2)-(credits_w/2);
|
|
|
|
credits_pos <= LCD_WIDTH+offset_dummy;
|
2006-05-29 10:21:22 +00:00
|
|
|
credits_pos += offset_dummy, offset_dummy++)
|
|
|
|
{
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
|
|
|
|
rb->lcd_fillrect(0, 0, LCD_WIDTH, font_h);
|
|
|
|
rb->lcd_set_drawmode(DRMODE_SOLID);
|
|
|
|
rb->lcd_putsxy(credits_pos, 0, elapsednames);
|
|
|
|
rb->lcd_update();
|
2002-09-05 17:58:27 +00:00
|
|
|
}
|
|
|
|
}
|
2006-05-29 10:21:22 +00:00
|
|
|
|
2009-01-16 10:34:40 +00:00
|
|
|
enum plugin_status plugin_start(const void* parameter)
|
2007-09-03 00:36:20 +00:00
|
|
|
{
|
|
|
|
(void)parameter;
|
|
|
|
|
2020-07-24 22:14:32 +00:00
|
|
|
#ifdef HAVE_BACKLIGHT
|
2007-09-03 00:36:20 +00:00
|
|
|
/* Turn off backlight timeout */
|
2011-01-24 12:29:16 +00:00
|
|
|
backlight_ignore_timeout();
|
2020-07-24 22:14:32 +00:00
|
|
|
#endif
|
2007-09-03 00:36:20 +00:00
|
|
|
|
2021-12-09 20:35:53 +00:00
|
|
|
#if LCD_DEPTH>=16
|
|
|
|
rb->lcd_set_foreground (LCD_WHITE);
|
|
|
|
rb->lcd_set_background (LCD_BLACK);
|
|
|
|
#endif
|
2007-09-03 00:36:20 +00:00
|
|
|
rb->show_logo();
|
|
|
|
|
|
|
|
/* Show the logo for about 3 secs allowing the user to stop */
|
2009-01-08 12:32:35 +00:00
|
|
|
if(!rb->action_userabort(3*HZ))
|
|
|
|
roll_credits();
|
2020-07-24 22:14:32 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_BACKLIGHT
|
2007-09-03 00:36:20 +00:00
|
|
|
/* Turn on backlight timeout (revert to settings) */
|
2011-01-24 12:29:16 +00:00
|
|
|
backlight_use_settings();
|
2020-07-24 22:14:32 +00:00
|
|
|
#endif
|
2007-09-03 00:36:20 +00:00
|
|
|
|
|
|
|
return PLUGIN_OK;
|
|
|
|
}
|