программирование

«Виола»: протокол NNTP

Из всей той экзотики раннего интернета, которую сейчас уже прочно забыло большинство, — IRC, Gopher, Finger, WAIS и прочего — я больше всего пользовался сетью «Юзнет», работавшей по протоколу NNTP. Это был аналог электронной почты, только сообщения доходили сразу до всех участников выбранной «группы» — что-то вроде общего почтового ящика.

Для тех скоростей, которые тогда были доступны, это был удобный инструмент. Я состоял в нескольких группах; сейчас уже не вспомню каких, но отлично помню наши бесконечные баталии в одной из локальных групп моей альма-матер, где мы спорили с оппонентом о том, что же такое бесконечность — число или понятие. Точку в споре поставил мой научный руководитель, Александр Михайлович Елизаров, заметив, что ответ зависит от того, какой раздел математики мы имеем в виду.

В общем, в 2025-м году, как ни удивительно, этот протокол ещё жив, что я с удивлением обнаружил, начав чинить его поддержку в «Виоле». На скриншоте, например, довольно свежее сообщение в группе comp.sys.mac.misc cервера news.neodome.net.

Почитать группу теперь можно и через «Виолу», запустив её следующим образом:

NNTPSERVER=news.neodome.net ./src/vw/vw news:comp.sys.mac.misc

Указывать сервер таким образом не слишком удобно, но в те годы, видимо, способа лучше ещё не придумали. Позже придумали схему урлов, где можно указать сервер и, по-хорошему, следовало бы её реализовать. Займусь этим в ближайшее время.

Учитывая, сколько мне пришлось исправить багов за это время, я думаю — не в их ли количестве была причина того, что «Виола» проиграла своим конкурентам? Возможно автор, учитывая заложенные, но не реализованные тут возможности, просто не имел сил заниматься всем — и править баги, и дописывать всё что нужно?

Скриншот письма в Viola WWW: тема «Re: [RUMOUR] R.I.P. Mac Pro ??», отправитель Jörg Lorenz, дата 19 ноя 2025, обсуждение неактуальности Mac Pro в эпоху Apple Silicon.

2 комментария

«Виола»: предок VRML ★

Недавно завершил в «Виоле» большую работу: реализацию раннего черновика стандарта VRML. VRML когда-то широко использовался в вебе для создания трёхмерных игр, да и просто для того, чтобы рассматривать с разных сторон какие-либо объекты в объёме.

Началось всё с того, что я заметил в браузере едва начатую реализацию тегов, помеченную комментариями как /* vr exp */. В исходном коде нашлась целая группа таких тегов. Назначение некоторых из них, например OVAL или LINE, было вполне очевидным, тогда как то, что в точности могли бы делать некоторые другие теги, например ACTION или BUTTON, было не вполне ясно.

Можно было бы реализовать только понятные части, но я тогда просто отложил эту задачу в сторону, тем более что она казалась пугающе сложной.

Шло время, и вдруг, копаясь в каталогах старого сайта, посвящённого «Виоле», я неожиданно нашёл черновик письма, в котором автор «Виолы» описывал своё видение того, как должен выглядеть VRML.

Скриншот веб-страницы «Proto-VRML Graphics Demo» с примерами: жёлтые фигуры на розовом фоне, треугольник и пятиугольник, простая красная домик с солнцем.
Готовая реализация графики, которая сейчас работает в браузере

Там раскрывалось значение всех ключевых тегов из вышеуказанной группы, их атрибутов, а также интерактивная часть — причём в двух вариантах: декларативном (через теги) и скриптовом (через язык «Виолы»).

Вкратце суть такова: теги описывают графические примитивы и их вид на странице. С некоторыми из них через активные элементы можно взаимодействовать, меняя их атрибуты.

Вот, например, как на этом языке рисуется синий квадрат с тёмно-синим бордюром на светло-сером фоне в координатах x=10, y=20, повёрнутый на 45°:

<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>

Особенно меня почему-то зацепил атрибут SC о роли которого я бы никогда самостоятельно не догадался. Автор описывал его так:

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 — так работало гораздо быстрее и надёжнее.

Скриншот веб-страницы «ACTION Script Demo - Clickable Shapes» с цветными геометрическими фигурами и описанием их интерактивных свойств (вращение, масштабирование, смена цвета).
Активные объекты, содержащие атрибут SC рассылают свои изменения по локальной сети

Поскольку я тестировал у себя на ноутбуке, запуская два экземпляра браузера, столкнулся и с другой проблемой — стоило убрать курсор с одного из окон, и оно переставало перерисовываться. Оказалось, это особенность оконного фреймворка, на котором построено приложение: так сделано для экономии процессорного времени.

Пришлось делать специальный таймер, который будит приложение, если ему адресованы интерактивные UDP-пакеты.

Работу я разбил на три части: реализацию графических примитивов, реализацию интерактивного взаимодействия и сетевое взаимодействие.

На всё ушло несколько дней интенсивной работы с нейросетью «Опус 4.5». Пришлось даже немного переделать парсер тегов внутри браузера. Несмотря на то, что работа двигалась трудно, отчаяния я не испытывал — было видно, что при работе в паре с «Опусом» эта задача вполне мне по силам.

На настоящий момент всё работает, так, на мой взгляд, как и задумывалось, за исключением декларативной части предлагаемого черновика.

Во-первых, она, при наличии скриптового языка, избыточна, во-вторых, в коде браузера видно, что автор её реализовывать и не собирался.

Скриншот окна браузера ViolaWWW с заголовком «Geometric Art - ViolaWWW Graphics Demo» и геометрической композицией из разноцветных фигур на сером фоне.
Пример с узорами, нарисованный при помощи реализованных графических примитивов

