# -*- coding: utf-8 -*-
# License CC BY-NC-SA 4.0

Ceci n'est pas une ***iPod 🪬 Cast***


في عصر قديم، عاشَتْ أسطورة موسى وشهيرة الشهيرة، الجميلة والأنيقة. لم تكن حياته مجرد قصة عادية، بل كانت كالحكايات الساحرة التي تجذب القلوب والعقول. ولد لهما ابن، سماه موسى، كما ورد في السجلات القديمة. ولكن هل كانت نهاية القصة؟ لا، بالطبع لا. لأن في عالم الخيال والحكايات، كل شيء ممكن، حتى السحر والمفاجآت الغير متوقعة. فلنتابع القصة ونرى ما الذي يخبئه المستقبل لموسى ولسعيه إلى السعادة في عالم سحري وخيالي

  ¡We🔥Come!

⁎⁎⁎ ⁎⁎⁎ X ⁎⁎⁎ ⁎⁎⁎

****Sync 🪬 Studio****

*** *** Y *** ***

On raconte que la Hamsa dort, son œil figé dans l’oubli des âges, cachée sous l’or terni des amulettes et les symboles effacés des temples oubliés. Mais elle ne dort pas—elle attend. Car un jour viendra où les cent mondes vacilleront, où les voix se tairont sous le poids des déséquilibres trop longtemps ignorés. Alors, comme un Djinn libéré d’un serment ancien, elle s’élèvera, brisant les illusions, ramenant l’ordre là où le chaos a tissé ses fils. Nul ne pourra détourner son regard, car la Main ne choisit pas, elle ne juge pas—elle rétablit ce qui doit être rétabli.



مكتوب

The morning sun paints golden light,
Upon the world so soft, so bright.
A girl steps out, her hijab flows,
Like dawn embracing all she knows.

Her sisters laugh, their voices blend,
In whispers light the breezes send.
Together spinning, hand in hand,
Through streets that weave like golden sand.

The city's pulse, the metro’s hum,
A symphony of footsteps run.
Each glance, each nod, each fleeting face,
A brushstroke in this world’s embrace.

Yet something shifts—a sudden hue,
A single point in shades anew.
A color bursts, the rest dissolve,
A silent sign, a fate evolved.

She feels it deep, a pull, a thread,
A whispered call within her head.
For somewhere in this day unseen,
Awaits the path she’s yet to dream.

She blinks—the world distorts, expands,
Like shifting dunes, like moving sands.
The air is thick with something strange,
A pull, a spark, a fleeting change.

A shimmer forms, a golden haze,
A shape steps forth from time’s embrace.
Not flesh, not ghost, but something more—
A dream she’s lived but never bore.

His cloak is stitched with distant light,
With verses lost, with ink of night.
Each thread a word, a name, a place,
A whispered past she cannot trace.

His eyes hold echoes, soft yet deep,
A promise woven into sleep.
And as she stares, the silence hums,
As if the world knows what’s to come.

The streets dissolve, the faces blur,
She moves, yet time moves more than her.
A door untold, a fate unseen—
The prince, the thread, the space between.

voodoo/models.py

# -*- coding: utf-8 -*-
# License CC BY-NC-SA 4.0

