powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / ProgressIndicator в ADF
25 сообщений из 91, страница 1 из 4
ProgressIndicator в ADF
    #38109901
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго здравия, дорогие коллеги.
Есть такая задача: имеется страница основанная на темплейте с кнопочками, по нажатию на кнопку выполняется коннект и прочие операции с удаленным сервером через ssh. Для корректного отображения процесса, хочется по нажатию этой же кнопочки, получать запуск и останов ProgressIndicator-а, но... все примеры, связанные с данным функционалом основаны на работе двух кнопочек "Старт" и "Стоп" - с ними все отлично работает. А вот с одной кнопкой никак, например, наипростейший вариант - запускать попап с прогрессом и закрывать его при выполнении процесса, оставляю в екшн методе кнопки запуск попапа и выполнение скрипта. Он запускается, ничего не делает какое-то время(кнопка в это врмя в состоянии недоступно), потом попап с прогрессом и сообщение лога выводятся вместе. Я так понимаю, все что в экшен листенере кнопки выполняется в одном потоке и поэтому получить результат отдельно нельзя.
Пробовала запускать попап через клиент листенер с помощью JavaScript, он и не ругается, но и ничего не делает, возможно, из-за того, что это темплейт и бины не видят друг-друга(не знаю как это еще объяснить).
В общем, кто как выходил из этой ситуации?
Использую JDev 11gR2
Как всегда, благодарна идеям :)
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38110353
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ничего не понял :).
Если с двумя кнопочками всё работает, то непонятно, какая проблема переделать для одной кнопки?
В чём именно затык?
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38110444
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
P.S. Если вы хотите видеть прогресс выполнения длинной операции и возможность её прервать вам не обойтись без создания нового потока, в котором будет эта операция выполняться. А на view достаточно будет добавить компонент poll, который будет обновлять состояние progress indicator. Это если я всё правильно понял :)
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38110535
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MOHAX777Это если я всё правильно понял :)
не совсем
MOHAX777В чём именно затык?
в том, что эти два процесса: отображение прогресса и сам процесс на сервере, выполняются в одном потоке, и получается, что как результат я получаю все скопом на выходе из екшн. листенера.
Поэтому их нужно как-то разграничить, мне подсказали 2 варианта: выделить выполнение процесса в отдельный поток, либо запускать его не по екшн листенеру кнопки, а по клиент листенеру, а по экшн листенеру отображение процесса ганять.
Попробую для начала 2й вариант, с разграничение потоков пока работать не приходилось.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38111803
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana Palunв том, что эти два процесса: отображение прогресса и сам процесс на сервере, выполняются в одном потоке, и получается, что как результат я получаю все скопом на выходе из екшн. листенера.
Поэтому их нужно как-то разграничить, мне подсказали 2 варианта: выделить выполнение процесса в отдельный поток, либо запускать его не по екшн листенеру кнопки, а по клиент листенеру, а по экшн листенеру отображение процесса ганять.
Попробую для начала 2й вариант, с разграничение потоков пока работать не приходилось.
Про первый вариант я вам в p.s. как раз и описал, а вот про второй вариант у меня сильные сомнения, что такое вообще возможно.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38111889
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MOHAX777Про первый вариант я вам в p.s. как раз и описал, а вот про второй вариант у меня сильные сомнения, что такое вообще возможно.
попробовала, возможно, но не в моем случае. Т.к. у меня на клиенте работа с радиоБаттонами, приходится сетить переменные, а вызов по клиентлистенеру все переменные обнуляет. Так шо "факир был пьян и фокус неудался", выделила выполнение скрипта в отдельный поток, все отрабатывает, НО, мне нужно выводить лог этого скрипта в виде сообщения на клиент, а FacesContext из потока не виден. Передать его в бин никак не могу, поскольку информация по процессу умирает вместе с потоком...
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113657
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana Palun,