2 комментария

Обратная разработка GIFLITE.EXE ★

Вчера мучился бессонницей, нужно было чем-то себя занять. Обычно я в таких случаях занимаюсь «Виолой», а тут, видимо, на меня повлияло близкое знакомство с JOPA — компилятором Джавы, решил направить свои силы куда-нибудь ещё.

Когда-то давно, когда я активно верстал, формат GIF был одним из самых ходовых, для анимации так вообще альтернатив не было. И мы в то время в обязательном порядке занимались оптимизацией графики.

В случае GIF очень хорошо помогала известная утилита GIFLITE.EXE — коммерческая разработка компании «Вайт Ривер Софтвейр» (White River Software), которая, по всей видимости, давно исчезла, так как я про неё ни в какой другой связи никогда ничего не слышал.

Утилита была под DOS, но я тогда работал под «Виндой» и проблем это не создавало, но позже, когда я пересел на «Мак», пользоваться ей стало неудобно. Тем не менее я всё равно ей ещё долго пользовался через всякие эмуляторы.

Скриншот терминала: слева — справка по команде giflite (сжатие GIF), справа — результаты теста пиксельного сравнения 925 файлов (923 прошли, 2 пропущены из-за ошибок сжатия).

Она всегда меня интриговала — было интересно что она вообще такое делает, как ей удаётся уменьшить размер гифа и чем отличаются её методы сжатия, которые задаются ключом -m.

В общем, раз уж не спалось, я провёл давно запланированный эксперимент, к которому всё никак не мог найти времени приступить — имея на руках только бинарный файл старой программы, воссоздать её на другой платформе. Довольно актуальная задача, кстати, я знаю, что у некоторых людей есть программы без исходного кода, которые они вынуждены запускать на давно устаревших компьютерах.

Забегая вперёд, хочу сказать, что эксперимент удался — программа создаёт в точности такие же GIF-файлы во всех режимах и я, кстати, получил ответ на свой вопрос — бо́льшая часть методов в ней объединяет близкие цвета, уменьшая файл за счёт этого.

А теперь, немного подробностей.

Во-первых, я использовал несколько сетей вперемешку и они показали себя очень по-разному, за ночь они у меня каким-то образом очеловечились и в голове создался образ каждой из них.

Opus 4.5 показался смелым исследователем, который идёт к цели, не пасует перед проблемами. Если где-то что-то непонятно, выскажет несколько гипотез, сам их проверит, докопается до истины. Выше всяких похвал.

GPT-5.1 Codex Max показался немного медлительным и чуть туповатым парнем, таким неповоротливым увальнем сибирских размеров, старательным, но звёзд с неба не хватающим.

Grok Code — торопыга, который как будто считает себя чересчур способным, много фантазирует, принимая свои фантазии за реальность и вообще слишком некритично, без рассуждений всё воспринимающий.

Во-вторых, я хоть и написал на «Гитхабе», что делал обратную разработку методом «чёрного ящика», на деле пришлось активно смотреть в исходники.

Сначала я дизассемблировал код, но это поначалу мало помогло — видно было, что нейросети пытаются «нащупать» в получившемся коде границу функций, чтобы разобраться с ними по отдельности, но не могут. Но позже этого код пригодился — чтобы восстанавливать логику более точно.

Потом я установил radare2 с плагином r2ghidra и нарезал бинарный файл на сишные функции. Код восстановился плохо, с лакунами, поэтому я запустил отдельную сетку, которой буквально по шагам объяснял что делать. Основная идея — довести сишный код до читаемого состояния, разбираясь с функциями от самых коротких к более длинным.

Для этого мы сначала разобрались с таблицей виртуальных функций внутри ассемблера, после чего дело пошло веселей. Заняло это несколько часов интенсивной работы с нейросетями, по ощущениям выглядело как парное программирование.

Параллельно, в другом окне другой экземпляр нейросети писал основной костяк кода, попутно разбираясь с проблемами, туда я заглядывал редко, но без моего внимания то окно тоже не обходилось.

В полным соответствии с принципом Парето, 20% кода отняло у меня 80% времени. Тут очень хорошо показал себя Opus 4.5, — поскольку в коде разобраться было сложно, там 40 тысяч строк на ассемблере, он ставил очень много эксприментов, сравнивая два набора файлов между собой — тот, который получался при запуске оригинального GIFLITE.EXE с нашим.

Мы долго не могли добиться бинарной точности результирующих файлов — очень много нюансов, которые влияли на то, что получалось. Вплоть до реализации алгоритма сортировки цветов, функции хеширования и прочих мелких деталей. Восстанавливать детали помог ассемблерный код — в Си некоторые подробности не перенеслись, отчасти из-за таблицы виртуальных функций, которую «Гидра» (r2ghidra) расщёлкать не смогла.

В-третьих, интересно было наблюдать образчик выученной беспомощности нейросетей. В самом начале они очень быстро сдавались при исследовании кода. Очень долго, много часов пришлось вести их за руку (я сначала использовал их вперемешку, но потом понял, что «Опус» справляется лучше всех), пока в какой-то момент накопилась критическая масса и всё пошло ощутимо легче. Под конец нейросеть молотила, уже почти не останавливаясь.

Я очень доволен тем, как прошёл эксперимент. Очень интересный опыт и результаты воодушевляющие. Код, как обычно, можно увидеть на «Гитхабе».

Оставить комментарий

JOPA: Javac One Patch Away

Пока я тут использую нейросети для развлечения, некоторые ребята пробуют их для чего-то более полезного — например, один наш соотечественник (о чём можно догадаться по неймингу) за две недели дописал форк старого джава-компилятора Jikes, написанный на Си++. Теперь компилятор называется JOPA и поддерживает Джаву версий 5, 6 и 7.

