А как?
Как?
Реально, как? Скажите мне. Почему это происходит так..

Прототипно-ориентированный язык программирования
Selectel открыл первую часть курса по JavaScript

Привет, Хабр! Новичкам бывает трудно сделать первый шаг в программировании. В интернете много сомнительных курсов, а качественные требуют финансовых вложений и несколько месяцев на изучение.
Мы в Selectel подготовили бесплатный курс, который поможет быстро и без лишних затрат изучить основы JavaScript. В первую часть входят три модуля. Вы узнаете:
для чего разработчики используют JavaScript,
как работать с со скриптами, веб-страницами и переменными,
как создать рабочее окружение на IT-инфраструктуре Selectel.
Участники курса смогут бесплатно протестировать сервисы Selectel, а по итогам тестирования — получить сертификат о прохождении.
Макротасок не существует.
Один из самых частых вопросов на собеседованиях для frontend разработчиков: Расскажите про событийный цикл? как выполняются таски? что такое микротаски и макротаски?
В архитектуре event loop вообще нет такого слова как макротаски(macrotasks). Я вообще не смог найти ни одной спецификации, где было бы написано слово macrotask. Кроме Promises/A+. Так в чем же разница между Promise и setTimeout? Почему Promise всегда(не всегда) будут исполняться в приоритете?
Браузер имеет несколько очередей задач (task queues) для разных типов тасок. Таска - это любой javascript код, запланированный стандартными механизмами, такие как запуск программы, запуск события или коллбэки. Помимо этого вы можете создать таску с помощью API, например WindowTimers(setTimeout, setInterval). Микротаски же в свою очередь такие же конструкции javascript, которые позволяют выполнять операции не дожидаясь запуска нового цикла event loop (process.nextTick, Promises, queueMicrotask). Так вот, так как setTimeout, setInterval относятся к браузерному API, то очередь микротасок, таких как Promise и т.д. всегда будет в приоритете выполнения, перед браузерным API.
При этом стоит учитывать, что браузерные API исполняют таски в разные очереди и по разному, например MutationObserver среагировавший после того, как в очередь микротасок попал успешный промис от функции fetch, будет выполнен раньше. То есть вставка в очередь тасок может быть не только как push. Таким образом то, что называют макротасками - это таски браузерного API, которые выполняются по одной на цикл движка браузера.
Полезные материалы
W3 (https://www.w3.org/TR/2011/WD-html5-20110525/webappapis.html#task-queue)
MDN Event Loop (https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)
Tasks, microtasks, queues and schedules (https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules)
Филипп Робертс: Что за чертовщина такая event loop? | JSConf EU 2014 (https://www.youtube.com/watch?v=8aGhZQkoFbQ)
Джейк Арчибальд. В цикле - JSConf.Asia (https://www.youtube.com/watch?v=cCOL7MC4Pl0)
Игра на джем "Rush lvl 8"
Ребята всем привет, опубликовал на джем игру простую, но довольно интересную.
Мне посоветовали её на гитхаб pages выложить, что я и сделал.
Если хотите - зацените геймплей и если хотите непосредственно попробовать то вот ссылка
https://prikalel.github.io/they-grow/
Если хотите поддержать то оставьте комментарий под постом или зайдите на страницу джема и поставьте лайк мне будет очень приятно)
Представлен открытый веб-редактор изображений DPaint.js (онлайн-версия) на JavaScript, созданный по образцу легендарного Deluxe Paint, с упором на ретро-форматы файлов Amiga. Помимо современных форматов изображений, DPaint.js может читать и записывать файлы иконок Amiga и изображения IFF ILBM.
Основные возможности проекта: слои, выделение, маскирование, инструменты трансформации, эффекты и фильтры, множественная отмена/повтор действий, копирование/вставка из любой другой программы обработки изображений или источника изображений, настраиваемые инструменты дизеринга и циклическая смена цветов.

Коллеги привет, искал себе решение как реагировать на изменения в объекте и нашел отличный сервис, который используется внутри директив таких как NgClass и NgStyle.
KeyValueDiffers позволяет создать KeyValueDiffer для сравнения изменений текущих пар ключ-значение с новыми. Если вы используете иммутабельные объекты, то можно просто обернуть все в эффект, ну а если вы наследники крутого легаси, где все объекты мутируются по ссылке, тогда проверку нужно вешать в DoCheck, чтобы реагировать на каждый тик change detection.
Накидал оба примера, чтобы поделиться с вами:
Иммутабельный с effect:
@Component({
selector: 'app-test',
template: ''
})
export class TestComponent {
public state = input.required<Record<string, string | number>>();
private differs = inject(KeyValueDiffers);
private differ: KeyValueDiffer<string, string | number> | undefined;
constructor() {
effect(() => {
const currentState = this.state();
// создаем диффер, если он еще не создан
if (!this.differ) {
this.differ = this.differs.find(currentState).create();
}
// Эффект будет перезапускаться при изменении инпут-сигнала.
const changes = this.differ.diff(currentState);
// только если есть изменения
if (changes) {
changes.forEachAddedItem((record) => {
console.log(`В объект добавлена запись: Ключ: ${record.key} | Значение: ${record.currentValue}`)
});
changes.forEachChangedItem((record) => {
console.log(`Изменено: ${record.key} | Новое значение: ${record.currentValue}`)
});
changes.forEachRemovedItem((record) => {
console.log(`Удалено: ${record.key}`)
});
// Остальные методы forEachItem и forEachPreviousItem по необходимости
}
})
}
}
Легаси подход, которого, надеюсь, ни у кого нет, но на всякий случай :)
@Component({
selector: 'app-legacy',
template: ''
})
export class LegacyComponent implements OnInit, DoCheck {
@Input({ required: true }) state!: Record<string, string | number>;
private differs = inject(KeyValueDiffers);
private differ: KeyValueDiffer<string, string | number> | undefined;
ngOnInit() {
// Создаем диффер при инициализации
this.differ = this.differs.find(this.state).create();
}
// Запускается на каждый тик change detection, так как мутации по-другому не отследим.
ngDoCheck(): void {
const changes = this.differ?.diff(this.state);
if (changes) {
changes.forEachAddedItem((record) => {
console.log(`В объект добавлена запись: Ключ: ${record.key} | Значение: ${record.currentValue}`)
});
changes.forEachChangedItem((record) => {
console.log(`Значение изменилось: ${record.key}`)
});
changes.forEachRemovedItem((record) => {
console.log(`Запись удалена: ${record.key}`)
});
// Остальные методы forEachItem и forEachPreviousItem по необходимости
}
}
}

Почему у PWA до сих пор нет полноценного «магазина приложений» — возможно ли это вообще?
Всем привет.
В течение последних месяцев, работая с PWA-приложениями, мы постоянно сталкивались с одним и тем же вопросом:
Почему в 2025 году у PWA до сих пор нет настоящего App Store?
Не просто каталога ссылок, а полноценного магазина приложений — знакомого, вызывающего доверие и понятного обычным пользователям.
При изучении существующих PWA-магазинов и каталогов обнаруживаются одни и те же повторяющиеся проблемы.
⸻
Установка остаётся непонятной для пользователей
Даже сегодня установка PWA вызывает затруднения у обычных пользователей.
Большинство из них не понимают:
• когда приложение действительно можно установить,
• почему инструкции по установке не совпадают с реальными шагами в их браузере или на устройстве.
Во многих PWA-каталогах всё ограничивается текстовой инструкцией — и на этом взаимодействие с сервисом фактически заканчивается.
⸻
Отсутствие доверия
Со стороны пользователя это проявляется в следующем:
• нет содержательных отзывов,
• отсутствует история установок,
• нет ощущения личной библиотеки приложений.
Со стороны разработчиков наблюдаются крайности:
• либо любой может опубликовать приложение без подтверждения права собственности,
• либо проверка обязательна, но сложна и ограничена одним способом (например, через DNS-записи).
В итоге доверие не формируется ни у одной из сторон.
⸻
Разработчики — второстепенные участники экосистемы
Распространённые проблемы:
• медленные и неудобные процессы публикации,
• почти полное отсутствие автоматического заполнения данных из манифеста,
• нехватка инструментов, которые были бы полезны разработчику ещё до установки приложения пользователем.
Экосистема не стимулирует разработчиков поддерживать и развивать свои PWA.
⸻
Интерфейс не воспринимается как «нативный»
Это тонкий, но важный момент.
Если магазин:
• выглядит как обычный веб-сайт,
• не вызывает ассоциаций с App Store или Google Play,
пользователи инстинктивно доверяют ему меньше — даже если сами приложения качественные.
⸻
При этом сами PWA как технология за последние годы заметно повзрослели: офлайн-режим, push-уведомления, installability, Web APIs.
Однако именно слой распространения и доверия остаётся самым слабым звеном.
⸻
Главный вопрос, к которому мы пришли
Возможно ли вообще создать PWA-магазин, который:
• пользователи будут воспринимать как настоящий магазин приложений,
• не станет источником боли для разработчиков,
• сможет устойчиво развиваться, а не быть заброшенным через несколько месяцев?
Или же сама идея магазина PWA в текущей экосистеме изначально ошибочна?
Будет интересно узнать ваш опыт.
Вы публиковали PWA-приложения в существующих магазинах или каталогах?
Что вызывало наибольшие сложности — у разработчиков или у пользователей?
Открытый проект blip в режиме онлайн позволяет визуально оценить сетевую задержку (латентность или latency) при передачи данных от ПК до разных серверов в мире. Решение работает в браузере на любом ПК, ноутбуке, планшете, смартфоне с поддержкой javascript и HTML canvas.

Функциональное программирование перевернуло фронтенд: почему JS возвращается к платформам?

Функциональное программирование перевернуло фронтенд-разработку, но теперь индустрия возвращается к платформенным подходам — почему и как это меняет JS-экосистему?
Статья «Как функциональное программирование изменило фронтенд и почему отрасль возвращается к платформе» разбирает эволюцию: от чистого FP к гибридным решениям, с примерами и выводами для фронтендеров.
Виктория Копылова делится своим анализом, основанным на современных наблюдениях и на тех статьях прошлого, где функциональное программирование воспринималось как путь к «правильному» фронтенду.
polluSensWeb теперь поддерживает 26 датчиков и веб-хуки

С последними обновленьями polluSensWeb теперь поддерживает 26 различных датчиков и внедряет интеграцию с веб-хуками, открывая возможности для автоматизации в реальном времени, пересылки данных и внешних аналитических конвейеров.
До сих пор polluSensWeb был в основном инструментом визуализации и диагностики. Данные оставались в сессии браузера. Это было удобно для тестирования, калибровки или демонстрации, но ограничивало возможности реального применения.
При включенных веб-хуках данные датчиков могут автоматически отправляться на внешний конечный пункт в режиме реального времени.
Это позволяет:
Пересылать измерения в базы данных.
Запускать оповещения или автоматизацию.
Отсылать данные в панели мониторинга, такие как Grafana.
Интегрироваться с платформами сообществ или пользовательскими API.
Как получить почти бесконечное зацикливание без использования циклов и без переполнения стека вызовов:
// Установите N = 64, и эта функция никогда не завершится
// Количество вызовов (calls) = 2^(N+1)
// Максимальная глубина вложенности = N
let calls = 0
const N = 18
function func(state, visited) {
calls++
if (calls > 10_000_000) {
throw new Error('calls: ' + calls)
}
if (visited.includes(state)) return
const newVisited = [...visited, state]
func((state + 1) % N, newVisited)
func((state + 1) % N, newVisited)
}
func(0, [])
console.log('calls:', calls)
Почему это работает без переполнения стека?
func(0, [])
├── func(1, [0])
│ ├── func(2, [0,1])
│ │ └── ... глубина растёт до N
│ │ и перебираются все возможные комбинации значений в newVisited
│ └── func(2, [0,1]) - возвращается, глубина УМЕНЬШАЕТСЯ
└── func(1, [0]) - второй вызов, стек уже освободился
А Garbage Collector (GC) при этом бесконечно удаляет созданные ранее массивы newVisited
Стек "дышит" - достигает максимума N, потом сворачивается, потом снова растёт. Это обход огромного дерева, имеющего небольшую глубину, но очень большую ширину. Это не бесконечная рекурсия. Но при N = 64 количество вызовов будет 2^65 (примерно 10^19) - это займёт тысячи лет, и стек никогда не переполнится.
DDoS-атаки: почему стандартные решения не спасают и как выстроить эффективную защиту. Интервью ispmanager с GreyWeb
Рады вас приветствовать, дорогие читатели!
Тема противодействия DDoS-атакам остается одной из самых острых и актуальных в сфере IT. Атаки постоянно эволюционируют, становятся более сложными и мощными, заставляя специалистов искать новые, более изощренные методы защиты.
В ispmanager мы регулярно сталкиваемся с вопросами наших пользователей о том, как обезопасить свои серверы и проекты. Именно поэтому мы провели глубокое интервью с ведущими экспертами по кибербезопасности из компании GreyWeb, которые специализируются на профессиональной защите от DDoS.
Что мы обсудили и почему это важно для каждого, кто управляет инфраструктурой:
• Эволюция угроз: Как меняются DDoS-атаки и почему вчерашние методы защиты сегодня уже неэффективны.
• Ограничения стандартных решений: Разбор типовых ошибок и мифов, связанных с "базовой" защитой.
• Комплексные стратегии: Какие подходы и технологии позволяют эффективно отражать даже самые мощные и целевые атаки.
• Взгляд изнутри: Практический опыт GreyWeb по предотвращению и минимизации ущерба от DDoS, кейсы и рекомендации.
• Подготовка к атаке: Что нужно сделать заранее, чтобы быть готовым к худшему сценарию.
Это интервью — не просто набор теоретических выкладок, а концентрат практического опыта и аналитики от специалистов, которые ежедневно борются с киберугрозами. Если вы системный администратор, DevOps-инженер, разработчик или владелец сервиса, который не понаслышке знает о рисках DDoS, этот материал будет для вас крайне полезен.
Приглашаем к прочтению: ➡️
https://www.ispmanager.ru/news/case-greyweb
Делитесь вашим опытом борьбы с DDoS в комментариях!

Как автоматизировать Photoshop через кодинг
Когда говорят об автоматизации, чаще всего имеют в виду Python. Но важно понимать: Photoshop не выполняет Python-код напрямую.
Зато у него есть встроенная поддержка скриптов — Photoshop умеет исполнять код на JavaScript (ExtendScript).
Это не «JS как в браузере» и не замена Python. Это родной язык автоматизации Photoshop, с прямым доступом к:
слоям
тексту
смарт-объектам
экспорту файлов
истории документа
Если задача — управлять самим Photoshop, то скрипты внутри Photoshop — самый надёжный путь.
Что это даёт на практике
Через код можно:
массово менять текст в PSD
генерировать сотни изображений из одного шаблона
автоматизировать экспорт
исключить Actions и Variables с их ограничениями
По сути, мы описываем действия, которые дизайнер делает руками, но в виде кода.
Пример задачи
Есть:
один PSD
текстовый слой
значения 1 м → 100 м
Нужно:
автоматически подставить значения
сохранить 100 PNG-файлов
вернуть PSD в исходное состояние
Пример скрипта для Photoshop (JSX)
#target photoshop
var doc = app.activeDocument;
var layerName = "1 м"; // имя текстового слоя
var outputFolder = Folder.selectDialog("Выбери папку для сохранения");
if (!outputFolder) {
alert("Папка не выбрана");
exit();
}
function findTextLayer(layerSet) {
for (var i = 0; i < layerSet.layers.length; i++) {
var layer = layerSet.layers[i];
if (layer.kind == LayerKind.TEXT && layer.name == layerName) {
return layer;
}
if (layer.typename == "LayerSet") {
var found = findTextLayer(layer);
if (found) return found;
}
}
return null;
}
var textLayer = findTextLayer(doc);
if (!textLayer) {
alert("Текстовый слой не найден");
exit();
}
for (var i = 1; i <= 100; i++) {
textLayer.textItem.contents = i + " м";
var file = new File(outputFolder + "/pkabel_4x2_5_" + i + "m.png");
var opts = new PNGSaveOptions();
opts.compression = 9;
doc.saveAs(file, opts, true, Extension.LOWERCASE);
}
// откат без сохранения
doc.activeHistoryState = doc.historyStates[0];
alert("Готово!");
Звёзды разработки и практикующие инженеры разбирают горячие темы — от FAIL до GOD. Встречайте tech-шоу «АйТир Лист» от МойОфис.

В нашем шоу мы берём одну область в разработке, выбираем самые обсуждаемые технологии, практики и подходы — и раскладываем их по шкале от FAIL до GOD.
Формат простой: эксперты защищают свои позиции, спорят, соглашаются и не соглашаются. 14 табличек, 14 поводов для споров и честный экспертный рейтинг без попытки всем понравиться.
Первый выпуск — опенсорс для фронтенда
Дебютный эпизод мы посвятили популярным опенсорс-решениям для фронтенда: от инструментов, которые давно пора отпускать, до стандартов индустрии.
В выпуске:
Александр Коротаев — эксперт по фронтенду и креативному кодингу
Алексей Золотых — тимлид команды веб-редакторов МойОфис
Ведущий — Эдгар Акопян
Обсуждаем инструменты, которые формируют повседневную фронтенд-разработку, и честно отвечаем на вопрос: что сегодня выглядит как GOD-tier, а что застряло на уровне MVP или FAIL.
Смотрите выпуск: YouTube | RuTube | VK
Второй выпуск — фичи и идиомы C++
Во втором эпизоде «АйТир Листа» — уже не инструменты, а язык.
Мы устроили полноценную битву мнений вокруг фич и идиом C++: 14 табличек превращаются в 14 поводов для дебатов, где каждая возможность языка проходит через экспертную оценку.
В выпуске:
Данил Черепанов — архитектор редакторов МойОфис
Антон Полухин — эксперт-разработчик C++ техплатформы городских сервисов Яндекс
Ведущий — Эдгар Акопян
Получилось много споров, неожиданных аргументов и ситуаций, где «привычно» не значит «хорошо».
Смотрите и делитесь мнением: YouTube | RuTube | VK
В следующих выпусках продолжим разбирать технологии без скидок на хайп и «так исторически сложилось». Предлагайте темы, а если готовы к жарким спорам – становитесь участниками нашего шоу) А как стать? Пишите в комменты с какой темой бы хотели поспорить!
Коллеги, всем привет!
За годы менторства по Angular (в том числе в HTML Academy) я заметил одну системную проблему: студенты и даже миддлы часто знают синтаксис RxJS, но не понимают реактивного мышления. В итоге мы получаем subscribe внутри subscribe и императивную лапшу.
Я искал интерактивные курсы, но большинство бесплатных ресурсов ограничиваются основами.
Курс бесплатный. Делал для себя и студентов, но теперь делюсь со всеми.
Буду рад фидбеку и баг-репортам (проект активно допиливаю).
Ссылка на курс: https://rxjs-course-avy.web.app/
React One Click Component
Поделюсь самодельным расширением для VS Code, которое позволяет создавать React-компоненты в один клик.