Используйте poll, в котором берите текст из потока и выводите на экран. Не вижу проблем.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113678
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MOHAX777Oksana Palun,
Используйте poll, в котором берите текст из потока и выводите на экран. Не вижу проблем.
13774749 и ниже.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113828
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczMOHAX777Oksana Palun,
Используйте poll, в котором берите текст из потока и выводите на экран. Не вижу проблем.
13774749 и ниже.

метод poll будет видеть facecontext, поэтому туда можно будет вывести лог из потока операции.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113841
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MOHAX777метод poll будет видеть facecontext, поэтому туда можно будет вывести лог из потока операции.
Так у Oksana Palun проблема в том что она не может передать данные из контекста запроса\ответа в асинхронную задачу и из асинхронной задачи обратно в контекста запроса\ответа.
Вместо того чтобы получить данные из facecontext и положить в асинхронную задачу, пытается использовать facecontext в самой асинхронной задаче.
Опять же все эти пляски со своими потоками в JEE вообще не рекомендуются без JMS. Тем более, если опыта работы с многопоточностью минимум.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113845
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MOHAX777метод poll будет видеть facecontext, поэтому туда можно будет вывести лог из потока операции.
И ещё не понятно куда буферизировать лог до того как следующий poll пришел. А если он ещё и жирный?
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113873
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczMOHAX777метод poll будет видеть facecontext, поэтому туда можно будет вывести лог из потока операции.
Так у Oksana Palun проблема в том что она не может передать данные из контекста запроса\ответа в асинхронную задачу и из асинхронной задачи обратно в контекста запроса\ответа.
Вместо того чтобы получить данные из facecontext и положить в асинхронную задачу, пытается использовать facecontext в самой асинхронной задаче.
Опять же все эти пляски со своими потоками в JEE вообще не рекомендуются без JMS. Тем более, если опыта работы с многопоточностью минимум.
Я делала и так и так. С пулом не сложилось, потому, что метод, который нужно вызывать в пуле, вызывается из бина, где инициализированы переменные, которые устанавливаются на клиенте. При срабатывании пула, они обнуляются, где это настраивается, если настраивается, я не нашла. Поэтому перешла к варианту с потоками,

"Вместо того чтобы получить данные из facecontext и положить в асинхронную задачу"

в поток я данные с клиента передаю, но задача в потоке возвращает лог, это совсем другие данные, которые нужно вернуть в facecontext. Ожидать этот лог, в клиентском бине, смысле не имеет, это будет то же самое, что и просто выполнение процесса по кнопке.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38113916
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunЯ делала и так и так.

Как и как?

Oksana PalunС пулом не сложилось, потому, что метод, который нужно вызывать в пуле, вызывается из бина, где инициализированы переменные, которые устанавливаются на клиенте. При срабатывании пула, они обнуляются, где это настраивается, если настраивается, я не нашла. Поэтому перешла к варианту с потоками,

Что такое "пул" в вашем понимании в этой теме, по-моему ещё никто не понял. Вы pool и poll часом не путаете?

Oksana Palun"Вместо того чтобы получить данные из facecontext и положить в асинхронную задачу"
в поток я данные с клиента передаю,
Вы не можете прямо с "клиента" передать данные в поток. Клиент отправляет данные на сервер, и этот запрос уже обрабатывается в контексте JSF. А там вы собираете данные из запроса и помещаета в "свой поток".
Вы бы уже, что ли, код показали. Потому что в вашей персональной терминологии, разобратся сложно.

Oksana Palunно задача в потоке возвращает лог, это совсем другие данные,

Мы и не ожидали что это будут "те же самые данные".

Oksana Palunкоторые нужно вернуть в facecontext.
Данные нужно сложить куда-то и замапить на id юзера\клиента\задачи\сессии. А потом когда запрос придёт ещё раз с клиента (если реализовать poll). Найти лог по id и вернуть.