Это может быть нужно, например, для «бутстрапинга» — когда нужно с «нуля», из исходников собрать джава-компилятор + рантайм + инструменты, без использования проприетарных бинарников.

Я попробовал у себя собрать этот компилятор. Сходу не удалось, но дописанное нейросетью можно нейросетью и запустить. В общем, пять минут и всё получилось.

Правда, на моём тестовом примере JOPA упала с ошибкой при попытке открыть rt.jar (это главный архив стандартной библиотеки), но это удалось решить, просто распаковав его рядом.

В общем, вывод такой: проект интересный, но это не полная JOPA, только компилятор, хотя и работоспособный, поэтому запустить скомпилированную в class программу нечем. У себя я запускал системной Джавой.

Скриншот терминала с командами настройки JAVA_HOME и сборки проекта BouncingBall.java, рядом — окно приложения с красным шаром на белом фоне.

Добавлено позднее: за такое меня ещё не благодарили, какой-то новый опыт:

Письмо от Paul S. с уведомлением о комментарии pshirshov в 7mind/jopa#21: «Thank your your contributions into JOPA», с ссылками на GitHub и отписку.

Оставить комментарий

«Виола» и самолёты: коррективы

Надо бы мне ещё вернуться к теме отображения «Виолой» самолётов. Пока я поправил только масштаб — заметил, что на старых скриншотах, снятых автором этого браузера в 90-е, модели как будто бы в два раза больше. Сообразил, что дело, видимо, в повышенном разрешении экрана моего «Макбука» — в так называемой «ретине». В итоге, я теперь обнаруживаю такие экраны и масштабирую изображение под них.

Но всплыла и ещё одна проблема — иногда «крутилки» как будто меняют ось, вокруг которой они крутят объект, при этом в терминале я вижу многочисленные ошибки следующего вида:

violaIdleEvent(): select() error: : Bad file descriptor

Как будто браузер теряет соединение со своим бэкендом для отрисовки моделей и вращение рассинхронизируется. Как только научусь стабильно повторять эту проблему, попробую поправить.

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и демонстрацией 3D-модели ракеты в желтом каркасе, отображаемой через XPlot.

Оставить комментарий

«Виола» и моя мечта: как ИИ снова мне помог ★

Вступление

Я, как вы знаете, довольно давно уже реставрирую браузер «Виола» из недописанных исходников. И была у одна мечта, связанная с ним: увидеть как в нём работает вращение трёхмерной модели самолёта.

Узнал я об этом из статей о судебной тяжбе компаний «Микрософт» и «Иолас» (Eolas), начавшейся в 1999-м году.

Компания «Иолас» утверждала, что первой разработала и внедрила технологию «встроенных объектов и плагинов» для веб-браузеров, и «Микрософт», по их мнению, нарушала права, используя схожий механизм. В этой связи автора «Виолы» вызывали в суд, где рассказал, что придумал эту технологию ещё в начале 90-х годов, тогда как «Иолас» получила на неё патент только в 1998-м.

Тема широко освещалась в прессе и в некоторых из статей есть статичный скриншот того как это выглядело. Кроме того, сохранился код страницы с программой на языке «Виола». Казалось бы — почти всё что нужно!

Скриншот ViolaWWW: заголовок «Front-Ending External Programs», описание встраивания front-end для XPlot, жёлтый каркасный самолёт на синем фоне.
Скриншот того как это выглядело в первой половине 1990-х

Что мешало

Но оказалось, что исполнению моей мечты мешало несколько обстоятельств.

Во-первых, на самом деле модель вращала утилита V-Plot, написанная Скоттом Силви, который учился вместе с автором «Виолы». Её исходники не сохранились.

Во-вторых, судя по сохранившимся исходникам веб-страницы, вращались две модели, которые назывались TomCat и x29.geom, которые ещё нужно было найти.

В-третьих, как оказалось, часть, которая должна взаимодейстовать с V-Plot не работала.

Вопрос №1: где взять V-Plot?

По всей видимости, в открытых источниках его не найти — сколько не запускал я невод глубокого поиска нейросетями, ничего не вышло. Тогда я решил пойти от обратного — у нас есть скрипт на «Виоле», который должен слать этой программе какие-то команды, так может нейросеть, отталкиваясь от них, мне её просто напишет?

Без особой надежды я дал нейросети такое задание и пошёл заниматься делами. Через какое-то время у меня был на руках исходник, в который я даже не заглядывал. Решил просто всё запустить и посмотреть что будет. Ожидаемо ничего не заработало сразу. Я пожаловался на этой нейросети и мы пошли смотреть в чём причина.

Оказалось, что специальный «объект» TTY «Виолы» для взаимодействия с программами, которые могут выводить графику в окно браузера, реализован только для «Линукса», а для «МакОСи» (в «Виоле» встречаются куски для очень старой версии этой операционной системы) код реализован не был.

Я как можно тщательнее, как зловредному джину, описал что именно хочу получить и опять переключился на свои дела. И вот тут, когда я без особой надежды вернулся через какое-то время посмотреть на то как нейросеть провалила задачу, меня ждало маленькое чудо: в окне, где должны выводиться модели, появилась жёлтая сетка — самодельный V-Plot делал что-то полезное!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и описанием демонстрации встраивания объекта viola для связи с процессом построения графиков XPlot.
Сетка — признак того, что взаимодействие с V-Plot работает!

Здо́рово! Но где же мои самолётики?