Что умеет:
гибкое именование файлов: выбор между PascalCase, camelCase, kebab-case или snake_case для генерируемых файлов;
работа с .tsx и .jsx для файлов компонентов, а также .scss, .css, .less и .sass для стилей;
редактируемые шаблоны: настройка содержимого генерируемых файлов прямо в VS Code;
опциональное создание файлов реэкспорта и стилей.
Более подробный readme на странице расширения, ссылка на исходники там же. На мой взгляд экстешнен написан таким образом, что его довольно легко переписать для любого web-фреймворка.
На всякий случай: ни с какими внешними сервисами и нейронками расширение не взаимодействует)
Доброго всем. Первая публикация, прошу не особо...
Не стану растекаться мыслью по древу, пост - следствие поиска по запросам типа "как лучше вставить и анимировать SVG иконки", и подобным в том же ключе. Так как самыми релевантными ответами поиска не удовлетворён, решил написать свой, во-первых, чтобы услышать сообщество. Мало ли, возможно технология уже вовсю применяется в фреймворках, и на поиск все забили "всё и так слишком очевидно".
Во-вторых, сам до сих пор копаюсь в ванильном, поэтому, если старшие товарищи найдут сей вариант приемлемым, пусть пост останется как справка, вроде "а чё, так можно было?". Если же такая практика не применима по ряду пока неизученных мной причин, пост тоже пусть остаётся дополненный комментариями, как пример того "как не надо делать". В общем.
Решил упаковать спрайт в Web Components. Для примера взял отображение файловых иконок, за подопечных три распространённых файловых формата .docs, .xls, .pdf. Раз уж мне и так пришлось испытать муки отсутствия музы( вообще ни разу не художник), прошу отнестись с пониманием к внешнему виду конечного продукта. Упор был на простоту, контролируемость, компоновку. В том смысле, что косметика человеком с утончённым восприятием этого мира может быть применима отдельно.
Да, и ещё один аспект постарался обыграть - наличие общих свойств для всех иконок, коими выбрал подложку, и текст mime типа, и уникальные для каждой иконки элементы, ими выступили "брендовые" цвета и элементы. Так, выбор иконок файловых форматов для спрайта показался оптимальным.
Далее, в общем код(сокращённо, рабочий пример по ссылке), совсем немного к нему объяснений и ссылка на песочницу. И, само собой, ожидание комментариев.
customElements.define("wc-icon-file",
class WC_ICON_FILE extends HTMLElement {
constructor() {
super();
this.#preform = '';
this.#mime = '';
this.#unic = '';
}
connectedCallback() {
this.init();
this.innerHTML=this.#preform;
}
init() {
this._mime = this.getAttribute('data-mime');
let availableMime = {
xlsfile: `<g class="wc-icon-${this.#mime}">
<line style="stroke-width:3;stroke-linecap:butt;" x1="13" x2="17" y1="24" y2="24"/>
<line style="stroke-width:3;stroke-linecap:butt;" x1="18" x2="22" y1="24" y2="24"/>
// и т.д.
<text x="8" y="19" class="f-mime">.xls</text>
</g>`,
docfile: `<g class="wc-icon-${this.#mime}">
<line style="stroke-width:1.8;stroke-linecap:round;" x1="20" x2="24" y1="23" y2="23"/>
<line style="stroke-width:1.3;stroke-linecap:round;" x1="16" x2="30" y1="27" y2="27"/>
// и т.д.
<text x="8" y="19" class="f-mime">.doc</text>
</g>`,
pdffile: `<path class="wc-icon-${this.#mime}" d="m 21.963376,23.938571 // и т.д. />
<text x="8" y="19" class="f-mime">.pdf</text>`
}
this.#unic = availableMime[this.#mime];
this.#preform = `<svg class="wc-icon-file" viewBox="0 0 48 48">
<path class="${this.#mime}" d="M13.528 3.087 30 3l8 9-.316 28.075c-.035 3.151-1.09
4.143-3.716 4.11h-20.44 c-2.303.095-3.676-.718-3.716-4.11V7.197c-.03-2.459
1.504-4.198 3.716-4.11z"/>
${this.#unic}
</svg>`
};
});
let wcIconFile = document.createElement('wc-icon-file');
// export {wcIconFile} по необходимостиСам компонент на странице объявляется как обычно:
<wc-icon-file data-mime="xlsfile"></wc-icon-file>
<wc-icon-file data-mime="docfile"></wc-icon-file>
<wc-icon-file data-mime="pdffile"></wc-icon-file> Код прокомментирую на предмет того, что в init() пришлось соблюсти порядок объявления переменных. Для определения схожих классов с разными "модификаторами" сначала брался атрибут в компоненте. По нему же делалась выборка this.#unic впоследствии вставляемая в this.#preform . Стили здесь не привожу, отмечу лишь, что настройки :hover и анимации там вполне работают.
Благодарю, что уделили время.
Я часто вижу, как разработчики испытывают трудности с i18next. И действительно, это технология интернационализации, которую нелегко освоить.
Несмотря на это, i18next остаётся решением по умолчанию, которое ChatGPT рекомендует для внедрения i18n. Мы слишком часто попадаемся на удочку страниц «Get Started» (да, оно работает, но действительно ли это сделано правильно?).
На практике я замечаю, что многие проекты пропускают самые критичные аспекты интернационализации, особенно связанные с SEO: перевод метаданных, теги hreflang, локализация ссылок, настройка sitemap и robots.txt.
Что ещё хуже, почти половина проектов, использующих i18next (особенно после роста популярности ИИ), не структурируют контент по неймспейсам или же загружают все неймспейсы при каждом запросе.
Последствия? Вы можете заставлять каждого пользователя загружать контент всех страниц на всех языках, даже если он посещает только одну страницу. Например: при 10 страницах и 10 языках 99% загружаемого контента никогда не будет использовано. Совет: используйте анализатор бандла, чтобы выявить это.
Чтобы решить проблему, я подготовил руководство о том, как правильно интернационализировать приложение Next.js 16 с i18next в 2025 году.
Вот ссылка: https://intlayer.org/ru/blog/nextjs-internationalization-using-next-i18next
Представлен открытый проект релейного компьютера 1961 года Minivac 601, работающий в браузере (код на GitHub). До появления микрочипов компьютеры строились на основе механических реле. Это рабочая модель Minivac 601, образовательного компьютера, разработанного Клодом Шенноном.