Oksana PalunОжидать этот лог, в клиентском бине, смысле не имеет, это будет то же самое, что и просто выполнение процесса по кнопке.
Что такое "клиентский бин"? Не нужно ничего "ожидать".
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114015
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunЯ делала и так и так. С пулом не сложилось, потому, что метод, который нужно вызывать в пуле, вызывается из бина, где инициализированы переменные, которые устанавливаются на клиенте. При срабатывании пула, они обнуляются, где это настраивается, если настраивается, я не нашла. Поэтому перешла к варианту с потоками


Вы как-то странно рассматриваете задачу, потоки и poll не должны расматриваться как "или то или другое". В данном случае они работают вместе:

1. По нажатии на кнопку "Пуск" создаётся поток, который сохраняется в application scope с привязкой к пользователю. В этом потоке есть метод, который отдаёт текущий лог.
2. Запускается poll с нужным интервалом, при этом в методе этого poll берётся нужный поток и вызывается метод, который возвращает лог. Этот лог выводим на экран. В случае, если поток завершил работу, то "дизэйблим" poll и "чистим" поток.

Проблемы:
1. если приложение валиться, то задачи мрут, если нужно их сохранение, то имеет смысл задействовать БД для хранения задач.
2. Необходимо чистить сохранённые в application scope потоки, если пользователь вышел/отвалился до завершения задачи. Впрочем, его CG может автоматом убрать, но тогда надо думать, где сохранять лог операции. Может, уважаемый Blazkowicz прояснит этот момент.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114036
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MOHAX7771. если приложение валиться, то задачи мрут, если нужно их сохранение, то имеет смысл задействовать БД для хранения задач.

В этом случае имеет смысл сразу брать JMS или любую готовую MQ. Городить очереди в базе, это уже попахивает лисопедом.

MOHAX7772. Необходимо чистить сохранённые в application scope потоки, если пользователь вышел/отвалился до завершения задачи.

Сервер точно не может знать когда юзер отвалился, разве что если сессия явно инвалидирована. Если асинхронная задача имеет цикличность, то, да. Можно в цикле проверять валидность сессии. Но, как я понимаю, из постановки задачи в данном случае там запускается какой-то тормозной скрипт, поэтому прервать его получится вряд ли. Разве что если оно понимает Thread.interrupt() нормально. Т.е. это нужно смотреть на то какая конкретно там задача решается асинхронно. Можно её прибить или нет.

MOHAX777Впрочем, его CG может автоматом убрать, но тогда надо думать, где сохранять лог операции.
Вот именно поэтому для данной задачи, я бы использовал COMET/Long Polling, чтобы лог незамедлительно слать клиенту. Нечего его на сервере хранить и потом ещё не известно когда чистить.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114039
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MOHAX7771. По нажатии на кнопку "Пуск" создаётся поток, который сохраняется в application scope с привязкой к пользователю. В этом потоке есть метод, который отдаёт текущий лог.
2. Запускается poll с нужным интервалом, при этом в методе этого poll берётся нужный поток и вызывается метод, который возвращает лог. Этот лог выводим на экран. В случае, если поток завершил работу, то "дизэйблим" poll и "чистим" поток.

А можете мне про этот метод рассказать подробнее? Я создала поток, по пулу пытаюсь его найти, из видимых мне, на данный момент способов, это список StackTraces у Thread, он его видит, но ничего считать я не могу.

MOHAX777Проблемы:
1. если приложение валиться, то задачи мрут, если нужно их сохранение, то имеет смысл задействовать БД для хранения задач.
2. Необходимо чистить сохранённые в application scope потоки, если пользователь вышел/отвалился до завершения задачи. Впрочем, его CG может автоматом убрать, но тогда надо думать, где сохранять лог операции. Может, уважаемый Blazkowicz прояснит этот момент.
Про отвалы мне уже говорили, пока даже и не думала, об этом. Будем решать проблемы по мере их поступления, задача вроде не должна отрабатывать дольше 10ти минут, а за это время он не валится. И кстати, есть ли в ADF возможность управления временем жизни сессий?
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114041
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczТ.е. это нужно смотреть на то какая конкретно там задача решается асинхронно. Можно её прибить или нет.
Поднятие/останов инстансов на линуксовом сервере.
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114044
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunА можете мне про этот метод рассказать подробнее? Я создала поток, по пулу пытаюсь его найти, из видимых мне, на данный момент способов, это список StackTraces у Thread, он его видит, но ничего считать я не могу.