Настал момент узнать откуда же брались самолёты. Оказалось, что «Виола» передаёт на вход V-Plot одну из моделей, которые выберет пользователь — там на выбор несколько графиков и две модели в формате OFF (Object File Format). Моделей в комплекте с исходниками браузера не оказалось.

Ориентируясь на приметное имя x29.geom, я решил поискать эту модель, вдруг это что-то известное. А параллельно зарядил ChatGPT глубоким поиском.

Модель действительно оказалось известной — её когда-то изготовила компания «Эванс энд Сазерлэнд», а потом использовали на европейской выставке 1987 года, электронные материалы которой каким-то чудом уцелели и доступны для скачивания.

ChatGPT оказался полезен тем, что правильно идентифицировал модель и рассказал её историю, но сам файл нашёлся банальным поиском по интернету.

Дальше нейросети меня опять удивили — посмотрев на мой найденный файл, сеть для программирования «Опус 4.5», не моргнув глазом, написала мне за каких-то несколько десятков секунд код для парсинга и отображения этого формата. И вот я уже вращал свой первый самолёт!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs», описанием демонстрации встраивания объекта и желтым 3D-графиком XPlot на синем фоне.
Браузер «Виола», вращающий модель самолёта Grumman X-29 в трёх измерениях

Отлично! А что со второй моделью?

Со второй моделью так гладко не вышло — как я ни старался, ничего путного по слову TomCat на нашёл. Решил смириться и найти хоть какую-нибудь модель того же самолёта — ChatGPT определила, что на картинке нарисован Grumman F-14 Tomcat.

Тут наконец пригодился глубокий поиск — нашёлся архив внутри которого лежала модель самолёта F-14, но, вот неприятность, в формате IOB (Imagine object). Формат давно мёртвый и единственный конвертор, который я нашёл — бинарный файл под операционную систему «Амига».

Я, было загрустил, но тут решил попробовать уже совсем безумную штуку — натурально попросить нейросеть написать мне конвертор из формата IOB в OFF, причём без описания самих форматов. Самое смешное, что это сработало, причём с первого раза! Получившаяся модель сразу появилась в окне и заработала!

Скриншот интерфейса ViolaWWW с заголовком «Front-Ending External Programs» и демонстрацией 3D-модели самолёта XPlot в виде жёлтой проволочной сетки на синем фоне.
Модель Grumman F-14 Tomcat, сконвертированная из формата IOB

Выводы, или Что меня удивило

Лёгкость к которой нейросеть провела обратную разработку команд, написала интерпретатор команд для V-Plot и конвертор, просто поражает! Честно сказать, я на такое совсем не надеялся. Максимум, который я ожидал — полуживой прототип, который придётся отлаживать не один день.

Конечно, у меня осталось ещё много задач даже в этом проекте, которые нейросети либо не могут решить самостоятельно, либо даже с моей помощью.

Тем не менее, та работа, которую я проделал над браузером при помощи нейросетей, совершенно неподъёмна для человека в такие короткие сроки.

8 комментариев

Внешний вид браузера «Виола»

Если вы приглядывались к браузеру «Виола» на моих многочисленных скриншотах, могли заметить, что он выглядит каким-то недоделанным — адресная строка и заголовок страницы небрежно брошены в интерфейс.

На деле всё обстояло даже хуже — в нулевом состоянии в этих местах были прописаны заглушки, по которым сразу становилось понятно, что это не интерфейс, а нечто временное.

Мне от этого делалось грустно — я люблю красивый дизайн, а тут такое уродство. Но оказалось, что внутри кода браузера есть закомментированные недописанные куски, в которых можно подглядеть, как на самом деле должен был выглядеть браузер!

Мы с нейросетью посмотрели на этот код, отряхнули его, дописали и выкинули оттуда очевидно лишние вещи (внизу были невзрачные кнопки, дублирующие меню, думаю, это остатки технического интерфейса). Теперь в свежей сборке можно увидеть, каким именно браузер должен был получиться. По-моему, стало гораздо лучше.

Скриншот веб-страницы проекта World Wide Web (W3) в браузере Viola, содержащий описание инициативы, ссылки на разделы и информацию о проекте.

Кстати, пока мы с нейросетью занимались интерфейсом, я решил заняться некрасивым уголком справа внизу. Снял скриншот, чтобы меньше объяснять — многие нейросети довольно неплохо по ним всё понимают и написал в промпте:

Посмотри на out.png, справа внизу светлый угол, за который тянуть надо, не совпадающий по цвету с остальным окном. надо бы поправить цвет, сделать в цвет остального окна.

Вот иллюстрация того как это ещё недавно выглядело:

Кнопки интерфейса: Back Up, Previous, Next, Show Source, Clone Page; надпись «Click to visit the previous document.
Неприятный уголок и технические кнопки, которые я потом убрал

Нейронка, так сказать «взяла под козырек» и начала что-то бодро писать на «Пайтоне». Что странно, кстати, — программа-то на Си. Через какое-то время я вернулся посмотреть что получилось.

Оказалось, она написала мне программу, которая покрасила краешек моего скриншота в правильный цвет!

В итоге я вообще убрал этот уголок: масштабирование всё равно нормально не работает, остаются артефакты, да и в оригинальной программе окно было фиксированного размера.

Оставить комментарий

Как мы видим старый веб

Я часто пишу, что считаю проект «Веб-архива» самым важным в интернете. Пользуюсь им постоянно и большинство ссылок за четверть века ведения своего сайта во временем стали вести туда. Особенно интересно на «Веб-архиве» смотреть на то, как начинался веб, времени прошло немного, но изменилось всё самым радикальным образом.

