violawww
«Виола»: тег TB
Всё это время я программировал с нейросетями, в основном с использованием самых мощных моделей, которые только доступны, но некоторое время назад решил изменить вектор. Теперь я, напротив, хочу посмотреть, на что способны более простые модели, в частности «Композер» (это дообученная открытая модель «Кими»), который входит в подписку «Курсора».
Для этого я использую свой любимый полигон — браузер «Виола». Я подыскал несколько несложных задач из разряда «найти бы место, а поправить можно за полчаса», то есть такие, где важно понять, где поправить; сама правка сложной не выглядит.
Одна из задач — дописать нестандартный тег TB, который автор так и не завершил. Судя по иллюстрациям в его недописанной книге о браузере, этот тег предназначался для разрыва таблицы: на рисунке он стоит между строкой «HTML Source / Output» и последующими. Вероятнее всего, TB расшифровывается как Table Bar.
Модель «Композер 2.0» справилась с задачей, в принципе, на «отлично» — лучше и желать нельзя. Моментально нашла место и поправила всё как надо с первой попытки.
Интересно, кстати, что иллюстрации в книге не совпадают с реальным поведением браузера. Такое ощущение, что автор браузера их либо дорисовывал потом в редакторе, либо
Чтение образов NeXTSTEP
Если вам (ну вдруг)
Мне пришлось заняться этим вопросом, потому что я надеялся, что внутри одного из найденных образов этой системы меня могут ждать новые открытия, связанные с браузером «Виола».
Пользоваться утилитой не очень удобно, особенно если не вполне ясно что ищешь, но её довольно просто подключить к известному файловому менеджеру mc (Midnight Commander).
Достаточно написать обёртку, которая принимает на вход две команды — list (выдача списка файлов в директории) и copyout (копирование указанного файла в указанный путь), — и всё заработает.
Правда у исходной утилиты в листинге отсутствуют некоторые необходимые поля (в частности — дата), поэтому мне пришлось добавить заглушки на эти позиции. Я уже отправил автору утилиты патч, который устраняет этот недостаток (заодно я пару багов нашёл и исправил).
К сожалению, ничего полезного внутри образа я не нашёл, но опыт интересный.
«Виола»: нейросеть «Опус 4.6»
Недавно компания «Антропик» выпустила новую нейросеть для программирования — «Опус 4.6». Я с большим интересом слежу за тем, что они выпускают, потому что, по моему опыту, их сетки программируют лучше любых других.
У меня в загашнике есть несколько сложных задач и с каждым обновлением программирующих нейросетей этот список потихоньку убывает — те задачи, которые ещё недавно были им не по зубам, постепенно поддаются.
«Опус 4.6» я тестировал на задаче реализации типа нумерации для списков в «Виоле» — в найденных мной материалах упоминается, что такая возможность должна быть, но она так и осталась нереализованной.
До выхода «Опуса 4.6» нейросети с этой задачей не справлялись — либо ломали код, либо делали довольно кривую реализацию. «4.6» с задачей справилась. Рабочую реализацию она написала примерно с третьего раза, но я считаю, что это очень хороший результат, учитывая скорость её работы. Правда было два неприятных момента.
С этим багом мы боролись очень долго. Конечно, это ожидаемо — «Курсор», — среда разработки, которую я использую,
«Виола»: формулы и стилизация
Долго же я прикидывал правда ли автор «Виолы» задумывал, чтобы математические формулы у него выводились на красном фоне. С одной стороны в коде именно так, да и мне это кажется даже
Действительно, есть ли в этом смысл? Почему именно формулы на странице должны быть
На скриншоте красного фона нет. Видимо
В общем, от красного фона я избавился и сделал возможность стилизовать формулы в соответствие с закомментированным кодом, который автор не дописал — у формул должна была появиться возможность устанавливать цвет фона, шрифта и бордюра. Всё это заработал в последнем коммите.
Вот, кстати, как выглядело недописанное место, где можно подсмотреть что планировалось сделать:
tagPtr = STG_tagPtr("MATH");
i = STG_attr(tagPtr, "BGColor");
if (i) set("BGColor", i);
i = STG_attr(tagPtr, "FGColor");
if (i) set("FGColor", i);
i = STG_attr(tagPtr, "BDColor");
if (i) set("BDColor", i);А то некоторые читатели недоумевают, наверное, откуда я вообще знаю что задумывал автор.
Этот кусочек выше был закомментирован и не дописан, зато из него видно, что автор собирался стилизовать задний фон (BGColor), цвет шрифта (FGColor) и цвет бордюра (BDColor).
Нередко такие места содержат в себе достаточно понятные намёки на то как это было задумано, в других же случаях помогают комментарии, главы из недописанной книги автора или его редкие письма в различные группы рассылок, куда он редкий раз писал свои мысли в самом начале
«Виола» и безопасность
Когда я только начинал заниматься восстановлением браузера «Виола», меня поразило как много он себе позволяет делать в системе. Если бы браузер с такими возможностями и с полным отсутствием защиты от несанкционированного их применения дожил до конца девяностых, хакеры бы от его репутации камня на камне не оставили.
Конечно,
At this point you’re probably thinking how great this this, but how do I know that the applets I run won’t delete my files, smuggle info out of my system, and do other mischiffs?
The answer is that these imported objects can’t (or shouldn’t be able to).
The current security policy is pretty straightforward and somewhat limiting for the objects. It basically goes this way: all imported objects are marked as untrusted, and as such these imported objects have no system priviledges, have no access to sub interpreters, and can not coarse other objects to execute scripts arbitrarily.
Видимо эта работа так и не была завершена, но, что радует, была начата. Я изучил всё то, что автор писал по этому поводу у себя на сайте, в группах рассылок и коде браузера и тщательно описал что именно было сделано. Потом я определил, что нужно доделать в коде, чтобы обеспечить минимальную защиту компьютера пользователя от вредоносных сайтов, и приступил к работе.
Конечная реализация вышла довольно прямолинейной. Браузер может работать в одном из двух режимов: защищённом и нет. Когда браузер переходит
В популярном приложении одно э́то было бы проблемой, но я не вижу смысла спрашивать разрешение и для локальных страниц, так как это осложнит мне тестирование браузера. Так что я себе проделал небольшую брешь в защите.
Из защищённого режима браузер переключается в режим без защиты только с разрешения пользователя, переключение инициируется, если во время интерпретации скрипта встречается вызов, требующий переключения в доверенный режим (например, работа с файловой системой или открытие сокета), а так же, если на странице установлен тег SECURITY с атрибутом LEVEL=0.
Оказывается, автор браузера предосмотрел такой тег, но не успел реализовать. Название атрибута в коде уже было, а вот его значение — это моё обоснованное предположение. В коде есть центральный флаг securityMode, принимающий два значения — 0 (система безопасности отключена) и 1. Я предположил, что атрибут LEVEL должен влиять на значение этой переменной.
Если пользователь не согласился на переход в доверенный режим, вызов, запросивший повышение привилегий, завершается с нефатальной ошибкой — там, где можно вернуть флаг того, что произошла ошибка, я это делаю. Как только браузер встретит следующий такой вызов, он опять попросит разрешения сменить режим. Тут, опять же, слабое место, — можно заспамить пользователя такими запросами. Собственно, эта проблема была в любом браузере девяностых годов.
Решается она просто. Например, можно добавить в диалог галочку «больше не спрашивать» и не позволять его вызывать до перехода на другую страницу, но это настолько не в духе браузеров тех годов, что я тоже не стал этого делать.
Если мы перешли в доверенный режим, то он сбросится на следующей же странице, загруженной из интернета.
Я потратил так много усилий и токенов нейросетей, чтобы сначала понять замысел автора, потом придумать в её рамках реализацию, закрывающую все белые пятна, а потом реализовать, что немного выдохся и пока больше таких больших доработок не делал, да и токены надо бы поэкономить. Поэтому пока что я доделываю всякие мелочи и дописываю документацию.
Но не будь нейросетей… Я уже не раз повторял это в частных разговорах, но, кажется, ни разу не писал у себя в блоге: без нейросетей я бы этим заниматься не стал. Усилие от реализации этих доработок без нейросетей во много раз перекрывает удовольствие от этой работы.
«Виола»: тег CHANGED
Если верить «Википедии», веб появился в 1989 году. Его ранний период очень плохо сохранился, даже проект
В «Виоле» я часто нахожу начатые и неоконченные части реализации
Так случилось и с тегом CHANGED. Я давно заметил его в коде, но не понимал как он должен работать. По коду про него было известно, что он должен был выделять часть текста оттенком жёлтого (точнее — цветом LemonChiffon1), имел два атрибута ID и IDREF и при этом был не блочным.
Конечно, мне было непонятно что у него за атрибуты, но последнее всё ещё сильнее усложняло. Когда я начал читать код, то подумал, что это
Тогда я решил, что это просто ошибка в коде и реализовал тег так как я его понимаю. Но было непонятно что делать с атрибутами, особенно с IDREF. По имени понятно, что это
Я записал себе в список дел
В архивах начала
Ни одна ссылка не работала, зато по имени htmlplus.dtd нашлось несколько уцелевших спецификаций, где, как я и надеялся, упоминался искомый тег с небольшим описанием:
<!-- change bars defined by a matched pair of CHANGED elements:
<changed id=z34> changed text <changed idref=z34>
This tag can't act as a container, since changes don't respect
the nesting implied by paragraphs, headers, lists etc.
-->
<!ELEMENT CHANGED - O EMPTY>
<!ATTLIST CHANGED -- one of id and idref is always required --
id ID #IMPLIED -- signals start of changes --
idref IDREF #IMPLIED -- signals end of changes -->Собственно, из этого кусочка всё стало ясно. Тег задуман таким образом, чтобы как бы «выпадать» из обычной логики вложенности тегов — так как выделение текста может пересекать границы других тегов.
Вместо открывающего и закрывающих тегов тут применяется тег с атрибутом ID для обозначения начала участка и тег с тем же значением в атрибуте IDREF для определения места, где участок заканчивается.
Этот тег не дожил до нашего времени, потому что его было предложено заменить на два других — ADDED и REMOVED, которые позже превратились в более привычные нам INS и DEL.
Несмотря на то, что найденная спецификация оказалась сложнее первоначальной моей реализации, в этот раз получилось всё запрограммировать даже быстрее, видимо при частом программировании с нейросетями нарабатываются
Один из таких способов, кстати, — банальное документирование. В процессе реставрации «Виолы», у меня набралось довольно много документации, благо при помощи нейросети это делать очень просто — даёшь команду что ещё учесть и она сама вписывает новые знания в подходящее место.
«Виола»: растягивание окна
В последнее время мало что дорабатываю в «Виоле», чаще борюсь с багами, а их там предостаточно. Сегодня ночью пал один из самых сложных в исправлении.
Дело в том, что у меня окно «Виолы» нормально не тянулось — если попробовать изменить размеры, то в окне появлялись чёрные полосы, положение элементов плыло, в общем пользоваться этим было невозможно. Я, понадеявшись на то, что оригинальная «Виола» просто не умела растягиваться, заблокировал во всех окнах такую возможность.
Но позже в видеоролике, где видно оригинальную «Виолу», запущенную в виртуальной машине, я увидел, что она прекрасно растягивается безо всяких проблем.
Видимо проблема
К проблеме растягивания я уже пытался подступиться, но, потратив несколько часов, отступил. На этот раз я попробовал новый подход. В прошлый раз нейросети пробовали
Я сообразил, что проект, видимо, просто слишком огромный. У нейросети «глаза разбегаются» в попытке сгенерировать фиксы, так как дело может оказаться в чём угодно.
Поэтому я попросил нейросеть сгенерировать небольшое приложение, которое компактно повторило бы проблему, чтобы там её править. Удивительно, но мой любимый «Опус 4.5» с задачей не справился — он слепил
Выручил
К тому времени, когда всё заработало, в коде было полно
Судя по логам, работу я закончил в третьем часу ночи.
«Виола»: тянущееся окно
Отложил пока в сторону свой проект до дописыванию браузера «Виола», поскольку исчерпал все токены на своём тарифе в «Курсоре». Там, конечно, остались бесплатные модели («Грок», например), но они годятся только
Зато случилось интересное — поиск в интернете принёс видео «Viola www y Erwise dos de los navegadores web pioneros», где
В моём проекте с этим сложности — при изменении размеров окна, всё очень некрасиво едет и красится чёрным, видимо
Раз это не так, то после перерыва надо будет вернуться к этой задаче. Попытаюсь решить её с «Опусом 4.5», пока это умнейшая сеть для программирования.
«Виола»: протокол NNTP
Из всей той экзотики раннего интернета, которую сейчас уже прочно забыло большинство, — IRC, Gopher, Finger, WAIS и прочего — я больше всего пользовался сетью «Юзнет», работавшей по протоколу NNTP. Это был аналог электронной почты, только сообщения доходили сразу до всех участников выбранной «группы» —
Для тех скоростей, которые тогда были доступны, это был удобный инструмент. Я состоял в нескольких группах; сейчас уже не вспомню каких, но отлично помню наши бесконечные баталии в одной из локальных групп моей
В общем,
Почитать группу теперь можно и через «Виолу», запустив её следующим образом:
NNTPSERVER=news.neodome.net ./src/vw/vw news:comp.sys.mac.miscУказывать сервер таким образом не слишком удобно, но в те годы, видимо, способа лучше ещё не придумали. Позже придумали схему урлов, где можно указать сервер и,
Учитывая, сколько мне пришлось исправить багов за это время, я думаю — не в их ли количестве была причина того, что «Виола» проиграла своим конкурентам? Возможно автор, учитывая заложенные, но не реализованные тут возможности, просто не имел сил заниматься всем — и править баги, и дописывать всё что нужно?
«Виола»: предок VRML ★
Недавно завершил в «Виоле» большую работу: реализацию раннего черновика стандарта VRML. VRML
Началось всё с того, что я заметил в браузере едва начатую реализацию тегов, помеченную комментариями как /* vr exp */. В исходном коде нашлась целая группа таких тегов. Назначение некоторых из них, например OVAL или LINE, было вполне очевидным, тогда как то, что в точности могли бы делать некоторые другие теги, например ACTION или BUTTON, было не вполне ясно.
Можно было бы реализовать только понятные части, но я тогда просто отложил эту задачу в сторону, тем более что она казалась пугающе сложной.
Шло время, и вдруг, копаясь в каталогах старого сайта, посвящённого «Виоле», я неожиданно нашёл черновик письма, в котором автор «Виолы» описывал своё видение того, как должен выглядеть VRML.
Там раскрывалось значение всех ключевых тегов из вышеуказанной группы, их атрибутов, а также интерактивная часть — причём в двух вариантах: декларативном (через теги) и скриптовом (через язык «Виолы»).
Вкратце суть такова: теги описывают графические примитивы и их вид на странице. С некоторыми из них через активные элементы можно взаимодействовать, меняя их атрибуты.
Вот, например, как на этом языке рисуется синий квадрат
<GRAPHICS WIDTH=400 HEIGHT=120>
<BGCOLOR NAME="lightgray"></BGCOLOR>
<RECT ID="rect1">
<POS X=10 Y=20></POS>
<SIZE X=70 Y=70></SIZE>
<FGCOLOR NAME="blue"></FGCOLOR>
<BDCOLOR NAME="navy"></BDCOLOR>
<ROT Z=45>
</RECT>Особенно меня
The SC attribute says that whenever the attributes in this object changes, relay the change to a server that broadcasts the change to all other browsers looking at this object… Have to think about this more…
Я сразу понял как хотел бы чтобы он работал: если на странице есть такой атрибут, считаем хеш урла, где находится сейчас наш браузер и, при любых изменениях тегов, связанных с этим атрибутом, рассылаем по локальной сети сообщение с закодированной командой. Одновременно мы слушаем сеть, принимаем команды, отфильтровываем те, в которых содержится хеш текущей страницы и только их и исполняем.
В итоге эту часть я сначала пытался сделать через маковский сервис «Бонжур», но позже переделал на мультикастовый UDP — так работало гораздо быстрее и надёжнее.
Поскольку я тестировал у себя на ноутбуке, запуская два экземпляра браузера, столкнулся и с другой проблемой — стоило убрать курсор с одного из окон, и оно переставало перерисовываться. Оказалось, это особенность оконного фреймворка, на котором построено приложение: так сделано для экономии процессорного времени.
Пришлось делать специальный таймер, который будит приложение, если ему адресованы интерактивные UDP-пакеты.
Работу я разбил на три части: реализацию графических примитивов, реализацию интерактивного взаимодействия и сетевое взаимодействие.
На всё ушло несколько дней интенсивной работы с нейросетью «Опус 4.5». Пришлось даже немного переделать парсер тегов внутри браузера. Несмотря на то, что работа двигалась трудно, отчаяния я не испытывал — было видно, что при работе в паре с «Опусом» эта задача вполне мне по силам.
На настоящий момент всё работает, так, на мой взгляд, как и задумывалось, за исключением декларативной части предлагаемого черновика.
Инсталлятор «Виолы»
Вчера я хотел
Так как с собой пришлось тащить ещё и «Кварц» (XQuartz), то лучшим выбором был dmg — файл с монтируемой файловой системой. Хорош он тем, что просто делается и легко стилизуется. Я, например, сделал внутри обои, вдохновлённые внешним видом браузера и поместил портрет автора с его старой домашней странички.
Для сборки сделал две новые цели — make app для сборки самого приложения и make dmg для сборки инсталлятора.
Больше всего, конечно, пришлось помучаться с приложением — чтобы пользователь потом не ставил сторонний софт, я перенёс все бинарные зависимости внутрь, переписав пути. Вообще, весь инструментарий для этого уже существует, но в случае утилиты magick из пакета ImageMagick пришлось делать отдельную компиляцию, чтобы сделать бинарник перемещаемым.
Нейросеть, которая мне это всё готовила, в этом месте зациклилась, пытаясь разобраться как готовый бинарник унести внутрь так, чтобы он заработал, хорошо что я быстро увидел, а то бы мне это обошлось в копеечку.
Добавлено позднее: код собран по процессоры АРМ и под «МакОС» 26.
«Виола» или «ВиолаВеВеВе»?
Как вы уже заметили, я упоролся по браузеру «Виола» и, похоже, перемкнуло меня надолго. Тем лучше! Давно у меня не было хобби
Вопрос, который меня интересовал — правильно ли я вообще называю эту программу? Для меня это важно.
Дело в том, что «Виола» — это язык программирования, а не сам браузер. Например, вся обработка тегов внутри написана на этом языке. Его название расшифровывается как «Visually Interactive
Браузер же правильно называется «ViolaWWW». Но называть его так очень неудобно, на редкость неуклюжее название, поэтому я почти всегда называю его «Виола». И мне подумалось, что неплохо бы выяснить как его называли в прессе во времена, когда он ещё не стал частью истории.
В общем, не мне одному было жалко ломать язык — например, в журнале «Internet World Magazine» за апрель 1995 года он тоже называется «Виола», значит всё в порядке.
«Виола» и самолёты: коррективы
Надо бы мне ещё вернуться к теме отображения «Виолой» самолётов. Пока я поправил только масштаб — заметил, что на старых скриншотах, снятых автором этого браузера
Но всплыла и ещё одна проблема — иногда «крутилки» как будто меняют ось, вокруг которой они крутят объект, при этом в терминале я вижу многочисленные ошибки следующего вида:
violaIdleEvent(): select() error: : Bad file descriptorКак будто браузер теряет соединение со своим бэкендом для отрисовки моделей и вращение рассинхронизируется. Как только научусь стабильно повторять эту проблему, попробую поправить.
«Виола» и моя мечта: как ИИ снова мне помог ★
Вступление
Я, как вы знаете, довольно давно уже реставрирую браузер «Виола» из недописанных исходников. И была у одна мечта, связанная с ним: увидеть как в нём работает вращение трёхмерной модели самолёта.
Узнал я об этом из статей о судебной тяжбе компаний «Микрософт» и «Иолас» (Eolas), начавшейся
Компания «Иолас» утверждала, что первой разработала и внедрила технологию «встроенных объектов и плагинов»
Тема широко освещалась в прессе и в некоторых из статей есть статичный скриншот того как это выглядело. Кроме того, сохранился код страницы с программой на языке «Виола». Казалось бы — почти всё что нужно!
Что мешало
Но оказалось, что исполнению моей мечты мешало несколько обстоятельств.
Вопрос №1: где взять V-Plot ?
По всей видимости, в открытых источниках его не найти — сколько не запускал я невод глубокого поиска нейросетями, ничего не вышло. Тогда я решил пойти от обратного — у нас есть скрипт на «Виоле», который должен слать этой программе
Без особой надежды я дал нейросети такое задание и пошёл заниматься делами. Через
Оказалось, что специальный «объект» TTY «Виолы» для взаимодействия с программами, которые могут выводить графику в окно браузера, реализован только для «Линукса», а для «МакОСи» (в «Виоле» встречаются куски для очень старой версии этой операционной системы) код реализован не был.
Я как можно тщательнее, как зловредному джину, описал что именно хочу получить и опять переключился на свои дела. И вот тут, когда я без особой надежды вернулся через
Здо́рово! Но где же мои самолётики?
Настал момент узнать откуда же брались самолёты. Оказалось, что «Виола» передаёт на вход
Ориентируясь на приметное имя x29.geom, я решил поискать эту модель, вдруг это
Модель действительно оказалось известной — её
ChatGPT оказался полезен тем, что правильно идентифицировал модель и рассказал её историю, но сам файл нашёлся банальным поиском по интернету.
Дальше нейросети меня опять удивили — посмотрев на мой найденный файл, сеть для программирования «Опус 4.5», не моргнув глазом, написала мне
Отлично! А что со второй моделью?
Со второй моделью так гладко не вышло — как я ни старался, ничего путного по слову TomCat на нашёл. Решил смириться и найти хоть
Тут наконец пригодился глубокий поиск — нашёлся архив внутри которого лежала модель самолёта
Я, было загрустил, но тут решил попробовать уже совсем безумную штуку — натурально попросить нейросеть написать мне конвертор из формата IOB в OFF, причём без описания самих форматов. Самое смешное, что это сработало, причём с первого раза! Получившаяся модель сразу появилась в окне и заработала!
Выводы, или Что меня удивило
Лёгкость к которой нейросеть провела обратную разработку команд, написала интерпретатор команд для
Конечно, у меня осталось ещё много задач даже в этом проекте, которые нейросети либо не могут решить самостоятельно, либо даже с моей помощью.
Тем не менее, та работа, которую я проделал над браузером при помощи нейросетей, совершенно неподъёмна для человека в такие короткие сроки.
Звуки в «Виоле»
Как я уже писал, анимацию в «Виоле» можно получить, задействовав скриптовый язык, а что же со звуком?
Из скриптового языка доступны только две функции — bell() издаёт системный «бип» и bellVolume(), позволяющая задавать или получать громкость этого «бипа» в процентах. Функций немного, но и их пришлось чинить — они обе используют вызов XBell(), который на «МакОСи» не работает испокон веков.
Пришлось примотать небольшой код на
Что касается HTML, отдельного тега нет, но небольшими ухищрениями можно заставить проиграть браузер любой файл, имя которого кончается на .au — этот файл передаётся маковской утилите afplay, а она умеет играть файл в целой куче аудиоформатов.
Каноничнее, конечно, использовать именно формат au, тем более, что в него аудио можно преобразовать большинством современных утилит, той же ffmpeg, например.
Так как же проиграть звук из HTML?
Самый простой способ — поставить на аудиофайл ссылку. При переходе на неё файл проигрывается, а не скачивается. Способ позанятнее — использование тега INSERT, аналога современного IFRAME. Он проиграет файл при открытии страницы, а если использовать атрибут AFTER, то ещё и зациклит его с указанной в миллисекундах задержкой.
Так как звук играется асинхронно, в теории, можно было писать игры или делать сайты с фоновой музыкой, для этого уже всё было готово. А если учесть, что скриптовый язык позволяет запускать что угодно (с безопасностью у этого браузера явные проблемы), то можно, запуская ту же утилиту afplay, организовать звуковые эффекты.
«Виола» и организация закладок
«Виола», конечно, глубже любой кроличьей норы — со временем всё больше и больше похороненных идей удаётся находить в её внутренностях. Вчера ночью, просматривая код незавершённых и закомментированных пунктов меню, я заметил интересное место — недописанный интерфейс каталога закладок.
Степень готовности там оказалась очень высокой, поэтому я решил оживить этот фрагмент. В «Виоле» уже есть его конкурент — «Hot List», позволяющий хранить закладки плоским списком. Но «Hot List» куда проще и примитивнее. В отличие от него, каталог позволяет создавать папки и перетаскивать закладки, визуально организуя их так, как больше нравится пользователю.
Несмотря на то, что кажется логичным перетаскивать закладку в папку, чтобы туда её перенести, такого автор, к сожалению, не задумывал — в комментариях к незавершённым кускам достаточно подробно описана логика перетаскивания. Чтобы не нарушать аутентичность, я тоже это не реализовывал.
Я вообще стараюсь придерживаться авторского замысла, но есть тут два места, где мне пришлось придумывать
Внешний вид браузера «Виола»
Если вы приглядывались к браузеру «Виола» на моих многочисленных скриншотах, могли заметить, что он выглядит
На деле всё обстояло даже хуже — в нулевом состоянии в этих местах были прописаны заглушки, по которым сразу становилось понятно, что это не интерфейс, а нечто временное.
Мне от этого делалось грустно — я люблю красивый дизайн, а тут такое уродство. Но оказалось, что внутри кода браузера есть закомментированные недописанные куски, в которых можно подглядеть, как на самом деле должен был выглядеть браузер!
Мы с нейросетью посмотрели на этот код, отряхнули его, дописали и выкинули оттуда очевидно лишние вещи (внизу были невзрачные кнопки, дублирующие меню, думаю, это остатки технического интерфейса). Теперь в свежей сборке можно увидеть, каким именно браузер должен был получиться.
Кстати, пока мы с нейросетью занимались интерфейсом, я решил заняться некрасивым уголком справа внизу. Снял скриншот, чтобы меньше объяснять — многие нейросети довольно неплохо по ним всё понимают и написал в промпте:
Посмотри на out.png, справа внизу светлый угол, за который тянуть надо, не совпадающий по цвету с остальным окном. надо бы поправить цвет, сделать в цвет остального окна.
Вот иллюстрация того как это ещё недавно выглядело:
Нейронка, так сказать «взяла под козырек» и начала
Оказалось, она написала мне программу, которая покрасила краешек моего скриншота в правильный цвет!
В итоге я вообще убрал этот уголок: масштабирование всё равно нормально не работает, остаются артефакты, да и в оригинальной программе окно было фиксированного размера.
«Виола»: ИИ и отображение PostScript
Когда я в очередной раз думаю, что понял какие задачи может, а какие не может решить нейросеть быстро и с минимальным моим участием, нейросети подкладывают мне свинью.
Случайно, изучая заголовки, которые отправляет «Виола», я обнаружил, что этот браузер
Непонятно для этого понадобился отдельный тег, ну вот так сделано. Для наглядности вот пример его использования:
<FIGURE TYPE="application/postscript" SRC="test_figure_ps.ps"
WIDTH="100" HEIGHT="100" MAYDELAY="2000" ISMAP></FIGURE>У него больше атрибутов, чем я использовал в примере, в минимуме ему нужен только TYPE и SRC, а остальные атрибуты у меня тут используются как ненужные подробности в моём рассказе, но так уж мне захотелось.
Когда я сделал тестовую страничку с этим тегом, оказалось, что ISMAP и MAYDELAY с «ПостСкриптом» не работали, как и, собственно, само отображение «ПостСкрипта».
С отображением я справился быстро. Секрет в том, что «Виола» на самом деле этот язык сама по себе не понимала, до моего вмешательства она использовала довольно неряшливый код, который использовал кучу временных файлов и две утилиты, — gs и ppmtogif, при помощи которых она получала GIF, который на самом деле и отображался.
Я весь этот код просто выкинул и заменил на вызов утилиты magick, которая умеет конвертировать «ПостСкрипт» в GIF напрямую безо всяких посредников. Пришлось только учесть, что
Довольно быстро я починил и реализацию атрибута ISMAP — просто скопировал его из обработчика формата XBM, где он работал, а починку MAYDELAY отдал нейросети.
Вроде ничего сложного, опять же — этот атрибут работал у XBM, я предполагал, что сеть быстро разберётся в чём там дело, передрав рабочий код и наложив его на особенность — XBM отображается напрямую внутренней библиотекой браузера, а «ПостСкрипт» конвертируется.
Примерно спустя час я сдался. Ни ChatGPT 5.1 Codex, ни Gemini 3 Pro, ни моя любимая Sonnet 4.5 с задачей не справились — каждая из них писала мне огромную простыню кода, которая задачу не решала.
Кусок кода, который надо было поправить, выглядел следующим образом. Если атрибут MAYDELAY не указывался, то вызывалась конвертация «ПостСкрипта» в GIF и он показывался, в противном случае запускался таймер, который вызывал loadData — другой… э… метод, назовём это так, программы на внутреннем языке «Виолы», в котором конвертации не было.
Модели это видели и просто копировали конвертацию в этот метод, но к моменту срабатывания таймера файл, с которым нужно было работать, уже пропадал. Думаю, его удалял сборщик временных файлов, встроенный в «Виолу». В итоге ничего толком не работало: модели ходили по кругу и, пытаясь исправить ситуацию, писали всё больше кода.
Исправление, которое сделал я, работает очень просто: я сначала делаю конвертацию, потом смотрю, есть ли параметр MAYDELAY, если нет, отдаю сконвертированную в GIF картинку в отрисовку, если есть, откладываю отрисовку, передавая в метод loadData уже сконвертированную картинку.
По сути, я передвинул несколько строк кода чуть ниже, это всё моё исправление. Я
«Виола», математика и скобки
Два дня занимался математическим модулем в «Виоле».
Поручил нейросети посмотреть, есть ли
С наскоку задачу решить не удалось — она оказалась сложной. Сначала мы сделали отдельные теги для разных видов скобок, дописали обработку и поправили все баги, а на следующий день убрали теги и научили парсер генерировать нужные токены на скобки.
Звучит, вроде, несложно, но на деле коммит оказался очень объёмным. Зато сейчас всё работает очень хорошо.
Ещё в комментариях к коду есть указание на то, что ширина скобки должна, по задумке автора, меняться динамически в зависимости от её высоты. Но я попробовал — смотрится плохо, фиксированная выглядит намного лучше, поэтому реализовывать это не стал.
«Виола»: математический модуль
Наверное, можно подумать, что я забросил заниматься браузером «Виола» — первым графическим браузером с потрясающими для своего времени возможностями. На самом деле — ничего подобного: почти каждый день, с редкими пропусками, я
Тот исходный код, который мне достался, был в статусе беты, но даже для беты тут очень много вполне очевидных багов, которые нужно исправить. А ещё — много впечатляющих вещей, которые автор, по всей видимости, не успел доделать. Часть из них я нашёл чисто случайно, как, например, модуль для отображения математических формул.
Нашёлся он совершенно случайно, когда я чинил баг с отображением символьных сущностей HTML — плёвая ошибка: дело было в том, что char у меня в компиляторе — тип со знаком, а в компиляторе автора, видимо, был без него.
В общем, обнаружив модуль для отображения математических функций, я занялся им. Основное поправил,
Вот как выглядят формулы:
<math>&integral;<sup>∞</sup><sub>0</sub> e<sup>-x</sup> = <box>σ<over>2</box></math>Это третья формула на моём скриншоте, можно посмотреть чему соответствуют отдельные элементы. Как можно убедиться, реализованное в «Виоле» почти в точности совпадает со стандартом HTML Math, разрабатываемым
Синтаксис довольно простой, но, в принципе, несложные формулы записать можно. Вся математика отображается красным, я думал это