Здравствуйте, гость ( Вход | Регистрация )
| Дата поста: | В теме: | За сообщение: | Спасибо сказали: | ||
|---|---|---|---|---|---|
| Сегодня, 1:03 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
MIKHAIL | |||
| 1.2.2012, 10:31 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
Как бы и Птока 0.4.2.0 умеет, судя по ченчлогам. Тут уже писали и не раз. |
MIKHAIL | ||
| 27.1.2012, 15:18 |
StatPX Lite API2 | Веб-статистика хаба, чат-ранг, статистика местоположения юзеров |
Sergius`, открываешь скрипт, находишь функцию UserConnected(user), там находишь строку Код SendMOTD(user) и вместо этого вписываешь это: Код if user.iProfile ~= -1 then SendMOTD(user) end |
Sergius` | ||
| 26.1.2012, 21:29 |
RusHub: Запрет неразрывного пробела rushub |
Setuper, как у тебя всё запутано! Извини, даже после твоего пояснения я не понял, то ли ты там описал небрежно, то ли что..Не хочется развивать разбор этих нюансов.. Что до обвинений меня - так помогайте сами, человек уже запарил чат хаба Майдц, мой приват там же, я хоть пытаюсь помочь, а те, кто занимается Русхабом, упорно делают вид, что не замечают его просьбы. И тут ты появился только после того, когда я что-то не так подсказал. Как понимаю, так и подсказываю. ShadoWx, вот тебе работающий на Птоке код: Код function ChatArrival(tUser, sData) Попытайся переделать его под себя. Хотя вроде они похожи.local sMsg = sData:match("^%b<>%s(.-)$") if sMsg:find"" then Core.SendToNick("ShadoWx", "Неразрывный перенос") return true elseif sMsg:find" " then Core.SendToNick("ShadoWx", "Неразрывный пробел") return true end end |
ShadoWx | ||
| 26.1.2012, 15:43 |
Список пользователей |
fmit, ну этот вариант (без таблицы, проверка с подстановкой каждого префикса в одной строке) у меня сразу был готов, но я хотел с таблицей, на будущее. Тогда вот: Код local sBotMsg = "<"..SetMan.GetString(21).."> *** Просьба добавить к нику префикс и перезайти. Если у вас ADSL - припишите к нику спереди префикс [ADSL], если FTTB - то [FTTB]. Пример:\n [ADSL]Александр, [FTTB]4uMa и т.д." -- текст можно переделать на свой function ValidateNickArrival(tUser, sData) if not tUser.sNick:find"^%[ADSL%]" and not tUser.sNick:find"^%[FTTB%]" then Core.SendToUser(tUser, sBotMsg) Core.Disconnect(tUser) end end |
fmit | ||
| 26.1.2012, 14:20 |
СКРИПТ ЗАГЛУШКИ |
Ищите сами. Здесь вам не детский сад. 1. Наверху страницы справа увидишь ПОИСК и окошко поисковое. Слова для поиска подберите опытным путём. 2. А ещё на форуме есть каталог тем. Каталог разбит на понятные для любого разделы. Полазай. |
Nickolya, shullz, Littlemuk | ||
| 25.1.2012, 5:04 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
Автоматически. Но не потому, что local tContains, а потому, что они задействованы только для выполнения данного цикла. А если внутри этого цикла запустишь ещё один цикл с переменными с такими же наименованиями, они всё равно не будут путаться. |
MIKHAIL | ||
| 25.1.2012, 4:50 |
XenoPhobia Скрипт для защиты от потенциальных прокси-спамеров из других стран |
Скрипт для защиты от потенциальных прокси-спамеров (да и не только прокси) из других стран Название: XenoPhobia (Ксенофобия) Платформа: PtokaX API: 2 Автор: Ksan (aka Trans) Местоположение: г.Томск Дата: 25-01-2012 Дополнительно: Для работы скрипта необходима база стран и диапазонов, и она должна лежать в папке CFG в корневой папке Птоки. Скорее всго, она у вас уже есть, хотя, может, и устарела слегка. Последнюю версию можно Распаковать из архива и положить в папку CFG. Птоки. Описание: -- если включен флажок бана, то банит (просто не пускает на хаб) юзеров из стран из отдельной таблицы (флажок ставится/снимается через меню) -- если включен флажок заглушки, то заглушает те страны, которых нет в списке исключений (флажок ставится/снимается через меню) -- но из этих стран не глушит те диапазоны, которые в исключениях (к диапазонам можно добавлять комментарии) -- также не глушатся ники, которые есть в исключениях (к никам можно добавить комментарии) -- отдельные IP тоже можно вносить в исключения (как диапазон, у которого начало и конец совпадают с данным IP) -- при показе страны заходящего на хаб или пишущего сообщение юзера показывается полное название страны + аббревиатура кода, например, так: "Россия (RU)". Так же и при просмотре списка. -- можно посмотреть списки исключений - страны, диапазоны, ники и список забаненных стран. -- все вышеуказанные операции производятся через меню, не останавливая скрипт и не открывая файлы блокнотом -- в коде присутствует примитивное предупреждение о рекламе (если в приватном сообщении у юзера из заглушенной страны имеется точное совпадение хотя бы одного слова из таблицы меток (tMarkers), то это сообщение скрипт покажет операторам/админам в приват). Поэтому вносите туда выражения только однозначные, например, "http://" и/или "dchub://", скрипт не антиреклама и не антимат, поэтому слова-исключения не предусмотрены -- сообщения юзеров заглушенных стран (не исключенных тем или иным способом) в чате видит только сам юзер и операторы/админы Примечания: -- скрипт написан практически без проверки корректности ввода (дабы не усложнять и не загромождать код), так что следите за своими руками, при неправильном вводе просто отмолчится, хотя ничего в таблицы не добавит и не убавит. -- в таблицы страны вносятся ТОЛЬКО в виде двухбуквенных кодов стран латинскими буквами, например: RU , но по ходу работы скрипт сам определяет полное название страны и при необходимости сообщает его (при выводе таблицы или в текущих сообщениях) -- текстовку скрипта можете изменять по своему усмотрению, но для этого вы должны хорошо понимать суть этого участка кода -- можно удалить из исключений все страны, даже свою, и добавить только диапазоны нужные, это ограничит любое общение всем, кроме своего окружения, например, локалки -- при запуске скрипта должны быть в наличии папка "XenoPhobia" и в ней 2 файла - один для динамических таблиц и второй - с полными названиями стран. Если файлы при запуске скрипта не обнаружатся, скрипт сообщит об этом, но сам останется в режиме ожидания, периодически проверяя их наличие, и при появлении файлов сразу же входит в нормальный режим. PS: -- чуть не забыл сказать - таблицу с полными названиями стран взял из скрипта CountryStats (автор - alex82). PPS: -- вдогонку - при первом запуске не забудьте заранее внести свой ник в список исключений (соблюдая структуру таблицы, как в представленных примерах), руками, а не через меню, иначе случайно можете оказаться без управления хабом, особенно это важно для тех, у кого хаб управляется удалённо. Картинки из жизни скрипта (списки в реале слегка форматированные, но тут это не будет видно): Список стран в исключениях Код [07:32:41] <Ксенофоб> *** Список разрешённых стран: 1: Армения (AM) 2: Азербайджан (AZ) 3: Болгария (BG) 4: Беларусь (BY) 5: Эстония (EE) 6: Европейский Союз (EU) 7: Грузия (GE) 8: Израиль (IL) 9: Киргизия (KG) 10: Казахстан (KZ) 11: Литва (LT) 12: Латвия (LV) 13: Польша (PL) 14: Россия (RU) 15: СССР (SU) 16: Таджикистан (TJ) 17: Туркмения (tm) 18: Украина (UA) 19: Узбекистан (UZ) Список невъездных стран Код [01:33:03] <Ксенофоб> *** Список забаненных стран: 1: Бразилия (BR) 2: Китай (CN) 3: Дания (DK) 4: Испания (ES) 5: Индия (IN) 6: Италия (IT) 7: США (US) 8: Вьетнам (VN) Список разрешённых диапазонов Код [07:34:46] <Ксенофоб> *** Список разрешённых диапазонов: 1: 176.65.48.0 -- 176.65.55.255 [ INTERNET-NET, Томск ] 2: 78.139.249.42 -- 78.139.249.42 [ TOMTEL-NET, Томск ] 3: 172.16.0.0 -- 172.31.255.255 [ Локалка ] 4: 90.188.95.153 -- 90.188.95.153 [ It's me! ] 5: 10.0.0.0 -- 10.255.255.255 [ Локалка ] 6: 46.161.144.0 -- 46.161.159.255 [ NTS-ETTH, Томск ] 7: 127.0.0.0 -- 127.255.255.255 [ Компьютер с хабом ] 8: 192.168.0.0 -- 192.168.255.255 [ Локалка ] Список ников-исключений Код [07:05:56] <Ксенофоб> *** Список ников-исключений: 1: Тест [ Просто так ] 2: Indy[wrk] [ Админ ] 3: Indy [ It's me! ] 4: Спорт [ ] 5: Ksan [ Админ ] 6: TestNick [ Тестер ] Граница на замке! UPD 1: -- добавил "бан" отдельных стран (юзеры оттуда не будут допускаться на хаб) с возможностью добавления/удаления стран в этот список через меню (2-буквенный код страны) и просмотр этого списка -- также добавил флажок включения этого бана (флажок можно ставить/снимать через меню) -- и добавлен флажок такой же относительно заглушек стран, включая и меню -- незначительно оптимизировал код -- таблицы/файлы совместимы с предыдущей версией скрипта, достаточно просто ещё добавить через меню страны в таблицу банов -- после перезапуска скрипта перезайти необходимо (добавлены новые пункты в меню) Внимание! Исправлено, перезалито. Заодно подправил организацию и вывод меню, и кое-что в коде незначительно подправил. Дата последнего апдейта: 2012-02-01 20:27 МСК |
Nickolya, ustas, rival, WINS, Mellon | ||
| 22.1.2012, 8:05 |
SuspendHub Блокирование хаба от входящих (защита от внешних атак) |
Артём | |||
| 13.1.2012, 21:13 |
TotalGag для аварийной заглушки всего хаба (кроме определенных лиц) |
MIKHAIL, ага, есть такое, спасибо, что подсказал! Это потому, что я Код ToArrival = ChatArrival добавил в последний момент по просьбе кое-кого, не догадавшись проверить работу скрипта с изменением.Исправляется так - вместо кода: Код if sUngagable[tUser.sNick] ~= 1 and bFlag then нужно вот это (тут всего 1 строка перемещена)Core.SendToUser(tUser, "<"..tUser.sNick.."> "..sMsg) if not (sData:match("From:") and sData:match("To:")) then Core.SendToOps("<"..tUser.sNick.."> ••• "..sMsg) end return true end Код if sUngagable[tUser.sNick] ~= 1 and bFlag then if not (sData:match("From:") and sData:match("To:")) then Core.SendToOps("<"..tUser.sNick.."> ••• "..sMsg) Core.SendToUser(tUser, "<"..tUser.sNick.."> "..sMsg) end return true end А строку Код ToArrival = ChatArrival оставить включенным.UPD: -- перезалил исправленный скрипт в первом сообщении. |
MIKHAIL | ||
| 10.1.2012, 6:23 |
SuspendHub Блокирование хаба от входящих (защита от внешних атак) |
Скрипт блокирования хаба от входящих юзеров (вариант защиты от внешних атак) Название: SuspendHub.lua Версия: 1.0 Платформа: PtokaX API: API 2 Автор: Ksan (aka Trans) Город: Томск, Россия Дата: 10-01-2012 Описание: 1. Если вы заметили, что ваш хаб атакуют, то через меню можете заблокировать хаб для всех входящих. По умолчанию - на 5 минут (это регулируется в настройках хаба), также в меню есть блокирование на желаемое время (тоже в минутах). Разблокирование через меню либо по прошествию заданного времени. При блокировании хаб извне будет казаться отключенным, с соответствующими сообщениями, а сидящие в хабе ничего не почувствуют, всё будет работать в обычном режиме. 2. Есть в скрипте и код блокирования без срока, но это опасно в случае вылета из хаба последнего оператора/админа - будет некому разблокировать хаб вплоть до его перезагрузки (а для удалённых хабов в некоторых случаях и это может оказаться проблемой). Для включения команды блокирования без срока нужно раскомментировать код в 2-х местах - в отправке меню и в исполняемом коде 3. Сообщения о блокировании/разблокировании приходят автору команды и в Опчат. Текстовку можете менять по своему вкусу. |
Nickolya, ustas, Tsd, Cyber_voodoo, dickTATOR, nafig | ||
| 8.1.2012, 1:04 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
MIKHAIL, Ну и заодно - И да, чуть не забыл - |
MIKHAIL | ||
| 5.1.2012, 19:57 |
RegmeEmail API2 | Регистрация через e-mail |
Ameet, находишь в скрипте вот такой код: Код function GetPass() и вместо него копируешь отсюда этот: math.randomseed(os.time()) return tostring(math.random(100, 99999999)) end Код local sPass = "" tAbc = { "0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f", "g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z", } function GetPass() math.randomseed(os.time()) sPass = tAbc[math.random(#tAbc)] -- 1-я буква пароля local iPass = math.random(4, 7) -- длина пароля = [(от 4 до 7) + 1] for i = 1, iPass do sPass = sPass..tAbc[math.random(#tAbc)] end return sPass end Тут в этой строке регулируется и создаётся произвольная длина пароля: Код local iPass = math.random(4, 7) Вместо 4 и 7 можешь писать другие разумные размеры длины пароля. Только нужно учитывать, что 1 символ уже создался в предыдущей строке.PS: Можно было обойтись без предварительной таблицы символов tAbc, но тогда код стал бы громоздче. UPD: Так, наверно, эту переменную - local sPass - надо объявить заранее, до использования в function GetPass(), иначе не уверен, что вытащится по return.. Поэтому в код внёс поправку небольшую. |
Ameet | ||
| 3.1.2012, 5:48 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
1. MIKHAIL, изящность достигается не этим, не твоими "блошиными" исследованиями, ей-богу! Я уже писал тебе выше. Твои скрипты пашут с производительностью в 1 млн вычислений в секунду? Тогда да, твои экзерсисы оправданы. А если ты пишешь то же, что и мы, то забей, займись чем-то более полезным. Просто пиши, как умеешь...остальное придёт с практикой 2. И да, ты выше спрашивал про function, отвечаю - нет разницы. Это вопрос предпочтений. Лично я пишу всегда так: Код function GetData(sData) Цитата [01:40:49] * 10 [01:40:49] * 11 Enyby, а ты проверял только 1 раз? Проверь несколько раз, удивишься. Вот у меня с 4 раз: Тык сюда: Цитата [08:41:58] 6 [08:41:58] 6 [08:42:22] 6 [08:42:22] 6 [08:42:40] 5 [08:42:40] 6 [08:43:08] 6 [08:43:08] 6 Разница чисел у тебя и у меня, думаю, только из-за разных процессоров. И вообще, иногда надо думать и о красоте, особенно когда нет практически разницы между способами в скорости. Разница в микросекунды и наносекунды не считаются. |
Enyby, MIKHAIL | ||
| 1.1.2012, 10:01 |
Kinozal_tv API2 | Скрипт новостей с трекера |
MIKHAIL, эти файлы у тебя могут лежать и в другом месте. Проверь, нет ли у тебя в папке с Птокой где-нибудь ещё одной папки libs.. |
MIKHAIL | ||
| 29.12.2011, 2:42 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
Код Stroka:sub(3,4) - тут от строки Stroka выделяется кусок от 3-го по 4-е число символов.Для изучаемого числа 0.141592654 это будет пропуск первых двух символов "0." и захват цифр "14" из "141592654" Можно брать и отрицательные значения для этих аргументов: Код Stroka:sub(3,-4) - тут у нас захватятся с 3-го по 4-е с конца, то есть, получим число "141592"Знак минус при аргументе означает - с конца строки. |
MIKHAIL | ||
| 29.12.2011, 2:25 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
MIKHAIL, заранее не парься. Пиши скрипт спокойно. Вот когда появятся проблемы, тогда и будем решать. И да, ты смотри моё предыдущее сообщение, я там подправил кое-что. |
MIKHAIL | ||
| 29.12.2011, 0:43 |
Вопросы Разработчикам Скриптов вопросы по скриптам (мелкие вопросы) |
MIKHAIL, а ещё есть это: Код local Pi = 3.141592654 -- твоё обрабатываемое число local sUnit = "" -- единица измерения, в данном случае пусто (а может быть и метр, и процент и что угодно) Core.SendToAll(string.format("%0.2f %s", Pi, sUnit)) -- где 2f - нужное число знаков после запятой, то есть, 2 в данном случае PS: в числе Пи надо было точку вместо запятой. А ещё можно так: Код local Pi = 3.141592654 local M, N = math.modf(Pi) -- получение целой части числа и дробной части Core.SendToAll(M.."."..tostring(N):sub(3,4)) -- получаем 3.14 Это для представления. А для выполнения матем. операций в дальнейшем нужно применить команду Код tonumber(вышеполученное строчное выражение) Например, продолжая предыдущий код (который с выводом числа в чат) - заменяем вывод в чат на эту строку: Код Core.SendToAll(tostring(tonumber(M.."."..tostring(N):sub(3,4))*10)) -- получаем 31.4 Тут происходит вот что - сначала соединяем и получаем в строковом виде 2 части (вторая часть только с двумя значащими цифрами после запятой) числа вновь, превращаем это полученное в числовой вид и умножаем на 10 и выводим результат в чат, превратив снова в строковый вид (чтоб убедиться в правильности метода). |
MIKHAIL | ||
| 27.12.2011, 18:01 |
Public PHP hublist (Хаблист) by Enyby Публичный открытый хаблист на PHP |
Цитата(Mellon) раз вы не тролль то я сделаю предположение что вам до 20. На баш! PS: [To All] И вообще, ребятки, зачем вы мучаете животное? Забейте (забаньте?) его и хватит его бред читать. |
Артём | ||
| 27.12.2011, 17:51 |
Tiny Hublist Программа для создания хаблистов |
Mellon, хосспади, какое-то невнятное бормотание и бред сумасшедшего ты пишешь. Может, просто промолчишь и за умного сойдёшь? Никогда не поверю, что человек, пишущий ТАК, способен написать хоть 10 строк кода без ошибок, неважно на каком языке...если русским-то не владеет и логика дико страдает. |
Артём, PomanoB | ||
| 27.12.2011, 4:37 |
WhoIs Через меню хаба добывает WHOIS-информацию об IP |
UPD: - Перезалил, чуть-чуть изменив одну строчку (причина - маленькое изменение на странице результатов сайта, приведшее к неработе скрипта). Теперь скрипт работает. PS: Сорри, что так долго не исправлял...просто руки не доходили, а реально пришлось вносить всего лишь пустяковое изменение.. |
striker | ||
| 26.12.2011, 16:11 |
Постоянно Зависает Работающая Ptokax 0.4.1.1 An error occured in the application |
Fe(one)X, разбирайся лучше, почему хаб зависает. Просто так ничего не бывает. У всех нормально пашет, и у тебя пахал столько времени, и вдруг стал виснуть....что-то тут не так у тебя. Не факт, что следующая версия не будет зависать. Так что разберись с этим сначала. |
dickTATOR | ||
| 22.12.2011, 3:15 |
Temperature Выводит текущую погоду автом. в чат и по запросу, можно. неск. городов |
UPD: - добавил показ текущей даты/времени местности (правда, на сервере погоды время отстаёт минут аж на 5 - исключил вывод данных при получении ошибки с сайта (чтоб все города не получали одну и ту же погоду) - небольшие косметические малозаметные изменения, улучшающие работу скрипта. Скрипт перезалил в сообщении #1. UPD: - убрал показ даты/времени для вывода в чат местной погоды (зачем местным показывать их время, тем более, не очень точное) Скрипт перезалил в сообщении #1. |
ustas | ||
| 19.12.2011, 12:57 |
Temperature Выводит текущую погоду автом. в чат и по запросу, можно. неск. городов |
UPD: Выявился неучтённый момент - в архивных данных могут оказаться 2 года через запятую с одинаковой температурой Max. или Min., и при попадании такого случая скрипт падает. Что сегодня и случилось с Владивостоком. Хорошо, хоть сам город не пострадал. Код подправил, скрипт перезалил в сообщении #1. UPD-2: Сделал косметическую подправку - восход/заход солнца разделил на 2 строки, а то слишком длинная получалась: Код Солнце: восход: 09:52 заход: 16:42 Скрипт перезалил в сообщении #1. |
striker | ||
| 15.12.2011, 7:24 |
Temperature Выводит текущую погоду автом. в чат и по запросу, можно. неск. городов |
Наконец-то собрался и переделал скрипт. Причина - полное изменение структуры страницы на сайте. Пришлось всё перелопатить. Плюс добавил показ восхода/захода солнца. Дата заливки: 15-12-2011 06:25 (мск.) Качайте из первого сообщения темы. |
rival, Dan Claimant, 10685 | ||
| 8.12.2011, 3:51 |
Несколько Слов О Захватах И Регулярных Выражениях исключительно для разработчиков |
Попробуй внедрить в свой скрипт эту процедуру (названия переменных можешь изменить как тебе понравится): Код t = {} for k, v in sMsg:gmatch("<pubDate>.-</pubDate>") do local s = v:match("<pubDate>(.-)</pubDate>") t[k] = s end При выполнении все строки, содержащее нужную тебе информацию (в данном случае время/дату) сохранятся в таблицу t Потом сможешь вытаскивать их когда и как тебе угодно, например, так: Код local sTime = t[1] дальше это вставляешь в своё выводимое сообщение в нужное место. |
MIKHAIL | ||
| 3.12.2011, 14:12 |
От: Mellon DC Hub List От темы с ID: 5060 |
Как вариант - А.П.Чехов. "Письмо учёному соседу": Цитата ..Вы сочинили и напечатали в своем умном соченении, как сказал мне о. Герасим, что будто бы на самом величайшем светиле, на солнце, есть черные пятнушки. Этого не может быть, потому что этого не может быть никогда. Как Вы могли видеть на солнце пятны, если на солнце нельзя глядеть простыми человеческими глазами, и для чего на нем пятны, если и без них можно обойтиться?.. |
-=ДЕМОН=- | ||
| 3.12.2011, 13:30 |
От: Mellon DC Hub List От темы с ID: 5060 |
Mellon, как тебе удаётся написать такие предложения - в 100 слов? И ещё: Цитата ты об этом мало что знаешь (так как тебя тогда не было) Интересно было бы услышать комментарии оппонента на эту тему. |
-=ДЕМОН=- | ||
| 2.12.2011, 17:42 |
помогите сделать скрипт |
max666: Цитата Да мне трудно потому что я в это не вникал и не собираюсь !!!! В этом вся суть твоя. Потому и не хотят тебе помогать. И вообще, если ты такой пустяк не можешь и даже не хочешь сделать, то нафиг ты хаб завёл, спрашивается?! |
Артём | ||
| 8.11.2011, 17:31 |
Сдвиг таймеров для частного случая Периодическая инициализация действий со сдвигом по времени |
Товарищ один (Akvilon) попросил помощи, и вот кидаю частное решение (хотя расширить никто не мешает). Цель - периодическая инициализация действий со сдвигом по времени (например, 2 сообщения в чат, разнесенных по времени на полчаса, то есть, общий период - 1 час) Код local iTime = 1 -- в данном случае - это 1 час function OnStartup() tmr1 = TmrMan.AddTimer(iTime*3600000) end function OnTimer(tmr) if tmr == tmr1 then Core.SendToAll("Бла-бла-бла!") tmr2 = TmrMan.AddTimer(iTime*30000) elseif tmr == tmr2 then Core.SendToAll("Шурум-бурум-тяп-ляп!") TmrMan.RemoveTimer(tmr2) end end Возможно, решение уже где-то есть, а возможно, ещё кому-то пригодится. |
rival | ||
1 2 3 > »
|
Сейчас: 7.2.2012, 14:21 |