И вот интересная штука, я ведь начал заниматься вебом в 90-е, свой первый в жизни сайт сделал в начале 1998-го, отлично помню, что браузеры того времени имели много нестандартных тегов, которые сейчас не отображаются — тот же мегапопулярный в те времена «Нетскейп» имел теги LAYER и ILAYER, вместо современных DIV и IFRAME.

Но только когда я начал заниматься реставрацией старого браузера, понял что ранний веб-то я в современном браузере иногда вижу совсем не так, как его задумывали авторы.

Мало беды, если не видно какого-то оформления, типа мигания (BLINK) или бегущей строки (MARQUEE), неприятно, если поедет оформление из-за отсутствия поддержки старого тега многоколоночности (MULTICOL) или тех же тегов-контейнеров (LAYER), но по-настоящему плохо, если не видна часть важного контента.

В максимальной степени это видно на страницах сайта браузера «Виолы», там в современных браузера вообще мало что показывается — поддержка слишком многого канула в Лету, а заметку я решил написать, потому что обнаружил, что презентация, которую я смотрел вчера, должна быть оформлена иначе.

Часть картинок, которые там использованы в оформлении, в ничем сейчас не поддерживаемом формате XPM, а другая часть вставлена при помощи тега FIG, поддержки которого сейчас тоже нигде нет.

На скриншоте — слайд про виртуальную среду, про который я писал вчера вечером, со всеми картинками, которые должны там отображаться. Тут, конечно, можно и без них обойтись, в этом смысле более показательный пример, как я уже упоминал выше, — сайт «Виолы».

Две бурые медведицы стоят на каменистом берегу у воды, одна смотрит в камеру, другая — в сторону; на заднем плане видна водная гладь и прибрежная растительность.

Оставить комментарий

HTML 3.0 и VR

Пока искал в интернете информацию по тегу FIGURE, набрёл на какую-то недоделанную, но очень интересную презентацию «A Quick Review of HTML 3.0». Судя по версии HTML, это должно быть в районе 1995 года.

Под подзаголовком «Figures with local event processing» скрывается видение того как в будущем будет выглядеть веб в виртуальной реальности. Причём автор считал, что это будет ближайшее будущее:

К концу этого десятилетия дальнейший рост соотношения цена/производительность позволит доступным настольным системам запускать высокореалистичные модели виртуальной реальности. […] сейчас самое подходящее время для разработки механизмов, позволяющих людям делиться VR-моделями в глобальном масштабе.

Я и не знал, что первый коммерческий наголовный дисплей был выпущен в 1994-м году, думал в 90-е такое только в фантастических фильмах встречалось:

Джойстики и устройства типа «SpaceBall» улучшают управление, но не могут конкурировать с полной «погружённостью», которую обеспечивают наголовные дисплеи. Системы премиум-класса используют магнитное отслеживание положения головы и конечностей пользователя, а также устройства вроде трёхмерных мышей и киберперчаток, ещё больше усиливающие иллюзию.

Автор соврешенно справедливо полагал, что звук тоже важен, не только изображение:

Звук может быть не менее важен для иллюзии, чем визуальная симуляция: звук тикающих часов усиливается по мере того, как вы к ним приближаетесь. Самолёт с рёвом пролетает над головой, перемещаясь от одного горизонта к другому.

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

Виртуальная среда может накладывать те же ограничения, что и реальный мир, например силу тяжести или ограничение движения ходьбой, подъёмом/спуском по лестнице, поднятием и опусканием предметов. Либо, наоборот, пользователи могут «обзавестись суперсилами» и с лёгкостью летать по воздуху или даже проходить сквозь стены!

…но на деле речь просто реализацию физики на экране:

При использовании простого интерфейса, например мыши, обучаться бывает легче, если набор возможных действий в каждый момент ограничен небольшой совокупностью вариантов. Например, движение вперёд по направлению к лестнице приводит к тому, что вы автоматически поднимаетесь по ступеням.

А тут технически интересная, но сейчас уже неактуальная идея, которая в теории могла бы помочь сэкономить вычислительные ресурсы — идея строить виртуальную среду из готовых предметов, используя для этого специальный язык разметки:

Возможно, мы сможем опереться на опыт конвертации документов и SGML и задавать VR-среды на логическом уровне, предоставив браузерам заполнять детали в соответствии с возможностями каждой платформы.

Базовая идея заключается в том, чтобы составлять VR-среды из ограниченного набора логических элементов, например стул, дверь, пол. Размеры некоторых элементов можно брать по умолчанию. Для других, например размеров комнаты, требуются списки точек — скажем, для описания многоугольника, задающего план пола. Дополнительные параметры задают цвет и текстуру поверхностей. Рамка картины, висящей на стене, может быть описана с помощью растрового изображения.

Я немного сократил статью, она чуть больше, но, к сожалению, не дописана, кончается в неожиданном месте:

Хранение таких подробностей в отдельных файлах даёт несколько преимуществ:

10 комментариев

«Виола»: ИИ и отображение PostScript

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

Случайно, изучая заголовки, которые отправляет «Виола», я обнаружил, что этот браузер каким-то образом работать с «ПостСкриптом» — это язык описания страниц, который используется, например, принтерами. Для этого, как оказалось, нужно использовать отдельный тег FIGURE.

Непонятно для этого понадобился отдельный тег, ну вот так сделано. Для наглядности вот пример его использования:

<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 напрямую безо всяких посредников. Пришлось только учесть, что по-умолчанию она создаёт GIF с прозрачностью, тогда как предыдущий набор использовал белый фон.

Довольно быстро я починил и реализацию атрибута ISMAP — просто скопировал его из обработчика формата XBM, где он работал, а починку MAYDELAY отдал нейросети.