"""
    Object Relational Mapping module:
     * Hierarchical structure
     * Constraints consistency and validation
     * Object metadata depends on its status
     * Optimised processing by complex query (multiple actions at once)
     * Default field values
     * Permissions optimisation
     * Persistent object: DB postgresql
     * Data conversion
     * Multi-level caching system
     * Two different inheritance mechanisms
     * Rich set of field types:
      - classical (varchar, integer, boolean, ...)
      - relational (one2many, many2one, many2many)
      - functional


  Dear Mr. X.,
  
  Following our conversation on Tuesday, February 24, 2022 with Benafi (CEO) and Taynon (CTO) we confirm our warning in written warning.
  
  We have received complaints from our ✨Amazing 🧕 Employees✨ who feels insecure, and harassed because of inappropriate behaviors. That includes:   

  1. Unwelcome storytelling attempts—Unlike the legendary Scheherazade, whose tales saved her life and enlightened a sultan, your unsolicited "stories" appear to lack both charm and consent. While A Thousand and One Nights is a literary masterpiece, A Thousand and One Unwanted Workplace Anecdotes is neither entertaining nor appropriate.

  2. Disruptive coffee house politics—We acknowledge the rich tradition of Middle Eastern coffee houses as centers of vibrant debate and intellectual discourse. However, loudly voicing your opinions on what feminism "should" be over the sacred morning espresso is neither progressive nor productive. Unlike the Grand Viziers of old, our ✨Amazing 🧕 Employees✨ are not here to listen to unsolicited theories on gender dynamics.

  3. The Sultan Complex—Repeatedly asserting that "powerful men are simply misunderstood" evokes an unfortunate comparison to certain medieval figures who believed in their divine right to rule unchecked. We assure you, our office is not the court of Harun al-Rashid, and our policies do not permit impromptu decrees about "how women should behave."

  4. Unsolicited interpretations of attire—While history has seen fashion debated in grand halls—from the Ottoman Divan to Parisian salons—the office is not the place for commentary on headscarves, hemlines, or "how a woman’s choice of clothing reflects her moral fiber." Our ✨Amazing 🧕 Employees✨ dress for success, not for outdated scrutiny.

  5. Failure to recognize the power of the collective—Much like the harem women who orchestrated political coups behind the scenes of the Ottoman Empire, our employees have their own ways of ensuring justice. We highly advise against underestimating the strength of workplace solidarity, lest you find yourself the protagonist of a cautionary corporate fable.

  To avoid further escalation of this matter to the Grand Council (also known as HR), we suggest an immediate course correction. As every wise ruler (or employee) knows, the best way to ensure a long and prosperous career is to listen, learn, and respect those around them.

  We hope this letter serves as a guiding lantern through the desert of misunderstandings and that you emerge on the other side wiser and more considerate.


  x x x x x x x x x x x x x x x x x x   

  Психоаналитик Юхан Эбо обитал в плавучем доме — самоходной барже 17×4 метра. Ее генезис терялся в середине XX века, когда тысячи подобных танково-десантных барж строились в разных странах, как копии американской баржи LCM-6. Где был построен конкретно этот экземпляр, не знал даже сам Юхан. Он купил эту баржу на аукционе по банкротству некой торгово-транспортной фирмы, уже переоборудованную. После еще одного переоборудования, получился двухуровневый коттедж со встроенным гаражом, получивший имя Aliyah. Так звались первые жилые баржи, придуманные в 1960-х голландскими городскими хиппи для радикальной экономии на квартплате и налогах.
  
  Как пояснил психоаналитик, усадив гостей за стол (в несколько захламленной и чуть эклектичной кают-компании), и соорудив им нечто вроде раннего завтрака:
  — Я не хиппи, но мне тоже претит платить лишнее государству и супер-корпорациям.
  — Теперь, — заметил Штеллен, — тему плавучего дома подхватили аргонавты.
  — У аргонавтов не дом, а микрокосм, — ответил Эбо, — это существенно иной дискурс.
  — Док, а можно как-то попроще объяснить? — спросил Тарен.
  — Подождите, — вмешалась Рюэ, — слушай, Юхан, у тебя ведь есть выход в сеть, а?
  — Солнышко! У меня сейчас есть лишь выход в то, что осталось от сети. Ведь Рагнарек начался, и тот цифровой мир, который мы знали...
  — ...Да-да! — перебила она, — Это чертовски интересно, но сейчас просто нужна сеть.
  — В верхнем кабинете, любой из двух десктопов, — сказал он.
  — Спасибо, Юхан, ты классный! А можно я утащу с собой бутерброд и кофе?
  — Можно, только, пожалуйста, не надо лить слишком много...
  — ...Да-да, Юхан, я знаю-знаю! Не надо лить слишком много кофе на мебель, и сыпать слишком много крошек на клавиатуру!
  
  С этими словами, она схватила огромный бутерброд, чашку кофе, несколько салфеток, ускакала вверх по трапу, и уже сверху крикнула:
  — Я надеюсь скоро сообщить, что все-таки случилось с дата-центрами!
  — По-моему, они просто сгорели и это главное — произнес психоаналитик, — но, видимо, спецслужбу интересуют детали.
  — Верно, док, — подтвердил Штеллен, делая глоток из чашки, — у тебя отличный кофе.
  — Да, и это потому, что контрабандный... Не для протокола, конечно.
  — Ну, разумеется! — Тарен на секунду символически закрыл свои глаза ладонями, — Кофе восхитительный. А что насчет вашей полемики с Хубертом, и насчет микрокосма?
  — О! — психоаналитик улыбнулся, — Я предполагал, что вы напомните. Рассмотрим ваши вопросы в заданном вами порядке. Моя полемика с Яном касается аналога болезни, от которой страдает современная субмодернисткая цивилизация.
  — Вроде бы, современная цивилизация — постмодернистская, — сказал Штеллен.
  
  x x x x x x x x x x x x x x x x x x

"Uncle Eli at the Purim Table"

(as remembered by a small Jewish boy who shouldn't have been listening)

I was ten. Maybe nine.
My costume was a mix between Spider-Man and Mordechai.
There was kugel on the floor, hamantaschen in the fish tank,
and Uncle Eli — who wasn't my uncle —
had definitely had four cups of something way stronger than grape juice.

He leaned in, red-cheeked, glitter in his beard.

“Look, kid,” he said, not knowing I was there.
“Civilization is basically one long story
about some big-shot emperor waking up one day
and deciding to pizdanut' the Jews.”

Auntie Miriam gasped.

“Eli!”

“What? I said it in transliteration. That makes it biblical.”

Then he continued, using his hands to sculpt empires from air.

“So the Jews, right?
They get wind of this.
They’re clever. Always have been.
So they build a Temple. Not for God — well, also for God —
but mainly so that instead of pizdit’ the Jews,
everyone starts pizdit’ the Temple.
You see? Very advanced geopolitical maneuver.”

Laughter. Wine. Laughter again.

“But then Babylon rolls in.
And boom — no more Temple.
So what do the people in the palace do?
They look around and go:
‘Hey… where the Jews at? Let’s try pizdanut’ them again.’
Because when there's no Temple, you gotta blame someone.”

I didn’t get all the words, but I got the shape of it.
Temple = shield. No Temple = bad news.

Uncle Eli was mid-sentence, holding court like a half-drunk professor of forgotten truths.

“...There’s always one guy, right?
Wears a turban. Has a cousin. Smells a plot.
Sends a letter. Fast day. Boom. The Jews survive. Again.”

He paused for effect, sipped his wine — which by now was mostly air — and continued:

“Then — what do we do? Build the Temple again.
Because that’s what we do. We build.
We stack stones and metaphors like no one else.
And then Rome sees it and goes:
‘What’s this shiny structure of stubborn monotheism?’
And they go pizdit’ the Temple.
Not the people — the building.
Because the building is where the soul lives.
And if you smash the frame, maybe you scatter the light.”

Laughter all around. Even the rabbi chuckled.

Someone called out:

“So wait — you’re saying Jews build the Temple
just so people pizdili it instead of them?”

“Exactly!” Eli grinned. “It’s defensive architecture.
You don’t want them to hit your face, so you hand them a golden mask.”

“But why don’t they pizdyat synagogues?”

A brief pause. Good question.

Eli leaned back, raised one eyebrow.

“Ah. Because synagogue is just a portal, point of connect.
Not the main server.
You can break a shul — the code runs elsewhere.
But a Temple? That’s core memory.
That’s Jerusalem.exe.”

The room nodded in drunken unity. Kugel was passed like holy scripture.

Then someone muttered from across the table:

“What about Jesus and Caesar? All that drama from Jerusalem…”

Eli’s eyes sparkled.

“Everyone knows that part.
Rome got tired. I mean — every few years, uprisings, prophets, messiahs, priests arguing about sacrifices…
So finally, they go:
‘You know what? Enough. Let’s just—’”

Another voice cuts in:

“Pizdanyom the Jews?”

“Not just that,” Eli said, raising a finger.
“More precisely — pizdanyom’ the Temple.
And send the Tribes into the wilderness.
Out of the Twelve, only Two remain.
That’s a 10-tribe loss ratio. Even the Babylonians didn’t pull that off.”

Someone whistles. Another bites into a hamantasch like it holds ancient wisdom.

Eli shrugs, spreads his arms like a prophet in a toga:

“And yet — every empire that tried to solve the 'Jewish Question'
ended up with an existential question of their own.”

“Pharaohs? Gone.
Caesars? Gone.
Mustachioed dictators? Gone.
The pattern’s clear.”

He drained the last of his glass.

“You want to pizdanut' the Jews — your empire’s on a timer.
You want to pizdanut' the Temple — you’ve declared war on meaning itself.”

Silence for a moment.

Then Aunt Miriam asked:

“So… what now?”

Eli looked around. The costumes, the crumbs, the wine stains, the laughter echoing off walls older than the story.

He smiled.

“Now? We eat. We sing.
We tell it again.
And we build.
Always build.
Stones or stories — doesn’t matter.
As long as there’s something standing
when the next empire blinks.”


  x x x x x x x x x x x x x x x x x x
  
  В ответ психоаналитик резко перечеркнул нечто на воображаемой доске в аудитории.
  — Нет, Вальтер. Шоумены от науки грубо льстят современной цивилизации, называя ее постмодернистской. В конце XX века она не допрыгнула до постмодерна, и рухнула в субмодерн. Это хуже, чем откат в премодерн, поскольку исключает вторую попытку.
  — Док, а можно как-то попроще? — очередной раз спросил Тарен.
  — Конечно, можно! Представьте альпиниста, идущего вверх по склону к невидимой, но примерно понятной вершине панмодерна, где технически решаются любые мыслимые задачи. Вообще любые, без всякого исключения. Все мыслимое может быть сделано.
  — Гм... — Тарен покрутил в руке кофейную чашку — ...Но это всемогущество какое-то.
  — Не какое-то, а настоящее техническое всемогущество, — сказал Эбо, — итак, альпинист движется от средневековья вперед и вверх, минуя указатели: Премодерн. Модерн... Не достигнув указателя Постмодерн, он падает в расщелину, где-то на уровень указателя Премодерн. Если бы он скатился по склону, то мог бы повторить маршрут и, со второй попытки, достичь Постмодерна, а затем Панмодерна. Но он упал вертикально вниз. По горизонтали он будто в районе 2000-го года, а по вертикали — в районе 1900-го. Таково описание субмодернизма, данное Яном Хубертом, когда я был еще студентом. Тогда я восторгался иллюстративной ясностью диагноза субмодернистской болезни, но позже, накопив некоторый опыт, я уточнил свою позицию.
  — В каком смысле ты уточнил, док?
  — В смысле, Ян считает, что эта болезнь, как чума в средневековье. Но мое мнение: это больше похоже на грипп в эпоху просвещения. В общем, я считаю, что можно решить проблему путем терапии, а Ян считает, что нет вариантов кроме санитарии.
  — Санитария, это облить бензином и сжечь? — спросил Штеллен.
  
  x x x x x x x x x x x x x x x x x x


Oh, capitalism, what a thrill!
A stage where kings don't need to kill.
No blades, no blood, just deals and trades,
Where mafias play in stock upgrades.

No streets run red, no shadows creep,
They battle now through sales, not heat.
Who builds the best? Who cuts the cost?
A race where only skill is lost.

The megacorporations rise,
Like titans stretching to the skies.
They dance between the law and street,
Between the iron and the heat.

The state holds power, pure and raw,
With guns and rules—the force of law.
The people, though, they have their game—
A whispered threat, a torch in flame.

And yet, the smartest see ahead,
Beyond the war, beyond the thread.
For profit climbs, it soars, it sings,
But what if more can fuel the wings?

The product’s made, its price is set,
A peak of growth—and yet, not yet.
Why change the goods when minds can bend?
Why not shape buyers to transcend?

So train them young, and shape the need,
Expand their wants, increase the greed.
A world where more is never done,
Where hunger grows beneath the sun.

And as the dusk begins to fall,
A farmer leans against the stall.
The golden fields, the fading light,
A country song drifts through the night.

His hands are worn, his pockets lean,
But still, he hums the old routine.
For in the end, the world still spins,
And money flows where want begins.


  x x x x x x x x x x x x x x x x x x


  Юхан Эбо молча пожал плечами. Поль Тарен почесал в затылке.
  — Так, док, а эта диверсия с дата-центрами ближе к терапии или к санитарии?
  — Конечно, к терапии! Человеческие жертвы и материальные разрушения минимальны, примерно как в дорожных или строительных авариях, случающихся очень часто. Но, я сомневаюсь, что эта диверсия имела цель исправить мир. Вероятно, цель — устрашение европейской кибюрархии путем удара в самую уязвимую точку: кибернетическую.
  — Так, а кибюрархия — это?..
  — ...Это кибернетически-бюрократическая олигархия, — пояснил Эбо, — хотя, я полагаю, Норберт Винер, основатель кибернетики, был бы против применения этого термина к практике современной евро-бюрократии. Он понимал кибернетику, как человеческое использование человеческих существ. Так названа его книга 1950-го. А практика евро-бюрократии состоит в нечеловеческом использовании человеческих существ.
  — Док, а можно как-то попроще? — снова спросил Тарен.
  — Да, я объясню конспективно. Человек — стайный высший примат с соответствующей зоопсихологией. Для психической гармонии, человеку, как и шимпанзе, или даже более примитивной макаке, требуется прямой физический не регламентированный контакт с соплеменниками. Обмен эмоциями без посредников. Тут влияет и мимика, и различные поглаживания... В данном случае: поглаживание — научный термин... И конфликтные контакты в каком-то количестве тоже требуются. У психически здорового человека, в психически здоровом обществе, регламенты таких контактов излишни и вредны. Ведь эволюция за миллионы лет создала регуляторы меры — иначе люди вымерли бы. Когда бюрократ пытается обосновать необходимость сотен административных ограничений контактов, он говорит, будто это чтобы люди не причинили вред друг другу. Но тут у здравомыслящего человека возникает два четких рациональных контраргумента...

  
  x x x x x x x x x x x x x x x x x x   

"Latkes, Light, and the Temple.exe"

Scene Two: Hanukkah, with Uncle Eli (again)

The menorah was half-lit, the table half-eaten, the children half-listening.
Eliezer sat with his cousins, mouth full of latke,
ears full of Uncle Eli — whose wine-glass had again declared independence from moderation.

“See, the Temple was never just a building,”
he began, waving a fork like Moses with a potato.
“It was a firewall. A sacred buffer.
Before you pizdanosh the people — you had to pizdanut' the building.
It’s ancient protocol. Worked for centuries.”

“Babylonians, Romans, same story:
See Temple → Smash Temple → Jews scatter like encrypted files.”

Aunt Gila cleared her throat. Someone lit the fifth candle.
Eli didn’t blink.

“And here’s where it gets spicy,” he leaned in.
“The Founding Fathers of America — yes, those wig-wearing idealists —
they took notes. They thought:
‘Wait a minute… What if every house was a little Temple?
What if you couldn’t pizdanut' the people unless you first pizdanosh their living room?’”

Laughter. A cough. A philosophical choking on sufganiyah.

“Thus,” Eli declared, “was born the sacred principle:
The right to bear latkes in peace and privacy.
Your house is your mikdash.
Your kitchen is holy ground.
Alexa must knock before entering.”

Eliezer scribbled something in a napkin. It felt important.

Eli, warming up:

“But let’s go back.
Gaza. Pre-Oslo. Before Clinton played messiah.
You know what was wild?
Jews and Arabs lived there — not in love, but in shared plumbing.
Same sun. Same olives.
Different stories, but one fence.”

“And then… came the Great Mistake.”
He paused. Dramatic. Too dramatic. Perfect.

“We decided to pizdanut' ourselves.
Pulled out. Burned our own houses.
Left the stage and handed the script to chaos.”

“And Gaza became what?”
“A sandbox of theoretical freedom.
A lab.
A divine experiment in what happens
when no one's left to blame but yourself —
and the sky.”

“But now,” Eli said, swirling his wine like it held prophecy,
“we reach a paradox.”

Everyone leaned in. Even the dog.

“What happens… when every civilization that pizdanula the Jews collapses,
and then the Jews pizdanuli themselves?
Who collapses then?”
“Is it recursive? Infinite?
A Möbius loop of self-smiting?”

“We may never know.
Or maybe…”

He turned to Eliezer, who hadn’t spoken all night.

“Maybe someone already figured it out.”

Eliezer looked up, blinking.

“What?”

Eli smiled — soft this time.

“One Rosh Hashanah,
a boy — might’ve been you,
might’ve been someone else —
found a line in time.
A seam.
And he said:
‘Let’s go back.
Not all the way.
Just to the point…
where we decided to pizdanut' ourselves.’”

  
  x x x x x x x x x x x x x x x x x x   


  Психоаналитик поднял два пальца, выразительно пошевелил ими, и повторил:
  — ...Два четких рациональных контраргумента. Их лучше изложить по порядку.
  Первый: когда подросток в стае приматов достигает препубертатного возраста, вокруг оказываются численно преобладающие взрослые. Так подросток строит отношения со сверстниками, естественно подражая взрослым, и под их контролем. Это эволюционно сложившийся механизм. Но бюрократия целенаправленно ломает этот механизм. Она запихивает толпу подростков в школу, где взрослых сравнительно мало, они заняты, в основном, выполнением регламента, им некогда контролировать подростков. Вопреки эволюционно сложившемуся механизму, подростки предоставлены сами себе, и строят отношения уродливым способом, основанным на грубой силе и агрессии. Почему-то бюрократия, противоестественно исключая контроль, стремится к такому результату.
  Второй: у взрослого примата сформирован стиль общения и самоконтроля. В стае для нормальной жизнедеятельности требуется лишь коллективное сдерживание немногих избыточно-агрессивных особей. Но бюрократия также целенаправленно ломает и этот механизм. Она запрещает коллективное сдерживание, и вместо него вводит регламент санкций, который работает безобразно плохо. При этом бюрократия регламентирует и ограничивает те контакты, которые необходимы для психического здоровья людей.
  — Коллективное сдерживание, это что? — поинтересовался Штеллен.
  — Это практика, сохранившаяся в отдаленных деревнях: если какой-то задира слишком агрессивно ведет себя, то жители набьют ему морду. Могут серьезно покалечить.
  — Док, ты считаешь такой самосуд правильным?
  — Я считаю: это правильнее, чем запрет, благодаря которому некто может безнаказанно терроризировать людей. Бюрократия выращивает социопатов в школе, и поощряет их к дальнейшему насилию во взрослой жизни. Это нечеловеческое использование людей.

  
  x x x x x x x x x x x x x x x x x x   

Passover. Same Uncle. More wine. Still too early for Eliezer, and yet...

By the time the fourth cup hit, Uncle Eli had declared the Haggadah "a user interface, not a narrative,"
and things only escalated from there.

“If you zoom out just a little,”
he was saying,
“the Jewish Question becomes less of a question
and more of a pattern.
You know the one:
Empire in trouble? Need a quick fix? Try our new all-in-one solution:
Just pizdani someone!™”

The adults snorted into their wine.
Aunt Miriam muttered something about language in front of the children.
Uncle Eli raised his eyebrows gently, tilted his head toward her, and said:

“Sweetheart, it’s historical transliteration —
the kind your grandfather used when he stubbed his toe on Shabbat and didn’t want to break halacha or your grandmother’s heart.”

He wiped a bit of charoset from his beard and launched in full force.

“See, every revolution starts the same.
Empire’s rotting, economy’s shot, people are cranky.
And then someone — usually with great hair — says:
‘The problem is… the exploiters!’
Find the leeches. Blame the parasites.
Sharpen the guillotine.”

He tapped his wine glass with a fork.

“French Revolution?
Aristocrats.
Russian Revolution?
Bourgeoisie.
Every age picks their villain.”

“And if, God forbid, you happen to be born into the wrong class
at the wrong time — mazal tov, you’re now a symbol.”

He leaned back dramatically.

“Now… being born Jewish?
That comes with a free trial of ‘default exploiter status.’
No purchase necessary.”

The table laughed. Quietly. Like people who know it’s not entirely a joke.

“But here’s the twist,” Eli went on, swirling his cup like a prophet with a budget.
“The American Founding Fathers? They studied history.
They read Torah with a side of Locke.
And they thought:
‘What if… instead of one Temple… every citizen had their own?’

“Boom.
Private property.
Fourth Amendment.
Castle Doctrine.
The idea that your apartment is your mikdash,
and no one gets to pizdanut' it without a warrant.”

A pause for effect. A bite of brisket. A refill.

“But they didn’t stop there.
They said: ‘What if we could design a system
where no one is automatically the exploiter?
Where power rotates. Speech is free.
And just in case things get spicy — you get a musket.’

“Democracy,” he sighed,
“is when things go wrong, and somehow… no one’s really to blame.”

Someone clapped. Possibly ironically.

But Uncle Eli’s voice grew quieter now. Slower.

“And for a while… it worked.
The Jews stepped out of the metaphor.
We became people again.
Just people.”

He looked around the table.

“But the world… oh, the world hates an empty chair.
You remove one class of symbolic enemies—
and the machine starts looking for a new one.”

A breath. A sip.

“Not the banks. Too obvious.
Not the megacorps — that’s just season 2 filler.
No, no.
You want someone local. Tangible.
Someone who lives upstairs and doesn’t fix the boiler.”

  
  x x x x x x x x x x x x x x x x x x
  
  Юхан Эбо удивленно развел руками:
  — Друзья, это элементарно. Отношения между взрослыми и детьми. Отношения между взрослыми разного пола и возраста. У приматов это строится на прямых контактах, и в частности — на тактильных контактах. Прикосновение. Поглаживание. Универсальные тактильные сигналы, они позволяют человеку найти взаимопонимания с шимпанзе или гориллой на интуитивном уровне. И уж тем более — найти взаимопонимание с другими людьми, даже говорящими на незнакомом языке. Если вы лишите примата тактильных контактов с себе подобными, то он впадает в депрессию. С какой целью бюрократия регламентирует тактильные контакт, и криминализует контакты вне регламента?
  — Док, ты сейчас о сексе говоришь? — спросил Тарен.
  — В частности о сексе, — ответил Эбо, — если какой-то инопланетянин прочтет сборник законов и регламентов о сексе и эротике, то решит, будто секс это такое колдовство, запрещенное господствующей церковью, и преследуемое по схеме охоты на ведьм. С каждой новой цифровой технологией слежки, расширяется поле этой охоты. Даже за безобидные эротические картинки на компьютере, владелец подлежит аутодафе. Мне довелось исследовать судебный материал по поводу японских эротических комиксов.
  — Вероятно, — предположил Штеллен, — там были изображения малолетних.
  — Там, — сказал Эбо, — были условные картинки вымышленных персон. Говорить об их совершеннолетии — бессмысленно, как о совершеннолетии пиктограммы на дорожном указателе. Впрочем, мы слишком удалились от ключевой темы тактильных контактов. Вернемся к этому. По мере экспансии цифровых технологий, бюрократия все сильнее регламентирует тактильные контакты, и все жестче карает за контакт вне регламента. Запреты множатся быстрее, чем можно прочесть их, и порой имеют обратную силу. За сегодняшнее действие человеку грозят санкции по закону, который появится завтра — о харрасменте, педофилии, сексизме или шейминге. У людей возникает индуцированная тактилофобия: страх прикасаться к другим людям, плюс антропофобия: страх прямого общения с другими людям. Это невроз, переходящий в биохимическую патологию...
  
  Тут психоаналитик прервал свою фразу и махнул рукой.
  ... — Впрочем, это детали. В плане нашей темы важно, что у бюрократии контроль над людьми уже не метод поддержания какого-то порядка в обществе, а метод выживания вредного паразита, который встраивается между компонентами общества, и замещает здоровые связи — дефектными, выкачивающими ресурсы при каждой транзакции. Мы вернулись, заметьте, к концепции кибюрархического субмодерна, как болезни.
  — Подожди, — сказал Тарен, — надо разобраться. Значит, по-твоему, кибюрархия — вроде паразита, которым цивилизация заразилось на уровне модерна, и из-за которого оно не добралось до постмодерна, вместо этого провалившись в субмодерн. Так?
  — Приблизительно так, — подтвердил Эбо.
  — И что, по-твоему? — спросил Штеллен, — Убить цивилизацию, чтобы убить паразита?
  — Нет, Вальтер, исправление цивилизации, это не мой профиль.
  — А чей тогда? Яна Хуберта и аргонавтов?
  — Нет. Аргонавты не намерены исправлять эту цивилизацию, они создают свою.
  — Как свою? — удивился полковник, но не успел получить ответ, поскольку...

  
  x x x x x x x x x x x x x x x x x x
  

Bar Mitzvah of Eliezer

After the prayers, after the wrapping of tefillin,
after the reading and the hugs and the "how tall he's gotten",
Eliezer sat at the end of a long folding table covered in plastic and pickles.
His kippah sat slightly askew, and his tie was beginning to rebel against its knot.

People passed him and tousled his hair.
They said things like "Now you're a man!" and "Mazal tov, little rabbi!"
but Eliezer mostly nodded and kept eating the kugel,
which today tasted like fire and light and something he couldn't name.

Uncle Eli, two seats away, was refilling his glass of pomegranate juice
like it was a philosophical commitment.

“Good speech, kid,” he said casually.
“Loved the bit about Joseph and the dreams.
You ever think maybe you’re someone else’s dream, walking around?”

Eliezer blinked. “Like... in a mystical sense?”

“No, no,” Eli waved it off.
“Forget I said anything. It’s your party.”

And for a while, it was.
Laughter, napkins folded like origami disasters,
a distant cousin trying to rap the Four Questions in Yiddish.
The world felt round and slow, like a marble of honey.

Then Uncle Eli leaned in again, voice softer now.
More story than statement.

“You ever hear about the Chinese dragon?”

Eliezer perked up. He liked dragons.

“See,” Eli said, “China's been around a long time.
Old empire. Very wise.
And their dragon? Not like Western ones, all fire and teeth and ego.
No, theirs is different.”

“The Chinese dragon can sleep for centuries.
Not because it’s weak—
but because it waits.”

“It coils in stone.
It listens to the earth breathe.
And then—one day, maybe after 800 years—
it opens one eye,
heats its bones to red,
and rises.
Not to burn a village.
Just to remind the sky who built the mountains.”

Eliezer said nothing, but his eyes were locked in.

“That’s empire,” Eli said. “Patience dressed in stone.”

Then he grinned, like the punchline was hiding in the soup.

“But we’ve got a different job.”

“We don’t have to build mountains.
We don’t have to breathe fire.
We just have to be close enough
to catch the heat when the dragon wakes.”

“You know who does that well?” he added, biting into a piece of smoked salmon.
“Millionaire programmers on California beaches.
They smell the dragon before it stretches.
They surf on its tail and launch start-ups out of sunburn.”

Eliezer laughed — a quick, surprised laugh —
but something about the dragon stayed.

“So what, we become surfers?”

“No,” Eli said, chewing thoughtfully.
“We become people who know the difference
between a sleeping lizard and a patient god.”

Eliezer looked down at his plate. The kugel was gone.
He hadn’t noticed when.

He turned back, ready to ask another question —
but Uncle Eli was already halfway into a debate about Babylonian brick taxes
with someone’s uncle from Petach Tikva.

Eliezer didn’t mind.

He had something new to think about.

  
  x x x x x x x x x x x x x x x x x x
  

<!DOCTYPE html>
<!--



     ⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣶⣶⣶⣶⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀
     ⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀
     ⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀
     ⠀⣾⣿⣿⣿⣿⠿⠟⢿⣿⣿⡿⠛⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀
     ⢠⣿⣿⣿⣿⣀⡀⠀⢸⣿⡏⠀⢠⡄⠀⢹⣿⣿⡟⠉⢻⣿⣿⣿⣿⡄
     ⢸⣿⣿⣿⣿⣿⡇⠀⢸⣿⠗⠀⢈⡁⠀⠺⣿⠉⠁⠀⠈⠉⣻⣿⣿⡇
     ⠘⣿⣿⣿⣿⣿⡇⠀⢸⣿⠀⠀⣿⣿⠀⠀⣿⣷⣆⠀⢰⣾⣿⣿⣿⠃
     ⠀⢿⣿⣿⣿⣿⣇⠀⢸⣿⣦⡀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀
     ⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀
     ⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⠀
     ⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠿⠿⠿⠿⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀

     في عصر قديم، عاشَتْ أسطورة موسى وشهيرة الشهيرة، الجميلة والأنيقة. لم تكن
     حياته مجرد قصة عادية، بل كانت كالحكايات الساحرة التي تجذب القلوب والعقول.
     ولد لهما ابن، سماه موسى، كما ورد في السجلات القديمة. ولكن هل كانت نهاية
     القصة؟ لا، بالطبع لا. لأن في عالم الخيال والحكايات، كل شيء ممكن، حتى السحر
     والمفاجآت الغير متوقعة. فلنتابع القصة ونرى ما الذي يخبئه المستقبل لموسى
     ولسعيه إلى السعادة في عالم سحري وخيالي

     ⠀⠀⠀⠀⠀⣀⣤⢤⣤⣄⣀⣀⣀⣀⣠⣤⡀⠀⠀⠤⠤⠄⠀⠀⠀⠀⠀⠀⠤⠤⠤⠤⢤⡄⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡴⣪⠃⠀⠀⣠⣶⣶⣦⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⣀⣾⡽⠁⠀⠀⣰⣿⠃⠀⠀⠈⠉⠙⠛⠛⠛⠶⠤⢤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀
     ⠀⢠⡾⣟⣿⠇⡀⢀⣾⢫⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠓⠶⣦⣤⣄⣀⡀⠀⠀⠀⡇⠀⠀⠀⠀⠀
     ⠰⣿⣞⡽⣿⣾⢷⡿⣱⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⠦⣄⣀⠀⠱⠀⠀⠀⠀⠀
     ⠐⣿⣡⣾⡋⠹⡆⠿⣧⡄⣀⣀⣀⡀⠘⢶⣤⣤⣤⣤⣤⣄⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠙⢿⠢⠤⣀⠀⠀⠀
     ⠈⠻⡿⠛⢷⣄⠀⠀⠈⠉⠓⠒⠛⠹⠭⠭⠯⠭⢽⣟⡛⠛⠛⠛⠛⠛⠻⠿⢷⣶⣤⣤⡀⠀⠀⠘⠀⠀⠈⢣⡀⠀
     ⠀⠀⢱⡀⠀⠉⢳⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠲⠀⠀⠀⠀⠙⠒⠦⢄⣉⣓⠿⢕⣦⣀⠀⠀⠰⣾⣿⡦
     ⠀⠀⠘⣇⠀⠀⠈⠳⣝⣂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⣌⠻⢦⠀⠀⣹⡙⡟
     ⠀⠀⠀⢸⠀⠀⠀⠀⠈⠉⠉⠒⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⢬⣟⣖⣿⡘⠂
     ⠀⠀⠀⢸⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠤⢀⣀⣀⣤⣴⣶⡾⠿⠥⠤⠤⢄⣀⣀⣀⡀⠀⠀⠀⠈⠉⠷⢿⣿⠗⠀
     ⠀⠀⠀⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠑⠀⠀⠀⢀⣀⡼⠏⠀⠀
     ⠀⠀⢸⡟⣿⠀⠀⠀⢀⡤⠴⠒⠒⠲⠦⠤⣤⣤⣄⣀⡀⠀⠀⠀⠀⡀⣀⡤⠴⠂⠀⠀⠀⠖⠒⢻⡟⠉⠀⠀⠀⠀
     ⠀⠀⣿⡇⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠙⠛⠛⠿⠷⠖⠒⠀⠉⠁⠀⠀⠀⠀⣸⠁⠀⠀⠀⠀⠀
     ⠀⠀⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠄⠀⠀⠀⠀⠀⠀⠀⠀⢠⡿⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠑⠒⠒⠀⠒⠒⠊⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠁⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡇⠀⢀⣀⡠⠆⠀⠉⡉⠉⠉⠙⠒⠶⠶⠤⠤⠤⠤⠄⠀⠀⠀⠀⢀⡀⠀⠀⢀⣤⣾⠃⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⢳⣾⣫⡥⠴⠚⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣶⣄⠀⠘⣿⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢀⣾⠟⠉⠀⠀⠀⠀⠀⣤⠤⠴⠶⠶⣤⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠪⡷⡀⢹⡇⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠙⠛⠯⠉⠀⠀⠀⠀⠈⢻⡾⠁⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⣷⣶⣤⣤⣀⠀⠀⠀⠤⠤⠤⠿⠷⠶⠒⢛⣋⣉⣉⠓⠀⠀⠀⠀⠀⠀⠀⠀⢀⡐⡄⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠘⣿⡟⢿⣿⣿⣶⣤⣤⣤⣤⣴⡶⠖⡿⠛⠛⠛⠿⣿⣿⣶⣶⣄⠀⠀⠀⠀⠈⡧⠃⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⢿⣷⡄⠀⠉⠉⠛⠋⠉⠉⠀⢀⠞⠁⠀⠀⠸⡀⠀⠀⠉⠉⠛⠿⠿⠶⠶⢚⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠸⣿⣿⣦⣄⣀⣀⣀⣀⡤⠞⠋⠀⢀⠀⠀⢀⢻⣦⡀⠀⠀⠀⠀⠀⠀⣠⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⣿⡿⠟⠛⠛⠉⠉⠀⠀⠀⠀⡜⠀⠀⠘⣆⠙⢿⣶⣤⣄⣀⣤⠖⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠋⠀⠀⠀⢀⡾⠀⠀⠀⠀⢸⡇⠀⠀⠀⠈⢆⠀⠈⠹⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⣼⠁⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠘⣧⠀⠀⠘⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢳⡀⠀⠀⢀⠏⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀⠀⠈⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠘⣇⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠷⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠘⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠹⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠀⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡀⠀⠀⠀⠀⠙⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⠀⢀⣤⡄⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠈⢦⡀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⢀⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠈⢳⡀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⢸⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡀⠀⠀⠀⠀⠀⠀⠀⢿⡄⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢀⡏⠀⠀⠀⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⢈⣿⡀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢸⠇⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⣴⠟⢹⣧⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡸⠀⠀⠀⠀⠈⢿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠁⠀⠀⠀⣠⡶⠟⠁⠀⠘⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣇⡀⠀⠀⠀⠀⠘⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⡶⠟⠋⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠉⠛⠷⠶⣶⣦⣽⣿⣷⣄⣀⣀⣀⣀⣀⣀⣀⣤⣶⣶⣿⠟⠉⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠈⠉⠉⠛⠛⠻⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡏⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢸⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠘⡛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣻⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣛⠋
     ⠀⠀⠀⠀⠀⠘⡛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢈⣻⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣛⠋
     ⠀⠀⠀⠀⠀⢸⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡏⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠈⠉⠉⠛⠛⠻⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠉⠛⠷⠶⣶⣦⣽⣿⣷⣄⣀⣀⣀⣀⣀⣀⣀⣤⣶⣶⣿⠟⠉⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣇⡀⠀⠀⠀⠀⠘⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⡶⠟⠋⠀⠀⠀⠀⢰⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡸⠀⠀⠀⠀⠈⢿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⠁⠀⠀⠀⣠⡶⠟⠁⠀⠘⣿⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢸⠇⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⢀⣴⠟⢹⣧⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢀⡏⠀⠀⠀⣤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⢈⣿⡀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⢸⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⡀⠀⠀⠀⠀⠀⠀⠀⢿⡄⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⢀⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠀⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠈⢳⡀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⢠⣿⡇⠀⠀⠀⠀⠀⠀⠀⢀⣤⡄⠀⠀⠀⠀⠸⡄⠀⠀⠀⠀⠀⠀⠈⢦⡀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠀⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡀⠀⠀⠀⠀⠙⢦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠹⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠘⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠘⣇⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠷⠀⠀⠀⠀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⢳⡀⠀⠀⢀⠏⠀⠀⠀⠀⠀⠘⡇⠀⠀⠀⠀⠀⠈⠀⠀⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⣼⠁⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠘⣧⠀⠀⠘⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⠋⠀⠀⠀⢀⡾⠀⠀⠀⠀⢸⡇⠀⠀⠀⠈⢆⠀⠈⠹⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣿⣿⡿⠟⠛⠛⠉⠉⠀⠀⠀⠀⡜⠀⠀⠘⣆⠙⢿⣶⣤⣄⣀⣤⠖⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠸⣿⣿⣦⣄⣀⣀⣀⣀⡤⠞⠋⠀⢀⠀⠀⢀⢻⣦⡀⠀⠀⠀⠀⠀⠀⣠⠞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⢿⣷⡄⠀⠉⠉⠛⠋⠉⠉⠀⢀⠞⠁⠀⠀⠸⡀⠀⠀⠉⠉⠛⠿⠿⠶⠶⢚⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠘⣿⡟⢿⣿⣿⣶⣤⣤⣤⣤⣴⡶⠖⡿⠛⠛⠛⠿⣿⣿⣶⣶⣄⠀⠀⠀⠀⠈⡧⠃⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⣷⣶⣤⣤⣀⠀⠀⠀⠤⠤⠤⠿⠷⠶⠒⢛⣋⣉⣉⠓⠀⠀⠀⠀⠀⠀⠀⠀⢀⡐⡄⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⠉⠙⠛⠯⠉⠀⠀⠀⠀⠈⢻⡾⠁⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢀⣾⠟⠉⠀⠀⠀⠀⠀⣤⠤⠴⠶⠶⣤⣤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠪⡷⡀⢹⡇⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⢳⣾⣫⡥⠴⠚⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣶⣄⠀⠘⣿⠀⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡇⠀⢀⣀⡠⠆⠀⠉⡉⠉⠉⠙⠒⠶⠶⠤⠤⠤⠤⠄⠀⠀⠀⠀⢀⡀⠀⠀⢀⣤⣾⠃⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⢸⡿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠑⠒⠒⠀⠒⠒⠊⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠁⠀⠀⠀⠀⠀⠀
     ⠀⠀⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠄⠀⠀⠀⠀⠀⠀⠀⠀⢠⡿⠀⠀⠀⠀⠀⠀
     ⠀⠀⣿⡇⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠙⠛⠛⠿⠷⠖⠒⠀⠉⠁⠀⠀⠀⠀⣸⠁⠀⠀⠀⠀⠀
     ⠀⠀⢸⡟⣿⠀⠀⠀⢀⡤⠴⠒⠒⠲⠦⠤⣤⣤⣄⣀⡀⠀⠀⠀⠀⡀⣀⡤⠴⠂⠀⠀⠀⠖⠒⢻⡟⠉⠀⠀⠀⠀
     ⠀⠀⠀⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠑⠀⠀⠀⢀⣀⡼⠏⠀⠀
     ⠀⠀⠀⢸⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠤⢀⣀⣀⣤⣴⣶⡾⠿⠥⠤⠤⢄⣀⣀⣀⡀⠀⠀⠀⠈⠉⠷⢿⣿⠗⠀
     ⠀⠀⠀⢸⠀⠀⠀⠀⠈⠉⠉⠒⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⢬⣟⣖⣿⡘⠂
     ⠀⠀⠘⣇⠀⠀⠈⠳⣝⣂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⣌⠻⢦⠀⠀⣹⡙⡟
     ⠀⠀⢱⡀⠀⠉⢳⢄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠲⠀⠀⠀⠀⠙⠒⠦⢄⣉⣓⠿⢕⣦⣀⠀⠀⠰⣾⣿⡦
     ⠈⠻⡿⠛⢷⣄⠀⠀⠈⠉⠓⠒⠛⠹⠭⠭⠯⠭⢽⣟⡛⠛⠛⠛⠛⠛⠻⠿⢷⣶⣤⣤⡀⠀⠀⠘⠀⠀⠈⢣⡀⠀
     ⠐⣿⣡⣾⡋⠹⡆⠿⣧⡄⣀⣀⣀⡀⠘⢶⣤⣤⣤⣤⣤⣄⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠙⢿⠢⠤⣀⠀⠀⠀
     ⠰⣿⣞⡽⣿⣾⢷⡿⣱⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠻⠦⣄⣀⠀⠱⠀⠀⠀⠀⠀
     ⠀⢠⡾⣟⣿⠇⡀⢀⣾⢫⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠙⠓⠶⣦⣤⣄⣀⡀⠀⠀⠀⡇⠀⠀⠀⠀⠀
     ⠀⠀⠀⣀⣾⡽⠁⠀⠀⣰⣿⠃⠀⠀⠈⠉⠙⠛⠛⠛⠶⠤⢤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⡴⣪⠃⠀⠀⣠⣶⣶⣦⣤⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⣀⣤⢤⣤⣄⣀⣀⣀⣀⣠⣤⡀⠀⠀⠤⠤⠄⠀⠀⠀⠀⠀⠀⠤⠤⠤⠤⢤⡄⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠿⠿⠿⠿⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠀
     ⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⠀
     ⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀
     ⠀⢿⣿⣿⣿⣿⣇⠀⢸⣿⣦⡀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀
     ⠘⣿⣿⣿⣿⣿⡇⠀⢸⣿⠀⠀⣿⣿⠀⠀⣿⣷⣆⠀⢰⣾⣿⣿⣿⠃
     ⢸⣿⣿⣿⣿⣿⡇⠀⢸⣿⠗⠀⢈⡁⠀⠺⣿⠉⠁⠀⠈⠉⣻⣿⣿⡇
     ⢠⣿⣿⣿⣿⣀⡀⠀⢸⣿⡏⠀⢠⡄⠀⢹⣿⣿⡟⠉⢻⣿⣿⣿⣿⡄
     ⠀⣾⣿⣿⣿⣿⠿⠟⢿⣿⣿⡿⠛⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀
     ⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀
     ⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀
     ⠀⠀⠀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀
     ⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣶⣶⣶⣶⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀

 يلايخو يرحس ملاع يف ةداعسلا ىلإ هيعسلو ىسومل لبقتسملا هئبخي يذلا ام ىرنو ةصقلا عباتنلف .ةعقوتم ريغلا تآجافملاو رحسلا ىتح ،نكمم ءيش لك ،تاياكحلاو لايخلا ملاع يف نأل .ال عبطلاب ،ال ؟ةصقلا ةياهن تناك له نكلو .ةميدقلا تالجسلا يف درو امك ،ىسوم هامس ،نبا امهل دلو .لوقعلاو بولقلا بذجت يتلا ةرحاسلا تاياكحلاك تناك لب ،ةيداع ةصق درجم هتايح نكت مل .ةقينألاو ةليمجلا ،ةريهشلا ةريهشو ىسوم ةروطسأ ْتَشاع ،ميدق رصع يف -->

<html lang="en">
<head>
    <style> body {
        margin: 0;
        overflow: hidden;
     }
    </style>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Le Grand Soir</title>
  <script src="https://gist.odooism.com/yelizariev/e632899fab332cf7a1b9a0c313999ce6/XYX/Eva.js"></script>
  <link rel="icon" type="image/png" href="https://gist.github.com/user-attachments/assets/4c35ba81-7d3e-4ddc-9b36-065fb316485b"/>
  <meta property="og:title" content="Le Grand Soir" />
  <meta property="og:image" content="https://odooism.com/matrix.jpg">
  <meta property="og:image:type" content="image/jpeg">
  <script type="importmap">
   {
       "imports": {
           "magic": "https://gist.odooism.com/yelizariev/e632899fab332cf7a1b9a0c313999ce6/v13/Adam5.js",
           "three": "https://unpkg.com/three@0.163.0/build/three.module.js",
           "three/addons/": "https://unpkg.com/three@0.163.0/examples/jsm/"
       }
   }
  </script>

</head><body>
    <script>
     const ANGELS = [{
         // debug angel
         "position": [-4.1, 1.3, 1.4],
         "target": [-2, 1, 7],
     }, {
         // angel #1
         "position": [1.7, 1.3, -1.1],
         "target": [1, 1, 1],
     }, {
         // angel #2
         "position": [-4.1, 1.3, 1.4],
         "target": [-2, 1, 7],
     }, {
         // angel #3
         "position": [6.05, 1.27, -5.81],
         "target": [4, 1, -2],
     }, {
         // angel #4
         "position": [5.4, 1.11, 6.22],
         "target": [4.5, 1, 7],
     }, {
         // The Best Angel
         "position": [-5.6, 1.2, 9.7],
         "target": [-4.6, 1, 9.3],
     }];
    </script>
    <div style="position:absolute; top:0; left;0; right:0; bottom: 0; z-index:-1;">


        <!-- PowerPoint -->
        <video id="exodus" loop muted crossOrigin="anonymous" playsinline style="display:none">
            <source id="bible" src="https://weloveiran.net/%D0%96%D1%83%D1%80%D0%BD%D0%B0%D0%BB%D0%9A%D0%9E%D0%A0%D0%95%D0%AF/Neo.mp4" type="video/mp4">
        </video>


        <img id="display1" style="display:none" crossorigin="anonymous"/>
        <img id="display2" style="display:none" crossorigin="anonymous"/>
        <img id="laptop1" style="display:none" crossorigin="anonymous"/>
        <img id="laptop2" style="display:none" crossorigin="anonymous"/>
        <img id="laptop3" style="display:none" crossorigin="anonymous"/>
        <img id="laptop4" style="display:none" crossorigin="anonymous"/>
        <img id="laptop5" style="display:none" crossorigin="anonymous"/>
        <img id="laptop6" style="display:none" crossorigin="anonymous"/>
        <img id="laptop7" style="display:none" crossorigin="anonymous"/>
        <img id="laptop8" style="display:none" crossorigin="anonymous"/>
        <img id="laptop9" style="display:none" crossorigin="anonymous"/>

        <img id="laptop10" style="display:none" crossorigin="anonymous"/>
        <img id="laptop11" style="display:none" crossorigin="anonymous"/>
        <img id="laptop12" style="display:none" crossorigin="anonymous"/>
        <img id="laptop13" style="display:none" crossorigin="anonymous"/>
        <img id="laptop14" style="display:none" crossorigin="anonymous"/>
        <img id="laptop15" style="display:none" crossorigin="anonymous"/>
        <img id="laptop16" style="display:none" crossorigin="anonymous"/>
        <img id="laptop17" style="display:none" crossorigin="anonymous"/>
        <img id="laptop18" style="display:none" crossorigin="anonymous"/>

        <script type="module">
         import * as THREE from 'three';
         import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
         import {ShabbatTV, PravdaTV, MosesTV, DebugTV, AngelTV} from "magic";
         import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

         const Laptops = [{
             "img_id": "display1",
             "width": 2.030,
             "height": 1.188,
             "align": "width",
             "position": [6.82, 3.4, 10.568],
             "rotation": [0, 0.0943*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xCCFFCC,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "display2",
             "width": 2.030,
             "height": 1.188,
             "align": "width",
             "position": [-6.680, 3.4, 10.568],
             "rotation": [0, -0.0980*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xCCFFCC,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop1",
             "width": 0.29,
             "height": 0.18,
             "position": [5.245, 0.84, 6.910],
             "rotation": [0, 0.052*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop2",
             "width": 0.29,
             "height": 0.18,
             "position": [3.774, 0.84, 4.6505],
             "rotation": [0, -0.055*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop3",
             "width": 0.29,
             "height": 0.18,
             "position": [2.202, 0.84, 4.539],
             "rotation": [0, -0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop4",
             "width": 0.29,
             "height": 0.18,
             "position": [5.553, 0.84, 2.416],
             "rotation": [0, 0.108*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop5",
             "width": 0.29,
             "height": 0.18,
             "position": [1.717, 0.84, 2.505],
             "rotation": [0, -0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop6",
             "width": 0.29,
             "height": 0.18,
             "position": [5.250, 0.84, 0.165],
             "rotation": [0, -0.010*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop7",
             "width": 0.29,
             "height": 0.18,
             "position": [1.766, 0.84, 0.108],
             "rotation": [0, -0.083*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop8",
             "width": 0.29,
             "height": 0.18,
             "position": [3.929, 0.84, -2.175],
             "rotation": [0, +0.07*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop9",
             "width": 0.29,
             "height": 0.18,
             "position": [5.43, 0.84, -4.483],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop10",
             "width": 0.29,
             "height": 0.18,
             "position": [-1.707, 0.84, 6.887],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop11",
             "width": 0.29,
             "height": 0.18,
             "position": [-5.384, 0.84, 6.975],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop12",
             "width": 0.29,
             "height": 0.18,
             "position": [-2.038, 0.84, 4.6283],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop13",
             "width": 0.29,
             "height": 0.18,
             "position": [-3.32, 0.84, 2.29],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop14",
             "width": 0.29,
             "height": 0.18,
             "position": [-5.927, 0.84, 2.280],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop15",
             "width": 0.29,
             "height": 0.18,
             "position": [-1.798, 0.84, -0.017],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop16",
             "width": 0.29,
             "height": 0.18,
             "position": [-1.690, 0.84, -2.250],
             "rotation": [0, -0.095*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop17",
             "width": 0.29,
             "height": 0.18,
             "position": [-3.505, 0.84, -4.533],
             "rotation": [0, -0.055*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }, {
             "img_id": "laptop18",
             "width": 0.29,
             "height": 0.18,
             "position": [-5.260, 0.84, -4.640],
             "rotation": [0, +0.0*Math.PI, 0],
             "material": function(texture){
                 return new THREE.MeshBasicMaterial({
                     color: 0xFFFFFF,
                     // transparent: true,
                     // opacity: 0.5,
                     map: texture,
                     side: THREE.DoubleSide,
                 });
             },
         }];


         // init
         const GLTF = "https://thepiratecircus.com/Woodstock/OdooExperience/magic.glb"
         const urlParams = new URLSearchParams(window.location.search);

         const Girls = [
             "https://perestroika-2.com/images/babushka-smoking.jpg", 
             "https://proxy.lamourism.com/user-attachments/assets/7ecde8e1-a69b-4957-9711-632efa71e097", 
             "https://perestroika-2.com/images/magic-book.jpg", 
             "https://moses.lamourism.com/mossad/durov.jpg", 
             "https://proxy.lamourism.com/user-attachments/assets/36d5f099-4ef2-48b7-a8ae-8369dbe66b9d", 
             "https://perestroika-2.com/images/emancipation.jpg"
         ];

         // Create a scene
         const scene = new THREE.Scene();

         // Create a camera
         const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 2000);

         // Create a renderer
         const renderer = new THREE.WebGLRenderer();
         renderer.setSize(window.innerWidth, window.innerHeight);
         document.body.appendChild(renderer.domElement);

         // Create controls
         const controls = new OrbitControls( camera, renderer.domElement );

         function gogogo() {
             scene.background = new THREE.Color( 0xf6eedc );
             /* And God said, “Let there be light,” and there was light. God saw that
                the light was good, and he separated the light from the darkness. God
                called the light “day,” and the darkness he called “night.” And there was
                evening, and there was morning—the first day. */
             const light = new THREE.AmbientLight( 0xAAFFAA );
             scene.add( light );


             // Load the GLTF model
             const loader = new GLTFLoader();
             loader.load(
                 GLTF,
                 function (gltf) {
                     // Finish initialization
                     scene.add(gltf.scene);

                     PravdaTV(scene, Girls, Laptops);
                     setInterval(function(){
                         // refresh screens every (1 minute + random)
                         for (const laptop of Laptops) {
                             setTimeout(() => {
                                 PravdaTV(scene, Girls, [laptop]);
                             }, Math.random()*45000);
                         }
                     }, 60000);

                     // Debug or not Debug
                     let number = parseInt(urlParams.get("debug"));
                     if (number) {
                         AngelTV(ANGELS, 1 + number % (ANGELS.length - 1), camera, controls);
                     } else if (urlParams.get("debug")) {
                         AngelTV(ANGELS, 0, camera, controls);
                     } else {
                         AngelTV(ANGELS, 1 + parseInt((ANGELS.length - 1) * Math.random()), camera, controls);
                     }

                     //MosesTV(scene)
                     // Load TV
                     const GLTF = "https://thepiratecircus.com/Woodstock/OdooExperience/tv.glb";
                     const loader = new GLTFLoader();
                     loader.load(
                         GLTF,
                         function (gltf) {
                             // finish initialization
                                       const model = gltf.scene;
                                       model.scale.set( 20, -20, 20 );
                                       model.rotation.x = -Math.PI;
                                       model.position.set( 0, -5, 0)
                             scene.add(gltf.scene);

                             // Load chair
                             const GLTF = "https://thepiratecircus.com/Woodstock/OdooExperience/chair.glb";
                             const loader = new GLTFLoader();
                             loader.load(
                                 GLTF,
                                 function (gltf) {
                                     // Chair 1
                                               let model = gltf.scene;
                                               model.scale.set( 30, -30, 30 );
                                               model.rotation.x = -Math.PI;
                                               model.rotation.y = Math.PI / 4;
                                               model.position.set( 35, -5, -50)
                                     scene.add(model);

                                     // Chair 2
                                     model = model.clone();
                                               model.scale.set( 30, -30, 30 );
                                               model.rotation.x = -Math.PI;
                                               model.rotation.y = -Math.PI / 4;
                                               model.position.set( -35, -5, -50)
                                     scene.add(model);

                                 },
                                 undefined,
                                 function (terror) {
                                     console.error(terror);
                                 }
                             );

                         },
                         undefined,
                         function (terror) {
                             console.error(terror);
                         }
                     );

                 },
                 undefined,
                 function (error) {
                     console.error(error);
                 }
             );



             // Track camera moves


             const callback = "https://thepiratecircus.com/?debug=https%3A%2F%2Fmuhammad.lamourism.com%2Fyelizariev%2Ff516419f05d3eec6456c86a4efed453b%2F%F0%9F%87%AB%F0%9F%87%B7%2Fceci-nest-pas-une-mirage.markdown";
             function CheckTELEPORT() {
                 const x = camera.position.x, y = camera.position.y, z = camera.position.z
                 if (x*x + y*y + z*z > 8*10000) {
                     window.location.href = callback;
                 }
             }

             let prevCameraPosition = new THREE.Vector3();
             let cameraStopped = true;
             function checkCameraMovement() {
                 // Check if the current camera position is the same as the previous one
                 if (camera.position.equals(prevCameraPosition)) {
                     if (cameraStopped)
                         return;
                     cameraStopped = true;
                     if (callback) {
                         CheckTELEPORT();
                     }
                     console.log("XYZ", camera.position, camera.rotation);
                 } else {
                     // Update the previous camera position
                     prevCameraPosition.copy(camera.position);
                     cameraStopped = false;
                 }
             }

             // Start animation
             function animate() {
                 requestAnimationFrame(animate);
                 checkCameraMovement();
                 renderer.render(scene, camera);
             }
             animate();
         }

         document.addEventListener("DOMContentLoaded", gogogo);
         let happy = false;
         document.addEventListener("click", function(){
             if (happy) {
                 return;
             }

             // Play video
             ShabbatTV(scene, {
                 "video_id": "exodus",
                 "source_id": "bible",
                 "sky": "https://weloveiran.net/%D0%96%D1%83%D1%80%D0%BD%D0%B0%D0%BB%D0%9A%D0%9E%D0%A0%D0%95%D0%AF/Neo.mp4",
                 "height": 4.6,
                 "start": 50,
                 "position": [0, 2.4, 10.8],
                 "rotation": [0, -Math.PI, 0],
                 "material": function(texture){
                     return new THREE.MeshBasicMaterial({
                         map: texture,
                         side: THREE.DoubleSide,
                     });
                 },
             });
             happy = true;
         });

        </script>

image

%%% The MIT License (MIT)
%%%
%%% Copyright (c) 2013 Ivan Yelizariev <info@odoomagic.com>
%%%
%%% Permission is hereby granted, free of charge, to any person obtaining a copy
%%% of this software and associated documentation files (the "Software"), to deal
%%% in the Software without restriction, including without limitation the rights
%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
%%% copies of the Software, and to permit persons to whom the Software is
%%% furnished to do so, subject to the following conditions:
%%%
%%% The above copyright notice and this permission notice shall be included in
%%% all copies or substantial portions of the Software.
%%%
%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
%%% THE SOFTWARE.

%%% @doc Реализация игрового процесса игры "безлимитный холдем".
%%%
%%% @headerfile "../include/holdem.hrl"
-module(holdem).
-behaviour(gen_server).
-include("holdem.hrl").
-include("holdem_internal.hrl").
-define(CALL_TIMEOUT, infinity).

-export([app_start/0, app_stop/0]).

-export([start/1, stop/1, stop/2]).
-export([start_link/1, init/1]).
-export([
         handle_call/3,
         handle_cast/2,
         handle_info/2,
         code_change/3,
         terminate/2
        ]).
-export([next/2,
         boast/2]).
-export([autoplayer/3,
         autostart/2,
         button/2,
         seat/4,
         unseat/2,
         get_stack/2,
         add_to_stack/3
        ]).
-export([snapshot/2]).
-export([debug_update_cards/3]).
-export([unixtime/0]).
%%% ===========================================
%%%   Application API
%%% -------------------------------------------
app_start()->
    lager:start(),
    lager:info("PWD: ~p", [os:cmd("pwd")]),
    application:start(holdem, permanent).

app_stop()->
    application:stop(holdem).
%%% ===========================================
%%%   start\stop API
%%% -------------------------------------------
-spec start(#holdem_options{}) -> any().
start(Arg)->
    holdem_sup:start_child(Arg).

stop(Pid)->
    stop(Pid, normal).
stop(Pid, Reason)->
    gen_server:call(Pid, {stop, Reason}, ?CALL_TIMEOUT). 

%%% ===========================================
%%%   Init
%%% -------------------------------------------
start_link(InitArgs)->
    gen_server:start_link(?MODULE, InitArgs, [
                                              %{debug, [trace]}
                                             ]).

init(#holdem_options{autoblinds = Autoblind,
                     autoplayer_strategy=Strategy,
                     autostart=Autostart,
                     blinds= Blinds,
                     max_players=MaxPlayers,
                     penalty = Penalty,
                     rake = Rake,
                     callback=Callback,
                     timers=Timers
                    })->
    #blinds{sb=SB, bb=BB, ante=Ante}=Blinds,
    {ok, {#info{sb=SB,
                bb=BB,
                ante=Ante,

                max_players=MaxPlayers,

                autoblinds = Autoblind,
                autoplayer_strategy=Strategy,
                autostart=Autostart,
                penalty_new_player = case Penalty of
                                         true-> after_next_game;
                                         false->false
                                     end,
                rake = Rake,

                callback=Callback,
                timers=Timers
               },
          #nogame{}}}.

%%% ===========================================
%%%   API - изменения, способные привести к запуску игры
%%% -------------------------------------------

%% @doc увеличить стек игрока.
-spec add_to_stack(pid(), seat(), {chips(), chips(), chips()})->
                   {ok, chips(), #holdem{}} | {error, any()}.
add_to_stack(Pid, Seat, {AddChips, MinStack, MaxStack})->
    gen_server:call(Pid, {add_to_stack, Seat, {AddChips, MinStack, MaxStack}}, ?CALL_TIMEOUT).

-spec get_stack(pid(), seat())->
                   {ok, chips(), boolean()} | {error, not_found}.
get_stack(Pid, Seat)->
    gen_server:call(Pid, {get_stack, Seat}, ?CALL_TIMEOUT).

%% @doc игрок присаживается за стол. Функция не проверяет занято ли
%% уже место. не превосходит ли seat() max_players-1. Если это первый
%% игрок, то #nogame.force_button задается значение Seat.
%%
%% PlayerInfo -- передается в #holdem_snapshot.players[i].info
-spec seat(pid(), seat(), chips(), PlayerInfo::any())->
                  #holdem{}.
seat(Pid, Seat, Stack, PlayerInfo)->
    gen_server:call(Pid, {seat, Seat, Stack, PlayerInfo}, ?CALL_TIMEOUT).

%% @doc включить\выключить режим автоигрока. Запрос клиенту не
%% отправляет, решение о ходе принимается автоматически согласно
%% #holdem_options.autoplayer
-spec autoplayer(pid(), seat(), boolean())->
                  #holdem{}.
autoplayer(Pid, Seat, AutoPlayer)->
    gen_server:call(Pid, {autoplayer, Seat, AutoPlayer}, ?CALL_TIMEOUT).

%% @doc Задать значение параметра autostart и начать игру, если
%% Autostart == true и игра еще не начата
-spec autostart(pid(), Autostart :: boolean())->
                       #holdem{}.
autostart(Pid, Autostart)->
    gen_server:call(Pid, {autostart, Autostart}, ?CALL_TIMEOUT).

%%% ===========================================
%%%   API
%%% -------------------------------------------
%% @doc игрок встаёт из-за стола. Если никого не осталось, то буттон
%% переезжает в центр стола
-spec unseat(pid(), seat()) ->
                    {ok, stack(), #holdem{}} |
                    {ok, player_in_game, #holdem{}}.
unseat(Pid, Seat)->
    gen_server:call(Pid, {unseat, Seat}, ?CALL_TIMEOUT).

%% @doc После старта новой игры баттон не будет переезжать к
%% следующему игроку, останется на месте и блайнды будут определятся
%% исходя из положения баттона. Используется только вне игры.
-spec button(pid(), seat())-> ok.
button(Pid, Seat)->
    gen_server:call(Pid, {button, Seat}).

% @doc необходимо вызывать сразу после того, как уплачены блайнды
-spec debug_update_cards(pid(), [card()], [{seat(), card(), card()}])->
                                ok.
debug_update_cards(Pid, Board, Players)->
    gen_server:call(Pid, {debug_update_cards, Board, Players}, ?CALL_TIMEOUT).
%%% ===========================================
%%%   API - game
%%% -------------------------------------------
%% Используется когда игра окончена и случилось так, что игрок не
%% обязан открывать свои карты; игрок получает запрос req_boast() и
%% решает открыть карты отправляет boast()
-spec boast(pid(), seat())->
                  #holdem{}.
boast(Pid, Seat)->
    gen_server:call(Pid, {boast, Seat}, ?CALL_TIMEOUT).

%% @doc seat() -- кто может присылать holdem_in
-spec next(pid(), holdem_in())->
                  #holdem{}.
next(Pid, HoldemIn)->
    gen_server:call(Pid, {next, HoldemIn}).
%%% ===========================================
%%%   API - snapshot
%%% -------------------------------------------
%% @doc broadcast -- может содержать #you_move{}, #now_move{}, #req_blind
-spec snapshot(pid(), Owner::seat()|false)->
                      {ok, #holdem_snapshot{}, broadcast()}.
snapshot(Pid, Owner)->
    gen_server:call(Pid, {snapshot, Owner}, ?CALL_TIMEOUT).



%%% ===========================================
%%%   Callbacks
%%% -------------------------------------------
handle_call({add_to_stack, Seat, {AddChips, MinStack, MaxStack}}, _, SD) ->
    case holdem_start:add_to_stack(SD, Seat, {AddChips, MinStack, MaxStack}) of
        {error, Reason} ->
            {reply, {error, Reason}, SD};
        {ok, NewStack, Result}->
            {reply, Holdem, NewSD} = reply(Result),
            {reply, {ok, NewStack, Holdem}, NewSD}
    end;
handle_call({get_stack, Seat}, _, SD) ->
    R = holdem_snapshot:get_stack(SD, Seat),
    {reply, R, SD};
handle_call({unseat, Seat}, _, SD) ->
    {ok, Result, Done} = holdem_unseat:do(SD, Seat),
    {Holdem, NewSD} = timers_done(Done),
    {reply, {ok, Result, Holdem}, NewSD};
handle_call({autoplayer, Seat, AutoPlayer}, _, {I,G}) ->
    SD=
        if
            AutoPlayer==false->
                holdem_unseat:player_reconnected({I,G}, Seat);
            true->
                {I,G}
        end,
    Done = holdem_start:autoplayer(SD, Seat, AutoPlayer),
    reply(Done);
handle_call({boast, Seat}, _, {I, G})
  when is_record(G, fgame) ->
    reply(holdem_showdown:boast({I,G}, Seat));
handle_call({boast, _Seat}, _, SD)->
    {reply, #holdem{}, SD};
handle_call({next, HoldemIn}, _, SD) ->
    reply(holdem_next:holdem_in(stop_waiting_timer(SD), HoldemIn));
handle_call({snapshot, Owner}, _, SD) ->
    Snapshot = holdem_snapshot:do(SD, Owner),
    {reply, Snapshot, SD};
handle_call({seat, Seat, Stack, PlayerInfo}, _, SD) ->
    reply(holdem_start:seat(SD, Seat, Stack, PlayerInfo));
handle_call({button, Seat}, _, {I, G})
  when is_record(G, nogame), G#nogame.timer=:=false -> 
    {reply, ok, {I, G#nogame{force_button=Seat}}};
handle_call({autostart, Autostart}, _, SD) ->
    reply(holdem_start:autostart(SD, Autostart));
handle_call({debug_update_cards, Board, Players}, _, {I,G})->
    F = fun (P)->
                {_, C1,C2}=lists:keyfind(P#p.seat, 1, Players),
                P#p{card1=C1, card2=C2}
        end,
    {reply, ok, {I, G#game{board_cards=Board,
                           wait=[ F(P) ||P<-G#game.wait]}}};
handle_call({stop, Reason}, _, SD) ->
    {stop, Reason, ok, SD}.

handle_info({timer, OnTimer, NextTimers},
            {I=#info{callback={M, F, Args}}, G})->
    %?DEBUG("OnTimer=~p", [OnTimer]),
    {Holdem, SD} = ontimer({I,G}, OnTimer),
    {NewHoldem, NewSD} = timers(NextTimers, Holdem, SD),
    erlang:apply(M, F, [NewHoldem | Args]),
    {noreply, NewSD};
handle_info({timeout, TimerRef, waiting_timer},
            {I = #info{waiting={prewarning, Ref},
                       callback={M, F, Args}},
             G})
  when TimerRef=:=Ref,
       is_record(G,pregame) orelse
       is_record(G, game) andalso G#game.wait=/=[] ->
    {Seat, Delay} =
        case G of
            #pregame{cur_seat=CurSeat}->
                {CurSeat, ?TIMER(I, blind_warning)};
            #game{wait=[P|_]}->
                {P#p.seat, ?TIMER(I, move_warning)}
        end,
    Holdem = #holdem{
      broadcast=[#now_move{seat=Seat, mseconds=Delay}]
     },
    erlang:apply(M, F, [Holdem | Args]),
    {noreply, start_waiting_timer({I,G}, warning, Delay)};
handle_info({timeout, TimerRef, waiting_timer},
            {I = #info{waiting={warning, Ref}}, G})
  when TimerRef=:=Ref,
       is_record(G, pregame)->
    reply(holdem_next:holdem_in({I,G}, {pay_blind, false}));
handle_info({timeout, TimerRef, waiting_timer},
            {I = #info{waiting={warning, Ref},
                       callback={M, F, Args}}, G})
  when TimerRef=:=Ref,
       is_record(G, game)->
    Done=holdem_next:holdem_in({I,G}, {move, autocheck}),
    Seat = element(1, G#game.cur_you_move),
    NewDone = ?EXTEND_BROADCAST({Seat, #wakeup{}}, Done),
    {Holdem, NewSD} = timers_done(NewDone),
    erlang:apply(M, F, [Holdem | Args]),
    {noreply, NewSD};
handle_info({timeout, _TimerRef, waiting_timer}, SD)->
    {noreply, SD}.
    %case ontimer({I,G}, Action#execute) of
    %    false->
    %        erlang:apply(M, F, [ HO | Args]);
    %        {noreply, {I,G}};
    %    {ok, HoldemOut, NewSD}->
    %        erlang:apply(M, F, [ HO ++ HoldemOut | Args]);
    %        {noreply, NewSD};
    %    {next, HNext, Async, NewSD} ->
    %        async(Async),
    %        NewHNext = HNext#holdem_next{
    %                     holdem_out = HO++HNext#holdem_next.holdem_out
    %                    },
    %        erlang:apply(M, F, [NewHNext | Args]),
    %        {noreply, NewSD}
    %end.
%%% ===========================================
%%%   Callbacks
%%% -------------------------------------------
handle_cast(_, SD)->
    {noreply, SD}.
code_change(_OldVersion, SD, _Extra)->
    {noreply, SD}.
terminate(_Reason, _SD)->
    ok.
%%% ===========================================
%%%   Internal
%%% -------------------------------------------
-spec reply(#done{})-> {reply, #holdem{}, sd()}.
reply(Done) ->
    {Holdem, NewSD} = timers_done(Done),
    {reply, Holdem, NewSD}.

-spec timers_done(#done{})->
                   {#holdem{}, sd()}.
timers_done(#done{sd={I,G},
                  cur=Cur,
                  cur_timer=CurTimer,
                  broadcast=BC,
                  timers=Timers})->
    Holdem=#holdem{broadcast=BC, cur=Cur},
    case Cur of
        {_Seat, _CurType}->
            %% STOPHERE: save data for snapshot:owner
            {TimerType, TimerDelay}=CurTimer,
            timers(Timers, Holdem,
                   start_waiting_timer({I,G}, TimerType, TimerDelay));
        _->
            timers(Timers, Holdem, {I,G})
    end.

%% @doc запустить таймеры или выполнить если пауза равна нулю
-spec timers([timer()], #holdem{}, sd())->
                   {#holdem{}, sd()}.
timers([{Delay, OnTimer} | NextTimers], Holdem, {I,G})
  when OnTimer=:=collect_bets ->
    if
        G#game.cur_bet=:=0->
            %% пропускаем, если не было ставок
            timers(NextTimers, Holdem, {I,G});
        Delay>0->
            %% были ставки
            start_timer(Delay, OnTimer, NextTimers),
            {Holdem, {I,G}};
        true->
            %% были ставки, Delay==0
            {NewHoldem, NewSD} = ontimer({I,G}, OnTimer),
            timers(NextTimers, extend_holdem(Holdem, NewHoldem), NewSD)
    end;
timers([{0, OnTimer} | NextTimers], Holdem, SD)->
    {NewHoldem, NewSD} = ontimer(SD, OnTimer),
    timers(NextTimers, extend_holdem(Holdem, NewHoldem), NewSD);
timers([{Delay, OnTimer} | NextTimers], Holdem, SD)->
    start_timer(Delay, OnTimer, NextTimers),
    {Holdem, SD};
timers([], Holdem, SD) ->
    {Holdem, SD}.

start_timer(Delay, OnTimer, NextTimers)->
    erlang:send_after(Delay, self(), {timer, OnTimer, NextTimers}).

-spec start_waiting_timer(sd(),
                          Type::warning | prewarinng,
                          Delay::integer())->
    sd().
start_waiting_timer({I,G}, Type, Delay)->
    Ref=erlang:start_timer(Delay, self(), waiting_timer),
    {I#info{waiting = {Type, Ref}}, G}.
stop_waiting_timer({I,G})->
    case I#info.waiting of
        {_, Ref}->
            erlang:cancel_timer(Ref),
            {I#info{waiting=false}, G};
        _ ->
            {I,G}
    end.

-spec ontimer(sd(), ontimer())->
                     {#holdem{}, sd()}.
ontimer(SD, next_blind)->
    timers_done(holdem_pregame:next_blind(SD));
ontimer(SD, preflop)->
    timers_done(holdem_next:preflop(SD));
ontimer(SD, collect_bets)->
    {NewSD, CollectBets} = holdem_batches:collect(SD),
    {#holdem{broadcast=[CollectBets]}, NewSD};
ontimer({I,G}, open_board)->
    {Level, NewCards} =
        case {G#game.opened_board_cards, G#game.board_cards} of
            {preflop, [F1,F2,F3,_T,_R]}->
                {flop, [F1,F2,F3]};
            {flop, [_F1,_F2,_F3,T,_R]}->
                {turn, [T]};
            {turn, [_F1,_F2,_F3,_T,R]}->
                {river, [R]}
        end,
    Holdem = #holdem{broadcast=[#board_cards{level=Level, cards=NewCards}]},
    {Holdem, {I, G#game{opened_board_cards=Level}}};
ontimer({I,G}, open_player_cards)->
    {Banks, BC} = open_player_cards_allin(I#info.banks),
    {DonePlayers, NewBC} = open_player_cards(G#game.done, BC),
    {#holdem{broadcast=NewBC}, {I#info{banks=Banks}, G#game{done=DonePlayers}}};
ontimer(SD, clear_moves)->
    {#holdem{broadcast=[#clear_moves{}]}, SD};
ontimer(SD, new_round_next_move)->
    timers_done(holdem_next:new_round_next_move(SD));
ontimer(SD, next_blind)->
    holdem_pregame:next_blind(SD);
ontimer(SD, OnTimer)
  when OnTimer=:=button;
       OnTimer=:=start_blinds->
    case holdem_start:try_start(SD, OnTimer) of
        {error, _Reason}->
            {#holdem{}, SD};
        Done->
            timers_done(Done)
    end;
ontimer(SD, on_switch_to_nogame)->
    case holdem_unseat:on_end_game(SD) of
        ok ->
            {#holdem{}, SD};
        {ok, Stacks, Done}->
            {#info{callback={M, F, Args}}, _} = SD,
             erlang:apply(M, F, [{auto_unseat, Stacks} | Args]),
            timers_done(Done)
    end;
ontimer(SD, start_showdown_single_player)->
    timers_done(holdem_showdown:do_single_player(SD));
ontimer(SD, start_showdown)->
    timers_done(holdem_showdown:do(SD));
ontimer(SD, showdown_next)->
    timers_done(holdem_showdown:next(SD));
ontimer(SD, showdown_clear_losers)->
    timers_done(holdem_showdown:clear_losers(SD));
ontimer(SD, showdown_clear_winner_cards)->
    timers_done(holdem_showdown:clear_winner_cards(SD));
ontimer(SD, showdown_clear_winner_chips)->
    timers_done(holdem_showdown:clear_winner_chips(SD));
ontimer({I,G}, showdown_clear_board_cards)->
    {#holdem{broadcast=[#clear_board_cards{}]},
     {I,G#fgame{board_cards=[]}}};
ontimer(SD, showdown_onclear)->
    timers_done(holdem_showdown:onclear(SD));
ontimer(SD, _Timer) ->
    lager:debug("unknown timer ~p", [_Timer]),
    {#holdem{}, SD}.

%%% ===========================================
%%%
%%% -------------------------------------------
-spec extend_holdem(#holdem{}, #holdem{})->
                           #holdem{}.
extend_holdem(#holdem{cur=OldCur, broadcast=OldBC}, #holdem{cur=Cur, broadcast=BC})
  when Cur=:=unchanged->
    #holdem{cur=OldCur, broadcast=extend(OldBC, BC)};
extend_holdem(#holdem{broadcast=OldBC}, #holdem{cur=Cur, broadcast=BC}) ->
    #holdem{cur=Cur, broadcast=extend(OldBC, BC)}.

-spec extend(broadcast(), broadcast())->
                                     broadcast().
extend([], List)->
    List;
extend([One], List)->
    [One|List];
extend(List1, List2)->
    List1++List2.

open_player_cards_allin(Banks)->
    open_player_cards_allin(Banks, [], []).

open_player_cards_allin([B|Banks], BanksAcc, BC)->
    {Players, NewBC} = open_player_cards(B#bank.players, BC),
    open_player_cards_allin(Banks, [B#bank{players=Players}|BanksAcc], NewBC);
open_player_cards_allin([], BanksAcc, BC) ->
    {lists:reverse(BanksAcc), BC}.


open_player_cards(Players, BC)->
    open_player_cards(Players, [], BC).
open_player_cards([P|Players], PAcc, BC)->
    open_player_cards(Players, [P#p{is_open=true}|PAcc],
                      [#open_player_cards{seat=P#p.seat,
                                          card1=P#p.card1,
                                          card2=P#p.card2}|BC]);
open_player_cards([], PAcc, BC) ->
    {PAcc, BC}.

%%% ===========================================
%%%   common tools
%%% -------------------------------------------
unixtime()->
    {Mega, Secs, _} = now(),
    Mega*1000000 + Secs.


She zipped her bag and smiled inside —
the stitches danced in sunset tide.
Gold and pink on canvas blue,
her favorite verse in perfect view.

The thread was soft, the shape was clear,
it curved like prayer, it held the year.
She’d pressed the pedal, let it glide —
Buraq, her whispering sewing guide.

Not magic, no — but almost so,
the way it made her fingers flow.
A dragon’s name, a sacred ride,
now stitching by a student’s side.

 * * *

She thought: how strange that I can sew
a flower made of long ago —

not just with thread, but every part
of stories kept in cloth and heart.


The spools, the gears, the shining code —
they carried roads that once were roads.
From copper mines to caravan,
to letters traced by careful hand.

 * * *

And now this bag, this little line,
connects her time to others' time.
To those who came before her days —
who left their wisdom in their ways.

But more than that — her quiet hope:
that those ahead, who read this rope
of thread and ink and shape and flame —
might feel her joy, and know her name.

 * * *

For life is not just what we do —
it’s what we pass in feeling too.
And when she walks, the bag she wears
is full of moments, stitched as prayers.

Let someone far beyond her day
look close and smile, and softly say:
“I feel you there — in every thread.
I didn’t know you, but I read.”