Извините но с каждым новым вашим сообщением возникает все большее желание поставить смайлик фейспалм. Ваша терминология просто взрывает мозг, выложите уже код, пожалуйста
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114053
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunЯ создала поток, по пулу пытаюсь его найти, из видимых мне, на данный момент способов, это список StackTraces у Thread, он его видит, но ничего считать я не могу.
Фак мой мозг. Сделайте HashMap с ключем http session id и значением ваш Thread. Хотя асинхронную задачу стоило инкапсулировать в что-то более приличное: Runnable, Сallable и т.п.

Oksana PalunИ кстати, есть ли в ADF возможность управления временем жизни сессий?
Google->ADF invalidate session
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114066
MOHAX777
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunMOHAX7771. По нажатии на кнопку "Пуск" создаётся поток, который сохраняется в application scope с привязкой к пользователю. В этом потоке есть метод, который отдаёт текущий лог.
2. Запускается poll с нужным интервалом, при этом в методе этого poll берётся нужный поток и вызывается метод, который возвращает лог. Этот лог выводим на экран. В случае, если поток завершил работу, то "дизэйблим" poll и "чистим" поток.

А можете мне про этот метод рассказать подробнее? Я создала поток, по пулу пытаюсь его найти, из видимых мне, на данный момент способов, это список StackTraces у Thread, он его видит, но ничего считать я не могу.

Ну вы же создаёте поток типа:

UploadFileThread upt = new UploadFileThread();
Thread threadUploadFile = new Thread(upt);
threadUploadFile.start();

вот и положите threadUploadFile в какой-нибудь map (application scope) с привязкой к пользователю.

Oksana PalunMOHAX777Проблемы:
1. если приложение валиться, то задачи мрут, если нужно их сохранение, то имеет смысл задействовать БД для хранения задач.
2. Необходимо чистить сохранённые в application scope потоки, если пользователь вышел/отвалился до завершения задачи. Впрочем, его CG может автоматом убрать, но тогда надо думать, где сохранять лог операции. Может, уважаемый Blazkowicz прояснит этот момент.
Про отвалы мне уже говорили, пока даже и не думала, об этом. Будем решать проблемы по мере их поступления, задача вроде не должна отрабатывать дольше 10ти минут, а за это время он не валится. И кстати, есть ли в ADF возможность управления временем жизни сессий?
стандартно через web.xml
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114074
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Oksana PalunПоднятие/останов инстансов на линуксовом сервере.
инстанс это "экземпляр". "экземпляр" он обычно чего-то (класса, SQL сервера и т.п.)? Это реализовано на pure Java, или запускается внешний процесс?
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114077
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczФак мой мозг. Сделайте HashMap с ключем http session id и значением ваш Thread. Хотя асинхронную задачу стоило инкапсулировать в что-то более приличное: Runnable, Сallable и т.п.