Вроде ничего сложного, опять же — этот атрибут работал у XBM, я предполагал, что сеть быстро разберётся в чём там дело, передрав рабочий код и наложив его на особенность — XBM отображается напрямую внутренней библиотекой браузера, а «ПостСкрипт» конвертируется.

Примерно спустя час я сдался. Ни ChatGPT 5.1 Codex, ни Gemini 3 Pro, ни моя любимая Sonnet 4.5 с задачей не справились — каждая из них писала мне огромную простыню кода, которая задачу не решала.

Кусок кода, который надо было поправить, выглядел следующим образом. Если атрибут MAYDELAY не указывался, то вызывалась конвертация «ПостСкрипта» в GIF и он показывался, в противном случае запускался таймер, который вызывал loadData — другой… э… метод, назовём это так, программы на внутреннем языке «Виолы», в котором конвертации не было.

Модели это видели и просто копировали конвертацию в этот метод, но к моменту срабатывания таймера файл, с которым нужно было работать, уже пропадал. Думаю, его удалял сборщик временных файлов, встроенный в «Виолу». В итоге ничего толком не работало: модели ходили по кругу и, пытаясь исправить ситуацию, писали всё больше кода.

Исправление, которое сделал я, работает очень просто: я сначала делаю конвертацию, потом смотрю, есть ли параметр MAYDELAY, если нет, отдаю сконвертированную в GIF картинку в отрисовку, если есть, откладываю отрисовку, передавая в метод loadData уже сконвертированную картинку.

По сути, я передвинул несколько строк кода чуть ниже, это всё моё исправление. Я как-то очень разочарован, что умнейшие из нейросетей до этого не додумались. Можно посмотреть в моём коммите, но там сразу несколько вещей исправляются.

Скриншот браузера Viola WWW с заголовком «PostScript FIGURE Test» и графиком: три надписи «text» (красный с зелёной обводкой, сплошной красный, красный контур).
Пример изображения PostScript взят из чужого репозитория

Оставить комментарий

Какой у вас GPU

Я тут случайно узнал, что через WebGL, оказывается, можно определить какой графический ускоритель используется на машине, где запущен браузер. Окно я стилизовал просто потому что просто так выводить было скучно. Посмотрите что у вас там написано.

Технически берётся параметр UNMASKED_RENDERER_WEBGL у контекста объекта WebGL.

GPU checker

_

×

У меня тут сейчас написано следующее:
ANGLE (Apple, ANGLE Metal Renderer: Apple M3 Max, Unspecified Version)

У братишки на рабочем компьютере (там «Виндоуз»):
ANGLE (Intel, Intel(R) UHD Graphics 770 (0x0000A780) Direct3D11 vs_5_0 ps_5_0, D3D11)

На моём смартфоне «Сяоми 14 Ультра»:
Adreno (TM) 750

Добавлено: как справедливо заметили в комментариях в телеграмном канале, это странно, что браузер позволяет так точно определить эту информацию, посколько производители браузеров часто борются с идентификацией браузера, а тут информация, которая позволяет производить идентификацию точнее.

6 комментариев

«Виола»: математический модуль

Наверное, можно подумать, что я забросил заниматься браузером «Виола» — первым графическим браузером с потрясающими для своего времени возможностями. На самом деле — ничего подобного: почти каждый день, с редкими пропусками, я что-то в нём правлю.

Тот исходный код, который мне достался, был в статусе беты, но даже для беты тут очень много вполне очевидных багов, которые нужно исправить. А ещё — много впечатляющих вещей, которые автор, по всей видимости, не успел доделать. Часть из них я нашёл чисто случайно, как, например, модуль для отображения математических формул.

Нашёлся он совершенно случайно, когда я чинил баг с отображением символьных сущностей HTML — плёвая ошибка: дело было в том, что char у меня в компиляторе — тип со знаком, а в компиляторе автора, видимо, был без него. Из-за этого часть функций, работающих с символами, работала неверно.

Скриншот веб-страницы «Complex Mathematical Formulas Test» с формулами: e^(iπ)+1=0, x=(-b±c)/2a, интеграл e^(-x), сумма квадратов и e^x².

В общем, обнаружив модуль для отображения математических функций, я занялся им. Основное поправил, но кое-что до сих пор работает неправильно, буду позже править, думаю на это уйдёт ещё много сил.

Вот как выглядят формулы:

<math>&integral;<sup>&infin;</sup><sub>0</sub> e<sup>-x</sup> = <box>&sigma;<over>2</box></math>

Это третья формула на моём скриншоте, можно посмотреть чему соответствуют отдельные элементы. Как можно убедиться, реализованное в «Виоле» почти в точности совпадает со стандартом HTML Math, разрабатываемым когда-то Консорциумом Всемирной паутины, который так и остался в стадии черновика. Правда в браузере реализована только малая часть.

Синтаксис довольно простой, но, в принципе, несложные формулы записать можно. Вся математика отображается красным, я думал это какой-то баг, но нет, это такая особенность.

4 комментария

«99 бутылок» и «Постгрес»

Недавно моему сайту исполнилось 25 лет и я вспоминал свою первую заметку, с которой всё началось. Она положила начало традиции, которая длится столько, сколько существует этот сайт — писать «песню о пиве», это такая американская считалочка, на различных языках программирования.

Когда я пересматривал ту заметку, обратил внимание насколько сложно написана была «песня о пиве» на языке СУБД «Постгрес». Это был 2000-й год, седьмая версия, не исключено что тогда проще было и нельзя. Но прошедшие десятилетия «Постгрес» сильно изменился, хочу показать насколько проще можно сейчас написать то же самое:

(
    WITH phrase(ph) AS (
        SELECT COALESCE(NULLIF(beer, 0)::text, 'no') || ' bottle' ||
            CASE beer WHEN 1 THEN '' ELSE 's' END || ' of beer'
        FROM generate_series(99, 0, -1) AS c(beer)
    )
    SELECT ph || ' on the wall, ' || ph || '.' || e'\n' ||
        'Take one down and pass it around, ' ||
        LEAD(ph) OVER() || e' on the wall.\n' AS " "
    FROM phrase LIMIT 99
)
UNION ALL SELECT
'No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.';

7 комментариев

AV1 и аппаратное ускорение

Есть такой относительно новый хороший формат графики для веба — AVIF (появился всего семь лет назад). Формат правда хороший, но есть недостаток — очень уж алгоритмически сложный. Из-за этого кодировать в него получается довольно медленно. Декодировать, кстати, тоже не сахар — на медленных компьютера сотня картинок может сильно нагружать процессор.

И декодеры и кодеры стараются программно ускорить, но всё равно получается довольно медленно. Я давно предсказывал появление аппаратных ускорителей, но пропустил момент, когда они появились. Мой «Макбук» на чипе «М3 Макс», значит у меня есть по меньшей мере декодер.

На картинке он обозначен как «AV1 decode», AV1 — это название кодека, которым сжата графика в формате AVIF.

График: производительность чипов Apple по видеоускорению. M3 Ultra — 1404%, M2 Ultra — 1202%, M1 Ultra — 1026%, M4 Max — 834%. Поддержка AV1, H.264, HEVC, ProRes.

У «Интела» аппаратный декодер тоже есть, думаю у других производителей тоже, я не смотрел. А это, по сути, значит, что формат уже победил всех конкурентов и постепенно начнёт выходить на первые позиции. Разве что появится что-то легковесное, но при этом обладающее лучшим коэффициентом сжатия, но в это верится с трудом.

Оставить комментарий

Что прикупить из нейросетей?

У меня постоянно спрашивают, сколько и за какие нейросети я плачу. На самом деле у меня немного платных сервисов — всего две подписки.

У меня оформлена самая дешёвая ($22,4 в месяц) подписка на ChatGPT, и то только из-за функции глубокого поиска. За эти деньги нейросеть может несколько раз (точно не помню, ни разу не упирался в лимит) очень тщательно, порой десятки минут, шерстить интернет с заданной вами целью, а затем кратко обобщить найденное.

Это ощущается как помощник, который готов выполнить для вас поисковую работу. Пользуюсь постоянно. В последний раз — два дня назад, когда искал, где недалеко от нашего отеля (мы сейчас в Эмиратах) жена и дочка могут покататься на лошадях.

Эту же сеть я использую для коррекции фотографий, редактирования текстов и выжимки текста, когда нет времени изучать что-то большое. Но, кажется, это всё можно делать и в бесплатной версии.

Кроме того, у меня есть самая дешёвая ($20) подписка на «Курсор», чтобы программировать, но сейчас мне не хватает, я всё время докупаю токены. Планирую перейти на более дорогой тариф ($80), но, учитывая мои аппетиты, может и этого не хватить. Когда «Виола» надоест, вернусь обратно на самый дешёвый.

4 комментария

«Виола» и эпоха раннего интернета

В начале интернета никто не думал о безопасности — ни о шифровании, ни об аутентификации, ни о защите от перебора или других атак. Даже в хорошо знакомой всем электронной почте можно было подставить произвольный обратный адрес.

«Виола» в этом смысле — продукт своего времени. Браузер позволяет себе очень многое, причём без какого-либо разрешения. С одной стороны это даёт дополнительные возможности, с другой позволяет легко натворить всяких дел.

На моём скриншоте две программы для «Виолы» от автора браузера.

Слева — небольшой графический редактор, в котором моя дочь нарисовала котика и синюю рыбу. Для своей работы редактор запросто читает несколько файлов из моей файловой системы — он использует содержимое этих файлов в качестве одного из вариантов кистей.

Справа — пример того, как страница может вывести произвольную информацию на панель браузера с кнопками. В данном примере создаётся соединение с адресом pebble.berkeley.ora.com по порту 7777, и строится график чисел, получаемых из этого сокета. Такого адреса давно нет, чтобы пример заработал, я написал небольшой сервер на «Пайтоне» и перенаправил этот адрес на свою машину.

Скриншоты интерфейса ViolaWWW: слева — окно «doodle» с рисунком кота и фигур, справа — «Continuously Updating Field» с кодом скрипта monitorBar.v и заголовком в тулбаре.

Осталось полшага до того, чтобы выкачать всё важное из моего компьютера и отправить в интернет по произвольному адресу и протоколу.

Я сейчас как раз думаю что с этим делать. Я могу сделать так, чтобы файлы читались не по абсолютному пути, а по относительному, из какой-то «песочницы», это просто, а вот что делать с сетевыми соединениями пока не ясно. Кроме того, скриптовый язык может запускать произвольные программы.

В браузере компании «Нетскейп» был специальный «менеджер привилегий», который позволял попросить у пользователя разрешение на выполнение каких-то действий. Вот так, например, нужно было попросить разрешение на доступ к файлам и сети:

netscape.security.PrivilegeManager.enablePrivilege('UniversalFileAccess')
netscape.security.PrivilegeManager.enablePrivilege("UniversalConnect")

Можно было бы сделать примерно так же — спрашивать разрешение, но слишком далеко отходить от исходного поведения браузера мне не хочется. Мне нравится идея сохранить его поведение как можно ближе к тому, что было в 90-е.

В общем, думаю пока как всё сделать лучшим образом.

Оставить комментарий

Как рождался CSS