Вы конечно понимаете, но для ТС надо бы уточнение чтобы она не забывала регулярно чистить эту мапу
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114080
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
забыл никИзвините но с каждым новым вашим сообщением возникает все большее желание поставить смайлик фейспалм. Ваша терминология просто взрывает мозг
Ставьте, если очень хочется, я ADF только учу, поэтому ничего странного, что моя терминология хромает, о чем я Вас предупреждала ранее. Если вы бедете просто рассказывать, как неправильно я выражаюсь, будет менее эффективно, если вы меня поправите.
забыл никвыложите уже код, пожалуйста
ОК
1.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
public class ExecShell
 implements Runnable
{
  private String lcommand;
  public ExecShell()
  {
    super();
  }
  public ExecShell(String acommand)
  {
    lcommand = acommand;
  }
  public void run()
  {
    execShellCommand(lcommand);//здесь запускается процесс обработки данных по  SSH
  }


2. Создание потока в бине(manage bean) по actionListener
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  public void schemeAction()
    throws SQLException, URISyntaxException, IOException,
           PropertyVetoException, JSchException, InterruptedException
  {
    String scriptPath = "/ora/scripts/";
    if (getSchAction() != null)
    {
      if (getSchAction().equals("setUp")) // поднять
      {
        Thread t = new Thread(new ExecShell(scriptPath + "start_db_common " + getSig()));
         t.setName("eSh");
         t.start();
....


3. pool
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
               <af:poll id="pull"
                       binding="#{backingBeanScope.backing_fragments_Versions.pull}"
                       interval="10" partialTriggers="pull"
                       clientComponent="true">
                <af:clientListener method="isJobDone" type="poll"/>
                <af:serverListener type="pollListener"
                                   method="#{backingBeanScope.backing_fragments_Versions.pollListener}"/>
              </af:poll>


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  public void pollListener(ClientEvent aEvent)
    throws InterruptedException
  {
   if (progressPopup.initialStateMarked()){
       Object[] obj =  Thread.getAllStackTraces().keySet().toArray();
        // ?
       }
       new PopupUtil().hidePopup(progressPopup.getClientId(FacesContext.getCurrentInstance()));
     }
  }
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114085
Oksana Palun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BlazkowiczOksana PalunПоднятие/останов инстансов на линуксовом сервере.
инстанс это "экземпляр". "экземпляр" он обычно чего-то (класса, SQL сервера и т.п.)? Это реализовано на pure Java, или запускается внешний процесс?
инстанс схем
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
  public static Session createSession()
  {
    Session session = null;
    try
    {
      JSch jsch = new JSch();
      String user = "oracle";
      String pass = "...";
      String host = "photon";
      session = jsch.getSession(user, host, 22);
      session.setPassword(pass);
      session.setConfig("StrictHostKeyChecking", "no");
      session.connect();
    }
    catch (Exception e)
    {
      FacesContext.getCurrentInstance().addMessage(null,
                                                   new FacesMessage(e.getMessage()));
      e.printStackTrace();
    }
    return session;
  }

  public static void execShellCommand(String command)
  {
    try
    {
      Session session = createSession();
      Channel channel = null;
      try
      {
        byte[] tmp = new byte[1024];
        channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);
        channel.setInputStream(null);
        ((ChannelExec) channel).setErrStream(System.err);
        InputStream in = channel.getInputStream();
        channel.connect();
        while (true)
        {
          while (in.available() > 0)
          {
            int i = in.read(tmp, 0, 1024);
            if (i < 0)
              break;
              JOptionPane.showMessageDialog(new JFrame("Message"),  new String(tmp,
                                                                                     0,
                                                                                     i));
          }
          if (channel.isClosed())
          {
            System.out.println("exit-status: " + channel.getExitStatus());
            break;
          }
          try
          {
            Thread.sleep(1000);
          }
          catch (Exception ee)
          {
           JOptionPane.showMessageDialog(new JFrame("Message"), ee.getMessage());
          }
        }
        channel.disconnect();
        session.disconnect();
        System.out.println("DONE");

      }
      catch (Exception e)
      {
        JOptionPane.showMessageDialog(new JFrame("Message"),e.getMessage());
        e.printStackTrace();
      }
    }
    catch (Exception e)
    {
      System.out.println(e);
    }
  }
...
Рейтинг: 0 / 0
ProgressIndicator в ADF
    #38114107
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никВы конечно понимаете, но для ТС надо бы уточнение чтобы она не забывала регулярно чистить эту мапу
И это не такая простая проблема, как может показатся на первый взгляд.
...
Рейтинг: 0 / 0
25 сообщений из 91, страница 1 из 4
Форумы / Java [игнор отключен] [закрыт для гостей] / ProgressIndicator в ADF
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]