Мне стало интересно: автор «Виолы» первым догадался отделить стилизацию элементов от структуры, или эта идея уже активно обсуждалась? Нашёл объёмное исследование о том, как зарождался CSS. Браузер «Виола» со своими собственными таблицами стилей там тоже упомянут.

Оказалось, что таблицы стилей как концепция гораздо старше самого веба. Ещё в конце 1970-х Брайан Рид из Университета Карнеги—Меллон разработал систему разметки «Скрайб». Она стала темой его докторской диссертации, защищённой в 1980 году, за которую в 1982-м Рид получил премию имени Грейс Мюррей Хоппер, присуждаемую Ассоциацией вычислительной техники (ACM).

Язык разметки описывал структуру документа — слова, строки, страницы, интервалы, заголовки, подстрочные примечания, нумерацию, оглавление и т. д. — по принципу, близкому к HTML. Далее специальный компилятор использовал базу стилей (Style Database), где хранились определения оформления — шрифты, поля, отступы и прочие параметры.

Сравнение разметки: ручные пометки, слова-разделители, escape-символы (@i, @b, @begin) для курсива, жирного, цитат.
Описание разметки «Скрайба», скриншот из руководства (октябрь 1980 года)

Позже, с появлением веба и браузеров, эта идея перекочевала и туда. До стандартизации CSS существовало множество предложений о том, каким должен быть синтаксис таблиц стилей в вебе, в найденном мной исследовании можно с ними ознакомиться.

Синтаксис «Виолы» был не самым продуманным, не был и единственным, но был одним из первых — он появился уже в 1993 году.

Оставить комментарий

Шахматы в «Виоле»

Посмотрел несколько готовых демок для «Виолы». Больше всего меня смутили шахматы — я-то думал в моём варианте этого браузера что-то сломано, а на деле это очень простая программа, где можно двигать любые фигуры — контроль хода рудиментарный. При этом нет ни игры за компьютер, ни даже взятия фигуры.

Для браузера, который в девяностые был первопроходцем в вебе, это более чем круто, но я всё равно ожидал какой-то более полный вариант.

Скриншот веб-страницы «A Chess Board» с шахматной доской, где белые фигуры стоят на 1–2 рядах, чёрные — на 7–8, а на 4-м и 5-м рядах по одной пешке каждого цвета.

Потихоньку начинаю смотреть что же не работает в интерпретаторе встроенного языка. Что меня поражает до сих пор — это возможность на нём дописывать браузер.

Например, я недавно делал поддержку протокола «Веб-архива» — если сайта нет, то я ищу его в «Веб-архиве». Чтобы это смотрелось естественно, мне хотелось в урле браузера оставить только урл открываемого сайта. Это я сделал при помощи встроенного языка:

/* Show original URL when loading via Wayback Machine */
dispURL = docURL;
/* Rule: find "https://web.archive.org/web/", then drop until next '/' */
wbPrefix = "https://web.archive.org/web/";
wbAt = findPattern(dispURL, wbPrefix);

if (wbAt != -1) {
    wbAfter = wbAt + 1;
    wbRest = nthChar(dispURL, wbAfter, 999);
    wbSlash = findPattern(wbRest, "/");

    if (wbSlash != -1) {
        dispURL = nthChar(wbRest, wbSlash + 1, 999);
    }
}
mvw.doc.url("show", dispURL);

Изобретённый компанией «Мозилла» «зул» (XUL), который позволяет делать то же самое , появился только в 1999-м, а тут браузер начала девяностых! Если бы он в своё время собрал вокруг себя сообщество побольше, интерактивная революция в вебе могла случиться на десятилетие раньше.

2 комментария

Скриптовый язык «Виолы»

С синтаксисом стилевых таблиц в «Виоле» я вполне освоился, а вот скриптовый язык толком ещё не смотрел. Вижу, что многие вещи точно работают. Например, логика стилевых таблиц целиком написана на нём. Ещё один пример: на одной из страниц документации к браузеру анимация сделана с помощью скриптинга.

Постепенно доберусь и до него, а пока масштаб трагедии самым краешком выглядывает из-за просматриваемых страниц: кое-где видно, что скрипты не всегда работают так как требуется.

Кстати, страница на скриншоте выглядит идеально, ровно как задумано. Такой её в современном браузере не посмотреть. Тут и анимация, и собственные виоловские стили, и кнопки, добавленные страницей — ещё одна интересная фича «Виолы».

Скриншот интерфейса браузера ViolaWWW Hypermedia Browser (V 3.3) с предупреждением о бета-версии, описанием функций поддержки HTML 3.0 и навигационными элементами.

2 комментария

Патч Бармина

У меня тут случайно получился прекрасный пример того, почему нейросети пока нельзя пускать в самостоятельное программирование.

Браузер «Виола», портированием которого я занимаюсь, среди прочих форматов графики поддерживает ещё и формат XPM. Сейчас не особо важно, что это такое, но вчера я вспомнил, что родственный ему формат XBM когда-то убрали из браузеров — в его парсере обнаружили уязвимости. К тому времени им почти не пользовались, так что это был логичный шаг.

Я решил посмотреть, нет ли в XPM тех же уязвимостей и, если они есть, — исправить.

Одна из уязвимостей, которую мы рассматривали, — запуск произвольных команд. Мы её, конечно, закрыли, но посмотрите, что нейросеть предложила в качестве теста на отсутствие уязвимости: запуск команды rm -rf /, которая, если бы сработала, удалила бы на диске всё, до чего у неё был бы доступ.

Массив тестовых данных для проверки обработки имён файлов, включая валидные случаи и попытки инъекции команд через символы ;, |, $(), `, &, >.

4 комментария

← 1 6 7 8 9 10 67 →