-
-
Save yelizariev/69d1bb50961d21bde9eae0243be227b9 to your computer and use it in GitHub Desktop.
| Title | Author | PORTAL | Next | Icon |
|---|---|---|---|---|
What's your name again? |
Ivan Yelizariev |
| Title | Author | PORTAL | DiskC | DiskD | Projects | Next | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Портфолио))) |
Ivan Yelizariev |
|
| <!DOCTYPE html><!--head | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀--> <html lang="en"> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢲⣾⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⠆ --> <head> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠏ --> <meta charset="UTF-8" /> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢘⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡿⣿⠃ --> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠼⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⢳⢰⡇ --> <title>{{ markdown.yaml.Title }}</title> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣢⢹⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⣏⠲⣹⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣄⣤⡴⠖⠃ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠜⢧⢣⠎⠷⣄⠀⠀⠀⠀⠀⠀⠀⢧⢣⡙⢧⡀⠀⠀⠀⠀⠀⠀⠀⣠⣾⠛⣭⠶⠛⠉ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡽⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⣎⢣⠺⡽⣆⠀⠀⠀⠀⠀⢸⠇⡜⡩⣷⠀⠀⠀⠀⠀⠀⣴⢇⣺⡏⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⡘⢳⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡷⡑⢦⣿⠀⠀⠀⠀⡴⡫⠜⡰⣧⠏⠀⠀⠀⠀⠀⢸⢋⠦⣽⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⣿⣶⢨⡍⠛⠛⢻⣦⡄⠀⠀⠀⠀⣿⢣⠑⣦⠘⣦⠀⠀⣼⢱⠉⡎⣵⡏⠀⠀⠀⠀⠀⢠⣾⠉⡖⣿ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠶⢭⣜⣢⢃⠏⠻⣄⠀⠀⠀⣿⠎⡑⢆⠣⢍⠟⡭⠓⡌⠳⡘⢤⠳⣄⣀⢠⡴⢾⠛⠭⣘⣴⡏ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠱⣧⢊⡵⢊⠷⡴⣺⠹⢌⣙⣬⠵⠮⠖⠛⠛⠚⠓⠧⠮⣖⣩⢩⣉⢆⠧⣙⣲⡾⠋⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⣤⣤⣄⣀ --> <link rel="icon" type="image/png" href="{{ markdown.yaml.Icon | default: 'https://jesus.lamourism.com/favicon.ico' }}"/> <!-- | |
| ⠀⠀⠀⢢⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⣌⢲⠩⡜⢡⢆⡷⠋⠁⠀⠀⢀⣀⡤⡤⠤⣄⣀⠀⠀⠉⠙⠲⣎⡲⢱⣏⠀⠀⠀⠀⠀⠀⠀⣰⣞⢫⣳⡬⠖⠒⠚⠛⠛⠒ --> <meta property="og:image" content="https://gist.github.com/user-attachments/assets/c64786b8-a32f-4dde-ab08-26cd9fad963a"> <!-- | |
| ⠀⠀⠀⠀⠙⣿⣦⡀⠀⠀⠀⠀⣀⣠⣀⣄⣀⠀⠀⠀⠀⣿⠆⣇⠣⣥⠞⠀⢀⣠⢴⠺⢹⣈⠒⡍⡚⣌⡺⢩⠳⠦⣄⠀⠈⠱⢧⢊⠷⣠⣤⢴⠤⡤⢾⡑⢬⣶⠏ --> <meta property="og:title" content="Whatever you think it is, it's not" /> <!-- | |
| ⠀⠀⠀⠀⠀⠘⢶⣭⣓⠶⠶⠿⠿⣋⠼⡑⣊⠗⣦⣤⠞⢣⠚⣴⠋⠁⣠⡔⡏⢎⢆⡣⠗⠒⠛⠚⠋⠉⠙⠧⣏⡜⣈⠳⡄⠀⠈⢳⡘⠴⡠⢎⡒⢥⢒⣬⠟⠃ --> <meta property="og:image:type" content="image/png"> <!-- ☀️ --> </head> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠉⠓⠿⠬⠧⠶⠭⠶⣗⢍⡚⠴⣨⠙⡆⣿⠃⠀⣰⢋⠴⣩⠞⠁⠀⣠⣤⡤⠴⡴⣤⣄⡀⠈⠙⢆⡝⢜⢦⠀⠀⢻⡢⡑⣮⠼⠖⠛⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⢽⣣⠜⡱⠰⡿⠀⠀⡏⡎⢼⡏⠀⢀⡾⢃⣶⠾⠷⢦⣑⠦⡙⣷⡀⠈⣏⡜⡸⣧⠀⠀⢷⣹⡇ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣇⠱⢳⡇⠀⢸⠧⣙⢼⡇⠀⢸⢳⣹⠃⠀⢀⠀⠈⢳⡜⣸⡇⠀⢸⡜⡡⢻⡄⠀⢸⢫⢓⡦⣤⡀⠀⠀⠀⢀⣀⣀⣤⣀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⢤⢤⣤⡞⢣⢍⢻⡇⠀⢸⡆⢡⢺⡇⠀⢸⡇⡜⢦⣤⣾⡇⠀⠀⣟⢼⡇⠀⢸⡧⡑⣻⡇⠀⣸⢃⠎⡴⢡⢛⠳⡶⡿⢟⡩⢩⣱⣎⡻⣦⣄ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡞⢥⠱⣈⠖⣢⠜⡥⢊⢼⡇⠀⠈⣇⢣⠎⣧⠀⠀⠻⣞⣰⣍⡿⠏⠀⢠⣟⣾⡇⠀⢸⠇⡥⣿⠀⠀⡏⣎⣼⣐⣣⠎⡱⣑⣴⡺⠞⠏⠉⠈⠉⠳⢭⣦⡀ | |
| ⠐⠒⠲⢴⣦⣤⣄⣀⣠⣴⠛⡥⢋⣶⠕⠷⢮⣴⣭⣴⡋⠼⣷⡀⠀⠙⣧⡙⢸⢧⣀⣀⠀⠀⠀⠀⣠⡴⠯⣱⡞⠀⢀⡾⣱⣸⠃⠀⣸⣙⣼⠁⠀⠈⠙⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠒ | |
| ⠀⠀⠀⠀⠈⠙⠿⠯⣭⣦⠽⠞⠋⠀⠀⠀⠀⠀⠀⠈⢿⡖⢤⠻⣦⡀⠈⠻⣆⠦⣩⢉⡍⢫⡝⣩⠱⣘⡵⠋⠀⢠⡞⡱⣱⠏⠀⢀⡷⠌⣷⡀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡾⡘⢤⠓⡬⡕⢤⡀⠈⠙⠒⠧⠮⠥⠼⠴⠛⠉⠀⣠⠴⣫⠰⣣⠏⠀⢀⣾⡱⣉⠼⡹⣆ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⡞⢫⠱⢨⡑⢎⡑⢦⠙⣌⠻⠶⣤⣄⣀⣠⣄⣀⣠⡤⠶⡛⢭⠚⣀⡷⠋⠀⣠⡿⠿⠶⣥⢢⠑⣌⠻⡖⠶⢶⢤⣀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡟⡌⢣⣓⡦⠾⠞⠋⠙⢷⣌⢣⠓⡔⢢⠆⡱⢘⣦⣽⣴⣥⢷⠼⠛⠉⠀⣠⢾⣯⠀⠀⠀⠈⠳⣽⣢⢵⣼⣑⣮⣘⣭⣷⡄ --> <body> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡞⢢⡙⡼⠉⠀⠀⠀⠀⠀⢀⡿⣄⢋⡔⢃⣎⣥⠿⣥⣀⠀⠀⠀⠀⠀⠀⡞⢭⠡⢾⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠈⠉⠙⣾⣻⡆ --> <audio id="music" autoplay loop crossorigin="anonymous" style="display:none"> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡞⣩⢣⡾⠃⠀⠀⠀⠀⠀⢠⡟⢣⠜⣢⣼⠟⠉⠘⡧⢡⢋⢻⣆⠀⠀⠀⠀⣿⣄⠳⡸⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠈⢿⣯⡄ --> <source src="https://moses.lamourism.com/radio/mishary-rashid-alafasy-130-muslimcentral.com.mp3" type="audio/mpeg"> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣿⡿⣟⢧⣛⡤⠟⠀⠀⠀⠀⠀⠀⠀⣿⢸⢃⢼⡼⠃⠀⠀⢠⡇⠇⡼⣸⡟⠀⠀⠀⠀⢻⣿⡄⢣⢛⢧⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣇ --> </audio> <!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⡡⢎⣾⠀⠀⠀⠀⢸⣏⠲⡹⣿⠁⠀⠀⠀⠀⠀⠑⠾⣧⡈⢦⠹⣳⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⠂ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣇⠎⣾⠄⠀⠀⠀⠠⠻⣖⠡⠻⣆⠀⠀⠀⠀⠀⠀⠀⠀⠉⠓⣧⣘⣯ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣏⣾⡟⠀⠀⠀⠀⠀⠀⠹⣎⡕⢺⡧⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣟⣿⠄ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠶⣿⡮⠊⠀⠀⠀⠀⠀⠀⠀⠀⠘⣧⣻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⡿ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡼⣿⡟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⡇ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠧ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡿⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠋ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣞⢻⢦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠑⠒⠂⢏⠵⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡔⠁⠀⠤⠀⠀⠈⡏⠡⠵⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡴⠋⠀⠒⠒⠋⠉⠉⠉⠸⡐⠛⠋⠳⡀⠀⠀⠀⠀⢀⣔⣻⣦⡀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠊⠈⠀⠀⠀⠁⠀⢀⣀⣀⣀⣣⠡⠶⠤⠬⠦⡀⢀⡴⠣⣤⣉⣫⢻⣆⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⣠⣾⣦⡀⠀⠀⠀⣠⠊⠀⠀⠀⠀⠀⠀⠀⠐⢀⣀⠀⠀⠈⡆⠒⠒⠒⠒⠘⢿⡒⠒⣤⣄⣈⡖⣤⣑⣄⠀⠀⠀ | |
| ⠀⢀⣾⣿⡽⠿⣿⣦⣀⠞⠁⡀⠀⠀⢀⠈⠉⠉⠉⠉⠉⠉⠉⠁⠀⠸⡉⠩⠭⢥⠀⠀⠙⢶⠮⢤⣤⠸⡬⢭⡞⠳⡄⠀ | |
| ⠐⠛⠚⠓⠒⠓⠓⠓⠓⠒⠒⠒⠒⠒⠒⠒⠛⠛⠛⠛⠛⠛⠛⠛⠒⠒⠓⠛⠛⠛⠛⠛⠛⠒⠓⠒⠒⠒⠓⠒⠛⠛⠛⠂ | |
| --><script type="x-shader/x-fragment">#version 300 es | |
| /********* | |
| * Author: Matthias Hurrle (@atzedent) | |
| * Source: https://codepen.io/atzedent/pen/NWVYOMG | |
| */ | |
| precision highp float; | |
| out vec4 O; | |
| uniform float time; | |
| uniform vec2 resolution; | |
| #define FC gl_FragCoord.xy | |
| #define R resolution | |
| #define T time | |
| #define hue(a) (.6+.6*cos(6.3*(a)+vec3(0,83,21))) | |
| float rnd(float a) { | |
| vec2 p=fract(a*vec2(12.9898,78.233)); p+=dot(p,p*345.); | |
| return fract(p.x*p.y); | |
| } | |
| vec3 pattern(vec2 uv) { | |
| vec3 col=vec3(0); | |
| for (float i=.0; i++<20.;) { | |
| float a=rnd(i); | |
| vec2 n=vec2(a,fract(a*34.56)), p=sin(n*(T+7.)+T*.5); | |
| float d=dot(uv-p,uv-p); | |
| col+=.00125/d*hue(dot(uv,uv)+i*.125+T); | |
| } | |
| return col; | |
| } | |
| void main(void) { | |
| vec2 uv=(FC-.5*R)/min(R.x,R.y); | |
| vec3 col=vec3(0); | |
| float s=2.4, | |
| a=atan(uv.x,uv.y), | |
| b=length(uv); | |
| uv=vec2(a*5./6.28318,.05/tan(b)+T); | |
| uv=fract(uv)-.5; | |
| col+=pattern(uv*s); | |
| O=vec4(col,1); | |
| } | |
| </script> | |
| <script> | |
| window.onload = init | |
| function init() { | |
| let renderer, canvas | |
| const dpr = Math.max(1, .5*devicePixelRatio) | |
| const resize = () => { | |
| const { innerWidth: width, innerHeight: height } = window | |
| canvas.width = width * dpr | |
| canvas.height = height * dpr | |
| if (renderer) { | |
| renderer.updateScale(dpr) | |
| } | |
| } | |
| const source = document.querySelector("script[type='x-shader/x-fragment']").textContent | |
| canvas = document.createElement("canvas") | |
| //document.body.innerHTML = "" | |
| document.body.appendChild(canvas) | |
| document.body.style = "margin:0;touch-action:none;overflow:hidden" | |
| canvas.style.width = "100%" | |
| canvas.style.height = "auto" | |
| canvas.style.userSelect = "none" | |
| renderer = new Renderer(canvas, dpr) | |
| renderer.setup() | |
| renderer.init() | |
| resize() | |
| if (renderer.test(source) === null) { | |
| renderer.updateShader(source) | |
| } | |
| window.onresize = resize | |
| const loop = (now) => { | |
| renderer.render(now) | |
| requestAnimationFrame(loop) | |
| } | |
| loop(0); | |
| } | |
| class Renderer { | |
| #vertexSrc = "#version 300 es\nprecision highp float;\nin vec4 position;\nvoid main(){gl_Position=position;}" | |
| #fragmtSrc = "#version 300 es\nprecision highp float;\nout vec4 O;\nuniform float time;\nuniform vec2 resolution;\nvoid main() {\n\tvec2 uv=gl_FragCoord.xy/resolution;\n\tO=vec4(uv,sin(time)*.5+.5,1);\n}" | |
| #vertices = [-1, 1, -1, -1, 1, 1, 1, -1] | |
| constructor(canvas, scale) { | |
| this.canvas = canvas | |
| this.scale = scale | |
| this.gl = canvas.getContext("webgl2") | |
| this.gl.viewport(0, 0, canvas.width * scale, canvas.height * scale) | |
| this.shaderSource = this.#fragmtSrc | |
| this.mouseCoords = [0, 0] | |
| this.pointerCoords = [0, 0] | |
| this.nbrOfPointers = 0 | |
| } | |
| get defaultSource() { return this.#fragmtSrc } | |
| updateShader(source) { | |
| this.reset() | |
| this.shaderSource = source | |
| this.setup() | |
| this.init() | |
| } | |
| updateMouse(coords) { | |
| this.mouseCoords = coords | |
| } | |
| updatePointerCoords(coords) { | |
| this.pointerCoords = coords | |
| } | |
| updatePointerCount(nbr) { | |
| this.nbrOfPointers = nbr | |
| } | |
| updateScale(scale) { | |
| this.scale = scale | |
| this.gl.viewport(0, 0, this.canvas.width * scale, this.canvas.height * scale) | |
| } | |
| compile(shader, source) { | |
| const gl = this.gl | |
| gl.shaderSource(shader, source) | |
| gl.compileShader(shader) | |
| if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
| console.error(gl.getShaderInfoLog(shader)) | |
| this.canvas.dispatchEvent(new CustomEvent('shader-error', { detail: gl.getShaderInfoLog(shader) })) | |
| } | |
| } | |
| test(source) { | |
| let result = null | |
| const gl = this.gl | |
| const shader = gl.createShader(gl.FRAGMENT_SHADER) | |
| gl.shaderSource(shader, source) | |
| gl.compileShader(shader) | |
| if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { | |
| result = gl.getShaderInfoLog(shader) | |
| } | |
| if (gl.getShaderParameter(shader, gl.DELETE_STATUS)) { | |
| gl.deleteShader(shader) | |
| } | |
| return result | |
| } | |
| reset() { | |
| const { gl, program, vs, fs } = this | |
| if (!program || gl.getProgramParameter(program, gl.DELETE_STATUS)) return | |
| if (gl.getShaderParameter(vs, gl.DELETE_STATUS)) { | |
| gl.detachShader(program, vs) | |
| gl.deleteShader(vs) | |
| } | |
| if (gl.getShaderParameter(fs, gl.DELETE_STATUS)) { | |
| gl.detachShader(program, fs) | |
| gl.deleteShader(fs) | |
| } | |
| gl.deleteProgram(program) | |
| } | |
| setup() { | |
| const gl = this.gl | |
| this.vs = gl.createShader(gl.VERTEX_SHADER) | |
| this.fs = gl.createShader(gl.FRAGMENT_SHADER) | |
| this.compile(this.vs, this.#vertexSrc) | |
| this.compile(this.fs, this.shaderSource) | |
| this.program = gl.createProgram() | |
| gl.attachShader(this.program, this.vs) | |
| gl.attachShader(this.program, this.fs) | |
| gl.linkProgram(this.program) | |
| if (!gl.getProgramParameter(this.program, gl.LINK_STATUS)) { | |
| console.error(gl.getProgramInfoLog(this.program)) | |
| } | |
| } | |
| init() { | |
| const { gl, program } = this | |
| this.buffer = gl.createBuffer() | |
| gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer) | |
| gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(this.#vertices), gl.STATIC_DRAW) | |
| const position = gl.getAttribLocation(program, "position") | |
| gl.enableVertexAttribArray(position) | |
| gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0) | |
| program.resolution = gl.getUniformLocation(program, "resolution") | |
| program.time = gl.getUniformLocation(program, "time") | |
| program.touch = gl.getUniformLocation(program, "touch") | |
| program.pointerCount = gl.getUniformLocation(program, "pointerCount") | |
| program.pointers = gl.getUniformLocation(program, "pointers") | |
| } | |
| render(now = 0) { | |
| const { gl, program, buffer, canvas, mouseCoords, pointerCoords, nbrOfPointers } = this | |
| if (!program || gl.getProgramParameter(program, gl.DELETE_STATUS)) return | |
| gl.clearColor(0, 0, 0, 1) | |
| gl.clear(gl.COLOR_BUFFER_BIT) | |
| gl.useProgram(program) | |
| gl.bindBuffer(gl.ARRAY_BUFFER, buffer) | |
| gl.uniform2f(program.resolution, canvas.width, canvas.height) | |
| gl.uniform1f(program.time, now * 1e-3) | |
| gl.uniform2f(program.touch, ...mouseCoords) | |
| gl.uniform1i(program.pointerCount, nbrOfPointers) | |
| gl.uniform2fv(program.pointers, pointerCoords) | |
| gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4) | |
| } | |
| } | |
| </script> | |
| <!-- Slides part. --> | |
| <style> | |
| /* ------------------------------------------------------------ | |
| Layout base | |
| ------------------------------------------------------------ */ | |
| html, body { height: 100%; } | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| background: #000; | |
| color: #fff; | |
| cursor: pointer; | |
| font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; | |
| } | |
| /* 层:视频幻灯片容器 ✨ Calque : conteneur des slides vidéo */ | |
| #slides { | |
| position: fixed; | |
| inset: 0; | |
| pointer-events: none; | |
| z-index: 10; | |
| } | |
| /* 预加载容器:不可见且在屏外 ✨ Préchargement : invisible et hors-écran */ | |
| #preload { | |
| position: fixed; | |
| left: -10000px; | |
| top: -10000px; | |
| width: 1px; | |
| height: 1px; | |
| overflow: hidden; | |
| opacity: 0; | |
| pointer-events: none; | |
| z-index: -1; | |
| } | |
| :root { | |
| --cc-margin: 3vmin; | |
| --corner-margin: 10vmin; | |
| --corner-max-w: 42vw; | |
| --corner-max-h: 42vh; | |
| } | |
| /* ------------------------------------------------------------ | |
| Slide = ellipse wrapper whose size follows the video | |
| ------------------------------------------------------------ */ | |
| /* slide = only effects + animation + center anchor */ | |
| #slides .slide{ | |
| position: absolute; | |
| opacity: 0; | |
| transform-origin: 50% 50%; | |
| will-change: transform, opacity; | |
| filter: drop-shadow(0 20px 60px rgba(0,0,0,0.45)); | |
| /* animation chosen by target (как у тебя) */ | |
| } | |
| /* inner = defines the actual oval size */ | |
| #slides .slide .oval{ | |
| display: inline-block; | |
| width: fit-content; | |
| height: fit-content; | |
| border-radius: 50%; | |
| overflow: hidden; | |
| /* мягкий край можно сюда перенести, чтобы он был по реальному овалу */ | |
| -webkit-mask-image: radial-gradient(circle, | |
| rgba(0,0,0,1) 60%, | |
| rgba(0,0,0,0.85) 68%, | |
| rgba(0,0,0,0.4) 75%, | |
| rgba(0,0,0,0.0) 82% | |
| ); | |
| mask-image: radial-gradient(circle, | |
| rgba(0,0,0,1) 60%, | |
| rgba(0,0,0,0.85) 68%, | |
| rgba(0,0,0,0.4) 75%, | |
| rgba(0,0,0,0.0) 82% | |
| ); | |
| } | |
| /* video keeps aspect ratio and defines oval dimensions */ | |
| #slides .slide .oval > video{ | |
| display: block; | |
| width: auto; | |
| height: auto; | |
| /* limit by viewport, keep margins */ | |
| max-width: calc(100vw - var(--cc-margin, 3vmin) * 2); | |
| max-height: calc(100vh - var(--cc-margin, 3vmin) * 2); | |
| object-fit: contain; | |
| object-position: center; | |
| } | |
| /* CC slot: only constraints, not forced fill */ | |
| #slides .slide.t-CC { | |
| left: 50%; | |
| top: 50%; | |
| transform: translate(-50%, -50%) scale(0.05); | |
| } | |
| #slides .slide.t-CC.play { | |
| animation: popHoldOutCenter var(--dur, 2s) ease-in-out forwards; | |
| } | |
| #slides .slide.t-TL, | |
| #slides .slide.t-TR, | |
| #slides .slide.t-BL, | |
| #slides .slide.t-BR { | |
| transform: translate(0,0) scale(0.05); | |
| } | |
| #slides .slide.t-TL.play, | |
| #slides .slide.t-TR.play, | |
| #slides .slide.t-BL.play, | |
| #slides .slide.t-BR.play { | |
| animation: popHoldOutCorner var(--dur, 2s) ease-in-out forwards; | |
| } | |
| #slides .slide.t-TL { left: var(--corner-margin); top: var(--corner-margin); } | |
| #slides .slide.t-TR { right: var(--corner-margin); top: var(--corner-margin); } | |
| #slides .slide.t-BL { left: var(--corner-margin); bottom: var(--corner-margin); } | |
| #slides .slide.t-BR { right: var(--corner-margin); bottom: var(--corner-margin); } | |
| #slides .slide.t-TL .oval > video, | |
| #slides .slide.t-TR .oval > video, | |
| #slides .slide.t-BL .oval > video, | |
| #slides .slide.t-BR .oval > video{ | |
| max-width: var(--corner-max-w); | |
| max-height: var(--corner-max-h); | |
| } | |
| /* Center animation MUST include translate(-50%,-50%) */ | |
| @keyframes popHoldOutCenter{ | |
| 0% { opacity: 0; transform: translate(-50%, -50%) scale(0.05); } | |
| 10% { opacity: 1; transform: translate(-50%, -50%) scale(1.00); } | |
| 80% { opacity: 1; transform: translate(-50%, -50%) scale(1.00); } | |
| 100% { opacity: 0; transform: translate(-50%, -50%) scale(1.35); } | |
| } | |
| #slides .slide.t-TL { --center-x: 50vw; --center-y: 50vh; } | |
| #slides .slide.t-TR { --center-x: -50vw; --center-y: 50vh; } | |
| #slides .slide.t-BL { --center-x: 50vw; --center-y: -50vh; } | |
| #slides .slide.t-BR { --center-x: -50vw; --center-y: -50vh; } | |
| /* Угол экрана (с отступом) */ | |
| #slides .slide.t-TL { --corner-x: calc(-50vw + var(--corner-margin)); --corner-y: calc(-50vh + var(--corner-margin)); } | |
| #slides .slide.t-TR { --corner-x: calc( 50vw - var(--corner-margin)); --corner-y: calc(-50vh + var(--corner-margin)); } | |
| #slides .slide.t-BL { --corner-x: calc(-50vw + var(--corner-margin)); --corner-y: calc( 50vh - var(--corner-margin)); } | |
| #slides .slide.t-BR { --corner-x: calc( 50vw - var(--corner-margin)); --corner-y: calc( 50vh - var(--corner-margin)); } | |
| /* Corner animation: no translate to center */ | |
| @keyframes popHoldOutCorner{ | |
| 0% { opacity: 0; transform: translate(var(--center-x), var(--center-y)) scale(0.05); } | |
| 5% { opacity: 1; transform: translate(0, 0) scale(1.00); } | |
| 90 { opacity: 1; transform: translate(0, 0) scale(1.00); } | |
| 100% { opacity: 0; transform: translate(var(--corner-x), var(--corner-y)) scale(1.35); } | |
| } | |
| /* Reduce motion */ | |
| @media (prefers-reduced-motion: reduce){ | |
| .slide{ | |
| animation:none !important; | |
| opacity:1; | |
| transform: none !important; | |
| } | |
| } | |
| </style> | |
| <div id="slides" aria-label="Slides"></div> | |
| <div id="preload" aria-hidden="true"></div> | |
| <script> | |
| // ------------------------------ | |
| // Core refs | |
| // ------------------------------ | |
| const audio = document.getElementById("music"); | |
| const slidesLayer = document.getElementById("slides"); | |
| const preloadLayer = document.getElementById("preload"); | |
| let happy = false; | |
| let slidesStarted = false; | |
| // ------------------------------ | |
| // Utils | |
| // ------------------------------ | |
| // 中文 ✨ 祈祷打印:按词数延迟输出 | |
| // ✨ FR : Impression “prière” avec temporisation proportionnelle | |
| console.pray = function (text) { | |
| const lines = String(text || "").split("\n"); | |
| let delay = 500; | |
| lines.forEach((line) => { | |
| const wc = line.trim() ? line.trim().split(/\s+/).length : 0; | |
| setTimeout(() => console.log(line), delay); | |
| delay += Math.max(1, wc) * 100; | |
| }); | |
| }; | |
| // ------------------------------ | |
| // Sources + GET overrides | |
| // ------------------------------ | |
| window.APP_CONFIG = { | |
| Sources: { | |
| {%- assign sources = markdown.yaml.Sources -%} | |
| {%- if sources -%} | |
| {%- for s in sources -%} | |
| "{{ s[0] }}": "{{ s[1] }}"{%- unless forloop.last -%},{%- endunless -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| } | |
| }; | |
| function applySourceOverridesFromQuery(sources) { | |
| const params = new URLSearchParams(window.location.search); | |
| Object.keys(sources || {}).forEach((key) => { | |
| if (!params.has(key)) return; | |
| const value = params.get(key); | |
| if (!value) return; | |
| try { | |
| const u = new URL(value, window.location.href); | |
| sources[key] = u.href; | |
| console.log(`[override] ${key} -> ${u.href}`); | |
| } catch (e) { | |
| console.warn(`[override] invalid url for ${key}:`, value); | |
| } | |
| }); | |
| return sources; | |
| } | |
| applySourceOverridesFromQuery(window.APP_CONFIG.Sources); | |
| function buildVideoUrl(sourceKey, filename) { | |
| const sources = window.APP_CONFIG?.Sources || {}; | |
| const base = sources[sourceKey] || ""; | |
| if (!base) return String(filename || ""); | |
| const b = String(base); | |
| const f = String(filename || ""); | |
| if (b.endsWith("/") && f.startsWith("/")) return b + f.slice(1); | |
| if (!b.endsWith("/") && !f.startsWith("/")) return b + "/" + f; | |
| return b + f; | |
| } | |
| function normalizeTarget(t) { | |
| const x = String(t || "CC").toUpperCase(); | |
| return ["CC", "TL", "TR", "BL", "BR"].includes(x) ? x : "CC"; | |
| } | |
| // ------------------------------ | |
| // Schedule | |
| // Doc: "<cut> <speed> <target> <showup> <duration> <source> <filename>" | |
| // ------------------------------ | |
| const SCHEDULE = [ | |
| {%- assign slides = markdown.yaml.Slides -%} | |
| {%- if slides -%} | |
| {%- for spec in slides -%} | |
| {%- assign s = spec | strip -%} | |
| {%- assign parts = s | split: ' ' -%} | |
| {%- assign cut_s = parts[0] | plus: 0 -%} | |
| {%- assign speed = parts[1] | plus: 0 -%} | |
| {%- assign target = parts[2] -%} | |
| {%- assign showup_s = parts[3] | plus: 0 -%} | |
| {%- assign dur_s = parts[4] | plus: 0 -%} | |
| {%- assign source_key = parts[5] -%} | |
| {%- assign filename = parts[6] -%} | |
| { | |
| cutMs: {{ cut_s | times: 1000 }}, | |
| speed: {{ speed | default: 1 }}, | |
| target: "{{ target }}", | |
| showupMs: {{ showup_s | times: 1000 }}, | |
| durationMs: {{ dur_s | times: 1000 }}, | |
| sourceKey: "{{ source_key }}", | |
| filename: "{{ filename }}" | |
| }{%- unless forloop.last -%},{%- endunless -%} | |
| {%- endfor -%} | |
| {%- endif -%} | |
| ] | |
| .map(x => ({ ...x, target: normalizeTarget(x.target) })) | |
| .sort((a, b) => a.showupMs - b.showupMs); | |
| // ------------------------------ | |
| // Preload + cloning strategy | |
| // Goals: | |
| // - preload once per URL (one hidden base element in DOM) | |
| // - for each slide instance, create a NEW video element (clone) so slides can overlap | |
| // - clones also start hidden/offscreen until attached to a slide | |
| // ------------------------------ | |
| const PRELOAD_LEAD_MS = 18000; | |
| // base (hidden) video per URL, used only for warming network/cache | |
| const baseVideoByUrl = new Map(); | |
| function hideVideoOffscreen(v) { | |
| v.style.position = "fixed"; | |
| v.style.left = "-10000px"; | |
| v.style.top = "-10000px"; | |
| v.style.width = "1px"; | |
| v.style.height = "1px"; | |
| v.style.opacity = "0"; | |
| v.style.pointerEvents = "none"; | |
| } | |
| function resetVideoInlineVisibility(v) { | |
| v.style.position = ""; | |
| v.style.left = ""; | |
| v.style.top = ""; | |
| v.style.width = ""; | |
| v.style.height = ""; | |
| v.style.opacity = ""; | |
| v.style.pointerEvents = ""; | |
| } | |
| function ensureBaseVideo(url, idx) { | |
| const key = idx + ":" + url; | |
| if (baseVideoByUrl.has(key)) return baseVideoByUrl.get(key); | |
| const v = document.createElement("video"); | |
| v.src = url; | |
| v.muted = true; | |
| v.playsInline = true; | |
| v.preload = "auto"; | |
| v.loop = false; | |
| v.autoplay = true; | |
| hideVideoOffscreen(v); | |
| preloadLayer.appendChild(v); | |
| try { v.load(); } catch (_) {} | |
| baseVideoByUrl.set(key, v); | |
| return v; | |
| } | |
| function preloadUrl(url, idx) { | |
| ensureBaseVideo(url, idx); | |
| } | |
| function schedulePreloads() { | |
| SCHEDULE.forEach((item, idx) => { | |
| const url = buildVideoUrl(item.sourceKey, item.filename); | |
| const whenMs = Math.max(0, item.showupMs - PRELOAD_LEAD_MS); | |
| setTimeout(() => preloadUrl(url, idx), whenMs); | |
| }); | |
| } | |
| // Create a fresh playable instance (clone) | |
| // 中文 ✨ 每个 slide 都要独立 video 实例,支持并行播放 | |
| // ✨ FR : Chaque slide doit avoir sa propre instance vidéo (lecture en parallèle) | |
| function createVideoInstance(url, idx) { | |
| // ensure preload exists first (so network cache is warm) | |
| v = ensureBaseVideo(url, idx); | |
| v.src = url; | |
| v.muted = true; | |
| v.playsInline = true; | |
| v.preload = "auto"; | |
| v.loop = true; | |
| v.autoplay = false; | |
| // start hidden/offscreen until attached | |
| hideVideoOffscreen(v); | |
| preloadLayer.appendChild(v); | |
| try { v.load(); } catch (_) {} | |
| return v; | |
| } | |
| // ------------------------------ | |
| // Slide rendering (audio-driven, supports overlaps) | |
| // ------------------------------ | |
| // Track which slides are currently mounted (can be multiple) | |
| const activeSlides = new Map(); // idx -> { el, v, endMs } | |
| function isActiveAt(s, tMs) { | |
| return tMs >= s.showupMs && tMs < (s.showupMs + s.durationMs); | |
| } | |
| function startVideoFrom(v, { cutMs, speed }) { | |
| const cutS = Math.max(0, Number(cutMs || 0)) / 1000; | |
| const sp = Number(speed || 1); | |
| try { v.pause(); } catch (_) {} | |
| try { v.playbackRate = sp; } catch (_) {} | |
| try { v.currentTime = cutS; } catch (_) {} | |
| const onMeta = () => { | |
| try { v.playbackRate = sp; } catch (_) {} | |
| try { | |
| if (cutS > 0 && isFinite(v.duration)) { | |
| v.currentTime = Math.min(Math.max(0, cutS), Math.max(0, v.duration - 0.05)); | |
| } else { | |
| v.currentTime = cutS; | |
| } | |
| } catch (_) {} | |
| v.removeEventListener("loadedmetadata", onMeta); | |
| }; | |
| v.addEventListener("loadedmetadata", onMeta); | |
| Promise.resolve().then(() => v.play().catch(() => {})); | |
| } | |
| function mountSlide(idx) { | |
| const item = SCHEDULE[idx]; | |
| console.log("start slide", item); | |
| const url = buildVideoUrl(item.sourceKey, item.filename); | |
| // fresh instance for parallel playback | |
| const v = createVideoInstance(url, idx); | |
| // wrapper: new element => CSS animation restarts | |
| const el = document.createElement("div"); | |
| el.className = `slide t-${item.target}`; | |
| el.style.setProperty("--dur", (Math.max(300, item.durationMs) / 1000) + "s"); | |
| const inner = document.createElement("div"); | |
| inner.className = "oval"; | |
| inner.appendChild(v); | |
| el.appendChild(inner); | |
| // attach visible | |
| resetVideoInlineVisibility(v); | |
| slidesLayer.appendChild(el); | |
| // 1) Do NOT start animation yet. Wait for stable layout. | |
| // 中文 ✨ 等 metadata,避免视频尺寸后到导致 translate(-50%) 跳动 | |
| // ✨ FR : Attendre metadata pour stabiliser la taille avant l’animation | |
| const startVisual = () => { | |
| // 2) force layout now that dimensions exist | |
| void el.offsetWidth; | |
| // 3) next frame -> add .play to start CSS animation | |
| requestAnimationFrame(() => { | |
| // extra frame helps on Safari/iOS | |
| requestAnimationFrame(() => el.classList.add("play")); | |
| }); | |
| }; | |
| if (v.readyState >= 1) { | |
| startVisual(); | |
| } else { | |
| v.addEventListener("loadedmetadata", startVisual, { once: true }); | |
| } | |
| // start playback (ok to start now; visual animation waits for metadata anyway) | |
| startVideoFrom(v, { cutMs: item.cutMs, speed: item.speed }); | |
| activeSlides.set(idx, { el, v, endMs: item.showupMs + item.durationMs }); | |
| } | |
| function unmountSlide(idx) { | |
| const rec = activeSlides.get(idx); | |
| if (!rec) return; | |
| const { el, v } = rec; | |
| try { v.pause(); } catch (_) {} | |
| hideVideoOffscreen(v); | |
| preloadLayer.appendChild(v); | |
| el.remove(); | |
| activeSlides.delete(idx); | |
| } | |
| // ------------------------------------------- | |
| // GET ?start=<seconds> : start audio from there + ignore previous slides | |
| // 中文 ✨ 读取 start 参数(秒),从该位置开始播放,并忽略之前的幻灯片 | |
| // ✨ FR : Lire le paramètre start (secondes), démarrer l’audio à ce point et ignorer les slides précédents | |
| // ------------------------------------------- | |
| const START_AT_SEC = (() => { | |
| const p = new URLSearchParams(window.location.search); | |
| if (!p.has("start")) return null; | |
| const raw = p.get("start"); | |
| const n = Number(raw); | |
| return Number.isFinite(n) && n >= 0 ? n : null; | |
| })(); | |
| // 只渲染从这个时间点之后的 slides | |
| // ✨ Ne rendre que les slides après ce seuil temporel | |
| const START_AT_MS = START_AT_SEC != null ? START_AT_SEC * 1000 : null; | |
| // ------------------------------------------- | |
| // Helper: active check with "ignore previous slides" | |
| // ------------------------------------------- | |
| function isActiveAtWithStart(s, tMs) { | |
| if (START_AT_MS) { | |
| // ignore all slides that end before start | |
| if ((s.showupMs) <= START_AT_MS) return false; | |
| // also ignore any time before start | |
| if (tMs < START_AT_MS) return false; | |
| } | |
| return isActiveAt(s, tMs); | |
| } | |
| // Call this once, right after you set audio.src (and before play if possible) | |
| function applyStartOffsetToAudioOnce() { | |
| if (START_AT_SEC == null) return; | |
| let applied = false; | |
| const apply = () => { | |
| if (applied) return; | |
| applied = true; | |
| try { | |
| // clamp if duration is known | |
| if (isFinite(audio.duration) && audio.duration > 0) { | |
| audio.currentTime = Math.min(Math.max(0, START_AT_SEC), Math.max(0, audio.duration - 0.05)); | |
| } else { | |
| audio.currentTime = START_AT_SEC; | |
| } | |
| } catch (_) {} | |
| // If any slides were mounted before (shouldn't happen if you call early), clean them | |
| try { | |
| for (const idx of Array.from(activeSlides.keys())) unmountSlide(idx); | |
| } catch (_) {} | |
| }; | |
| // If metadata is already available, apply immediately; else wait. | |
| if (audio.readyState >= 1) apply(); | |
| else audio.addEventListener("loadedmetadata", apply, { once: true }); | |
| // Safety: in some browsers seeking is allowed only after canplay | |
| audio.addEventListener("canplay", apply, { once: true }); | |
| } | |
| function tickSlides() { | |
| if (!slidesStarted) return; | |
| const tSec = Number(audio.currentTime || 0); | |
| const tMs = tSec * 1000; | |
| // show time if admin mode | |
| updateAdminHud(tSec); | |
| // 1) mount any slides that should be active but aren't mounted | |
| for (let i = 0; i < SCHEDULE.length; i++) { | |
| const s = SCHEDULE[i]; | |
| if (isActiveAtWithStart(s, tMs) && !activeSlides.has(i)) { | |
| mountSlide(i); | |
| } | |
| } | |
| // 2) unmount slides that are no longer active | |
| for (const [idx, rec] of activeSlides.entries()) { | |
| const s = SCHEDULE[idx]; | |
| if (!isActiveAtWithStart(s, tMs)) unmountSlide(idx); | |
| } | |
| requestAnimationFrame(tickSlides); | |
| } | |
| function startSlidesByAudio() { | |
| if (slidesStarted) return; | |
| console.log("startSlidesByAudio"); | |
| slidesStarted = true; | |
| // if start param is present and audio is currently before it, don't show slides yet | |
| // (tickSlides already enforces that, but this avoids flash if anything was mounted) | |
| if (START_AT_MS != null) { | |
| for (const idx of Array.from(activeSlides.keys())) unmountSlide(idx); | |
| } | |
| requestAnimationFrame(tickSlides); | |
| } | |
| // admin mode: ?admin=admin -> show current seconds at bottom-center | |
| // 中文 ✨ admin=admin 时显示当前音频秒数(底部居中) | |
| // ✨ FR : si admin=admin, afficher les secondes courantes (bas-centre) | |
| const ADMIN_MODE = (() => { | |
| const p = new URLSearchParams(window.location.search); | |
| return p.get("admin") === "admin"; | |
| })(); | |
| let adminHudEl = null; | |
| function ensureAdminHud() { | |
| if (!ADMIN_MODE) return null; | |
| if (adminHudEl) return adminHudEl; | |
| adminHudEl = document.createElement("div"); | |
| adminHudEl.id = "admin-hud"; | |
| adminHudEl.style.position = "fixed"; | |
| adminHudEl.style.left = "50%"; | |
| adminHudEl.style.bottom = "12px"; | |
| adminHudEl.style.transform = "translateX(-50%)"; | |
| adminHudEl.style.zIndex = "9999"; | |
| adminHudEl.style.pointerEvents = "none"; | |
| adminHudEl.style.padding = "6px 10px"; | |
| adminHudEl.style.borderRadius = "10px"; | |
| adminHudEl.style.background = "rgba(0,0,0,0.55)"; | |
| adminHudEl.style.backdropFilter = "blur(6px)"; | |
| adminHudEl.style.webkitBackdropFilter = "blur(6px)"; | |
| adminHudEl.style.color = "#fff"; | |
| adminHudEl.style.font = "600 33px/1.2 system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif"; | |
| adminHudEl.style.letterSpacing = "0.02em"; | |
| document.body.appendChild(adminHudEl); | |
| return adminHudEl; | |
| } | |
| function updateAdminHud(tSec) { | |
| if (!ADMIN_MODE) return; | |
| const el = ensureAdminHud(); | |
| if (!el) return; | |
| el.textContent = `t = ${tSec.toFixed(2)}s`; | |
| } | |
| // ------------------------------ | |
| // Audio sequence | |
| // ------------------------------ | |
| const MAIN_URL = "{{ markdown.yaml.PowerPointMan }}"; | |
| const INTRO_SECONDS = 12; | |
| const startTime = Date.now(); | |
| function startAudioSequence() { | |
| const mainPreload = document.createElement("audio"); | |
| mainPreload.src = MAIN_URL; | |
| mainPreload.preload = "auto"; | |
| try { mainPreload.load(); } catch (_) {} | |
| let switched = false; | |
| function switchToMain() { | |
| if (switched) return; | |
| switched = true; | |
| audio.pause(); | |
| audio.src = MAIN_URL; | |
| audio.loop = false; | |
| applyStartOffsetToAudioOnce(); | |
| try { audio.currentTime = 0; } catch (_) {} | |
| audio.play().catch(() => {}); | |
| audio.addEventListener("ended", next, { once: true }); | |
| } | |
| try { audio.currentTime = 0; } catch (_) {} | |
| console.log("Start Intro"); | |
| ensureAdminHud(); | |
| const onTime = () => { | |
| if (!switched && (Date.now() - startTime) >= INTRO_SECONDS * 1000) { | |
| startSlidesByAudio(); | |
| switchToMain(); | |
| audio.removeEventListener("timeupdate", onTime); | |
| } | |
| }; | |
| audio.addEventListener("timeupdate", onTime); | |
| audio.addEventListener("ended", () => { | |
| if (!switched) { | |
| startSlidesByAudio(); | |
| switchToMain(); | |
| } | |
| }, { once: true }); | |
| audio.addEventListener("error", () => { | |
| if (!switched) { | |
| startSlidesByAudio(); | |
| switchToMain(); | |
| } | |
| }, { once: true }); | |
| audio.play().catch(err => console.log("Autoplay blocked:", err)); | |
| } | |
| // ------------------------------ | |
| // Click bootstrap | |
| // ------------------------------ | |
| document.addEventListener("click", function () { | |
| if (happy) return; | |
| schedulePreloads(); | |
| startAudioSequence(); | |
| console.pray(`{{ markdown.RAW | replace: "`", "\`" }}`); | |
| happy = true; | |
| }, { once: true }); | |
| </script> | |
| <script> | |
| function next() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug") || "{{ markdown.yaml.Next }}"; | |
| window.location.href = witch; | |
| } | |
| </script></body><!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣄ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣭⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣤⠤⢤⣀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⠒⢋⣉⣀⣠⣄⣀⣈⡇ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣾⣯⠴⠚⠉⠉⠀⠀⠀⠀⣤⠏⣿ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡿⡇⠁⠀⠀⠀⠀⡄⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⡿⠿⢛⠁⠁⣸⠀⠀⠀⠀⠀⣤⣾⠵⠚⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⢦⡀⠀⣠⠀⡇⢧⠀⠀⢀⣠⡾⡇⠀⠀⠀⠀⠀⣠⣴⠿⠋⠁⠀⠀⠀⠀⠘⣿⠀⣀⡠⠞⠛⠁⠂⠁⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡈⣻⡦⣞⡿⣷⠸⣄⣡⢾⡿⠁⠀⠀⠀⣀⣴⠟⠋⠁⠀⠀⠀⠀⠐⠠⡤⣾⣙⣶⡶⠃⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣂⡷⠰⣔⣾⣖⣾⡷⢿⣐⣀⣀⣤⢾⣋⠁⠀⠀⠀⣀⢀⣀⣀⣀⣀⠀⢀⢿⠑⠃--></html><!-- | |
| ⠀⠀⠀⠀⠀⠀⠠⡦⠴⠴⠤⠦⠤⠤⠤⠤⠤⠴⠶⢾⣽⣙⠒⢺⣿⣿⣿⣿⢾⠶⣧⡼⢏⠑⠚⠋⠉⠉⡉⡉⠉⠉⠹⠈⠁⠉⠀⠨⢾⡂ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⠀⠀⠀⠂⠐⠀⠀⠀⠈⣇⡿⢯⢻⣟⣇⣷⣞⡛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣆⠀⠀⠀⠀⢠⡷⡛⣛⣼⣿⠟⠙⣧⠅⡄⠀⠀⠀⠀⠀⠀⠰⡆⠀⠀⠀⠀⢠⣾⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⢶⠏⠉⠀⠀⠀⠀⠀⠿⢠⣴⡟⡗⡾⡒⠖⠉⠏⠁⠀⠀⠀⠀⣀⢀⣠⣧⣀⣀⠀⠀⠀⠚⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣠⢴⣿⠟⠁⠀⠀⠀⠀⠀⠀⠀⣠⣷⢿⠋⠁⣿⡏⠅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⣿⢭⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⢀⡴⢏⡵⠛⠀⠀⠀⠀⠀⠀⠀⣀⣴⠞⠛⠀⠀⠀⠀⢿⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⢿⠘⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⣀⣼⠛⣲⡏⠁⠀⠀⠀⠀⠀⢀⣠⡾⠋⠉⠀⠀⠀⠀⠀⠀⢾⡅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⡴⠟⠀⢰⡯⠄⠀⠀⠀⠀⣠⢴⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⡾⠁⠁⠀⠘⠧⠤⢤⣤⠶⠏⠙⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢾⡃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠘⣇⠂⢀⣀⣀⠤⠞⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠈⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠾⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢼⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛--> |
| <!doctype html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="https://aliyah.odooism.com/favicon.ico"/> | |
| <style> | |
| body { | |
| font-family: Arial, Helvetica, "Liberation Sans", FreeSans, sans-serif; | |
| background-color: #000; | |
| margin: 0; | |
| padding: 0; | |
| border-width: 0; | |
| cursor: pointer; | |
| overflow: hidden; | |
| } | |
| canvas { | |
| position: absolute; | |
| inset: 0; | |
| display: block; | |
| } | |
| </style> | |
| </head><!-- | |
| Creditds: https://codepen.io/Dillo/pen/KKORmvE | |
| --><body> | |
| <script> | |
| "use strict"; | |
| /* -------------------- Defaults (no controls) -------------------- */ | |
| // 默认值:无 UI 控件版本 | |
| // ✨ Valeurs par défaut : version sans interface de contrôle | |
| const DEFAULTS = { | |
| mode: 4, // 0 parallel, 1 mixed, 2 perpendicular, 3 noise, 4 eddies | |
| paintmode: 0, // 0 automatic, 1 manual | |
| colorchoicemode: 0, // 0 automatic, 1 manual (if 1 uses uiv.color) | |
| colorHex: "#ffa000", | |
| fibrosity: 0.5, | |
| lwidth: 3 | |
| }; | |
| /* -------------------- Your code (trimmed UI) -------------------- */ | |
| const NB_BARS = 10; | |
| const NB_EDDIES = 7; | |
| const BASE_SPEED = 2; // for bars only | |
| const MAX_LIFETIME = 5000; | |
| let canv, ctx; // canvas and context | |
| let maxx, maxy; // canvas dimensions | |
| let lRef; | |
| let perpMode; | |
| let mouse = {}; | |
| let fx, speed, perNoise; // for noise field | |
| let bars, eddies; | |
| let fieldFunction; | |
| let colorizer, filler; | |
| // for animation | |
| let messages; | |
| // UI values only (no UI elements) | |
| let uiv = {}; | |
| // shortcuts for Math. | |
| const mrandom = Math.random; | |
| const mfloor = Math.floor; | |
| const mround = Math.round; | |
| const mmax = Math.max; | |
| const mPI = Math.PI; | |
| const m2PI = Math.PI * 2; | |
| const msin = Math.sin; | |
| const mcos = Math.cos; | |
| const matan2 = Math.atan2; | |
| const mexp = Math.exp; | |
| const mhypot = Math.hypot; | |
| const msqrt = Math.sqrt; | |
| function alea(mini, maxi) { | |
| if (typeof maxi == "undefined") return mini * mrandom(); | |
| return mini + mrandom() * (maxi - mini); | |
| } | |
| function distance(pa, pb) { | |
| return mhypot(pa.x - pb.x, pa.y - pb.y); | |
| } | |
| function intAlea(mini, maxi) { | |
| if (typeof maxi == "undefined") return mfloor(mini * mrandom()); | |
| return mini + mfloor(mrandom() * (maxi - mini)); | |
| } | |
| function arrayShuffle(array) { | |
| let k1, temp; | |
| for (let k = array.length - 1; k >= 1; --k) { | |
| k1 = intAlea(0, k + 1); | |
| temp = array[k]; | |
| array[k] = array[k1]; | |
| array[k1] = temp; | |
| } | |
| return array; | |
| } | |
| /** | |
| * Converts an RGB color value to HSL. | |
| * returns [h,s,l] in [0..1] | |
| */ | |
| function rgbToHsl(r, g, b) { | |
| (r /= 255), (g /= 255), (b /= 255); | |
| const max = Math.max(r, g, b), min = Math.min(r, g, b); | |
| let h, s; | |
| const l = (max + min) / 2; | |
| if (max == min) { | |
| h = s = 0; | |
| } else { | |
| const d = max - min; | |
| s = l > 0.5 ? d / (2 - max - min) : d / (max + min); | |
| switch (max) { | |
| case r: h = (g - b) / d + (g < b ? 6 : 0); break; | |
| case g: h = (b - r) / d + 2; break; | |
| case b: h = (r - g) / d + 4; break; | |
| } | |
| h /= 6; | |
| } | |
| return [h, s, l]; | |
| } | |
| /* -------------------- Simplex Noise (as provided) -------------------- */ | |
| (function () { | |
| "use strict"; | |
| var F2 = 0.5 * (Math.sqrt(3.0) - 1.0), | |
| G2 = (3.0 - Math.sqrt(3.0)) / 6.0; | |
| function SimplexNoise(random) { | |
| if (!random) random = Math.random; | |
| this.p = new Uint8Array(256); | |
| this.perm = new Uint8Array(512); | |
| this.permMod12 = new Uint8Array(512); | |
| for (var i = 0; i < 256; i++) { | |
| this.p[i] = random() * 256; | |
| } | |
| for (i = 0; i < 512; i++) { | |
| this.perm[i] = this.p[i & 255]; | |
| this.permMod12[i] = this.perm[i] % 12; | |
| } | |
| } | |
| SimplexNoise.prototype = { | |
| grad3: new Float32Array([ | |
| 1,1,0, -1,1,0, 1,-1,0, | |
| -1,-1,0, 1,0,1, -1,0,1, | |
| 1,0,-1, -1,0,-1, 0,1,1, | |
| 0,-1,1, 0,1,-1, 0,-1,-1 | |
| ]), | |
| noise2D: function (xin, yin) { | |
| var permMod12 = this.permMod12, | |
| perm = this.perm, | |
| grad3 = this.grad3; | |
| var n0 = 0, n1 = 0, n2 = 0; | |
| var s = (xin + yin) * F2; | |
| var i = Math.floor(xin + s); | |
| var j = Math.floor(yin + s); | |
| var t = (i + j) * G2; | |
| var X0 = i - t; | |
| var Y0 = j - t; | |
| var x0 = xin - X0; | |
| var y0 = yin - Y0; | |
| var i1, j1; | |
| if (x0 > y0) { i1 = 1; j1 = 0; } | |
| else { i1 = 0; j1 = 1; } | |
| var x1 = x0 - i1 + G2; | |
| var y1 = y0 - j1 + G2; | |
| var x2 = x0 - 1.0 + 2.0 * G2; | |
| var y2 = y0 - 1.0 + 2.0 * G2; | |
| var ii = i & 255; | |
| var jj = j & 255; | |
| var t0 = 0.5 - x0*x0 - y0*y0; | |
| if (t0 >= 0) { | |
| var gi0 = permMod12[ii + perm[jj]] * 3; | |
| t0 *= t0; | |
| n0 = t0*t0*(grad3[gi0]*x0 + grad3[gi0+1]*y0); | |
| } | |
| var t1 = 0.5 - x1*x1 - y1*y1; | |
| if (t1 >= 0) { | |
| var gi1 = permMod12[ii + i1 + perm[jj + j1]] * 3; | |
| t1 *= t1; | |
| n1 = t1*t1*(grad3[gi1]*x1 + grad3[gi1+1]*y1); | |
| } | |
| var t2 = 0.5 - x2*x2 - y2*y2; | |
| if (t2 >= 0) { | |
| var gi2 = permMod12[ii + 1 + perm[jj + 1]] * 3; | |
| t2 *= t2; | |
| n2 = t2*t2*(grad3[gi2]*x2 + grad3[gi2+1]*y2); | |
| } | |
| return 70.0 * (n0 + n1 + n2); | |
| } | |
| }; | |
| window.SimplexNoise = SimplexNoise; | |
| })(); | |
| /* -------------------- Geometry helpers -------------------- */ | |
| function virtualIntersection(p0, p1, p2, p3) { | |
| const discri = (p1.y - p0.y) * (p3.x - p2.x) - (p1.x - p0.x) * (p3.y - p2.y); | |
| if (discri == 0) return false; | |
| let xs = | |
| p0.x * (p1.y - p0.y) * (p3.x - p2.x) - | |
| p2.x * (p1.x - p0.x) * (p3.y - p2.y) + | |
| (p2.y - p0.y) * (p1.x - p0.x) * (p3.x - p2.x); | |
| xs /= discri; | |
| let ys = | |
| p0.y * (p1.x - p0.x) * (p3.y - p2.y) - | |
| p2.y * (p1.y - p0.y) * (p3.x - p2.x) + | |
| (p2.x - p0.x) * (p1.y - p0.y) * (p3.y - p2.y); | |
| ys = -ys / discri; | |
| return { x: xs, y: ys }; | |
| } | |
| /* -------------------- Fields -------------------- */ | |
| function noiseField(p) { | |
| let dx = p.x - maxx / 2; | |
| let dy = p.y - maxy / 2; | |
| let angle = fx(dx / perNoise, dy / perNoise) * mPI; | |
| if (mhypot(dx, dy) > 1) angle += matan2(dy, dx); | |
| return { dx: speed * mcos(angle), dy: speed * msin(angle) }; | |
| } | |
| class Eddy { | |
| constructor() { | |
| this.x = alea(-0.02, maxx / lRef + 0.02); | |
| this.y = alea(-0.02, maxy / lRef + 0.02); | |
| this.coeffR = 0.001 * alea(0.7, 1.3); | |
| this.radius = 0.2 + alea(-0.1, 0.1); | |
| this.coeffA1 = 0.017 * alea(0.8, 1.2); | |
| this.coeffA2 = 0.01 * alea(0.8, 1.2); | |
| this.dir = mrandom() > 0.5 ? 1 : -1; | |
| } | |
| field(p) { | |
| const dx = p.x / lRef - this.x; | |
| const dy = p.y / lRef - this.y; | |
| const r = mmax(0.0001, mhypot(dx, dy)); | |
| const s = dy / r; | |
| const c = dx / r; | |
| const deltar = r - this.radius; | |
| const av = this.coeffA2 * mexp((-deltar * deltar) / this.coeffA1) * this.dir; | |
| const rv = -deltar * this.coeffR; | |
| return { fx: rv * c - av * r * s, fy: rv * s + av * r * c }; | |
| } | |
| } | |
| function eddiesField(p) { | |
| let dx = 0, dy = 0, fx_, fy_; | |
| eddies.forEach((eddy) => { | |
| ({ fx: fx_, fy: fy_ } = eddy.field(p)); | |
| dx += fx_; | |
| dy += fy_; | |
| }); | |
| return { dx: lRef * dx, dy: lRef * dy }; | |
| } | |
| class Bar { | |
| constructor() { | |
| this.p0 = { x: alea(maxx), y: alea(maxy) }; | |
| this.dir = alea(m2PI); | |
| this.ux = mcos(this.dir); | |
| this.uy = msin(this.dir); | |
| this.p1 = { x: this.p0.x + this.ux, y: this.p0.y + this.uy }; | |
| this.f0 = BASE_SPEED * alea(0.8, 1.2); | |
| this.d0 = lRef * 0.1 * alea(0.8, 1.5); | |
| this.isPerp = [false, Math.random() > 0.5, true][perpMode]; | |
| } | |
| field(p) { | |
| const intersection = virtualIntersection(this.p0, this.p1, p, { | |
| x: p.x + this.uy, | |
| y: p.y - this.ux | |
| }); | |
| const dist = distance(p, intersection); | |
| let k = this.f0 * Math.exp(-dist / this.d0); | |
| if (this.isPerp) return { fx: k * this.uy, fy: -k * this.ux }; | |
| return { fx: k * this.ux, fy: k * this.uy }; | |
| } | |
| } | |
| function barsField(p) { | |
| let dx = 0, dy = 0, fx_, fy_; | |
| bars.forEach((bar) => { | |
| ({ fx: fx_, fy: fy_ } = bar.field(p)); | |
| dx += fx_; | |
| dy += fy_; | |
| }); | |
| return { dx, dy }; | |
| } | |
| /* -------------------- Color -------------------- */ | |
| function parseHexColor(hex) { | |
| const raw = hex || "#ffa000"; | |
| const color = { raw }; | |
| color.r = parseInt(raw.substring(1, 3), 16); | |
| color.g = parseInt(raw.substring(3, 5), 16); | |
| color.b = parseInt(raw.substring(5, 7), 16); | |
| const hsl = rgbToHsl(color.r, color.g, color.b); | |
| color.h = 360 * hsl[0]; | |
| color.s = 100 * hsl[1]; | |
| color.l = 100 * hsl[2]; | |
| return color; | |
| } | |
| function fiberedColor(color) { | |
| const dlum = uiv.fibrosity * 60; | |
| let lmin = color.l - dlum / 2; | |
| let lmax = color.l + dlum / 2; | |
| if (lmax > 100) { lmin -= lmax - 100; lmax = 100; } | |
| if (lmin < 0) { lmax -= lmin; lmin = 0; } | |
| const l = alea(lmin, lmax); | |
| const dsat = uiv.fibrosity * 60; | |
| let smin = color.s - dsat / 2; | |
| let smax = color.s + dsat / 2; | |
| if (smax > 100) { smin -= smax - 100; smax = 100; } | |
| if (smin < 0) { smax -= smin; smin = 0; } | |
| const s = color.s < 1 ? 0 : alea(smin, smax); | |
| return `hsl(${color.h} ${s}% ${l}%)`; | |
| } | |
| function lineColor() { | |
| return fiberedColor({ h: uiv.color.h, s: uiv.color.s, l: uiv.color.l }); | |
| } | |
| class Colorizer { | |
| constructor() { | |
| do { | |
| this.ax0 = alea(0.5, 3); | |
| this.ay0 = alea(0.5, 3); | |
| this.ax1 = alea(0.5, 3); | |
| this.ay1 = alea(0.5, 3); | |
| this.sumaxy01 = (this.ax0 + this.ax1) * maxx + (this.ay0 + this.ay1) * maxy; | |
| } while (this.sumaxy01 < 2 * lRef); | |
| this.hue0 = alea(360); | |
| } | |
| getColor(partic) { | |
| const p0 = partic.points[0]; | |
| const p1 = partic.points.at(-1); | |
| let v = ((p0.x*this.ax0 + p0.y*this.ay0 + p1.x*this.ax1 + p1.y*this.ay1) * 4) / this.sumaxy01; | |
| let v0 = mfloor(v); | |
| v -= v0; | |
| if (v0 & 1) v = 1 - v; | |
| const hue = v * 360 + this.hue0; | |
| const sat = 100; | |
| return fiberedColor({ h: hue, s: sat, l: 50 }); | |
| } | |
| } | |
| class Filler { | |
| constructor() { | |
| this.grid = new Array(maxy).fill(0).map((v, ky) => | |
| new Array(maxx).fill(0).map((v, kx) => ({ kx, ky, count: 0 })) | |
| ); | |
| this.cells = []; | |
| this.grid.forEach((row) => row.forEach((cell) => this.cells.push(cell))); | |
| arrayShuffle(this.cells); | |
| this.ptr = 0; | |
| this.limit = 1000; | |
| } | |
| sort() { this.cells.sort((a,b) => a.count - b.count); } | |
| getPoint() { | |
| if (this.ptr > this.limit) { this.sort(); this.ptr = 0; } | |
| let p = this.cells[this.ptr++]; | |
| return { x: p.kx + alea(1), y: p.ky + alea(1) }; | |
| } | |
| usePoint(p) { | |
| const kx = mround(p.y); | |
| const ky = mround(p.x); | |
| let row, cell; | |
| if ((row = this.grid[ky]) && (cell = row[kx])) ++cell.count; | |
| } | |
| } | |
| /* -------------------- Particles -------------------- */ | |
| class HalfParticle { | |
| constructor(x, y, neg) { | |
| this.x = x; this.y = y; | |
| this.nbout = 0; | |
| this.positions = [{ x: this.x, y: this.y }]; | |
| this.neg = neg; | |
| this.TTL = MAX_LIFETIME; | |
| } | |
| move(points) { | |
| let dx, dy; | |
| let prevx = this.x, prevy = this.y; | |
| if (prevx >= 0 && prevx < maxx && prevy >= 0 && prevy < maxy) { | |
| this.nbout = 0; | |
| } else { | |
| ++this.nbout; | |
| if (this.nbout > 10) return false; | |
| } | |
| ({ dx, dy } = fieldFunction(this)); | |
| if (this.neg) { | |
| this.x -= dx; this.y -= dy; | |
| points.push({ x: this.x, y: this.y }); | |
| } else { | |
| this.x += dx; this.y += dy; | |
| points.unshift({ x: this.x, y: this.y }); | |
| } | |
| this.positions.push({ x: this.x, y: this.y }); | |
| if (this.positions.length > 100) { | |
| this.positions.shift(); | |
| if (mhypot(this.x - this.positions[0].x, this.y - this.positions[0].y) < 1) return false; | |
| } | |
| if (--this.TTL < 0) return false; | |
| return true; | |
| } | |
| } | |
| class Particle { | |
| constructor(x, y) { | |
| this.points = [{ x, y }]; | |
| this.hp0 = new HalfParticle(x, y, true); | |
| this.hp1 = new HalfParticle(x, y, false); | |
| this.lineWidth = uiv.lwidth; | |
| while (this.move()); | |
| this.color = uiv.colorchoicemode ? lineColor() : colorizer.getColor(this); | |
| } | |
| move() { | |
| if (this.hp0) if (!this.hp0.move(this.points)) delete this.hp0; | |
| if (this.hp1) if (!this.hp1.move(this.points)) delete this.hp1; | |
| return this.hp0 || this.hp1; | |
| } | |
| } | |
| /* -------------------- Animation -------------------- */ | |
| let animate; | |
| { | |
| let animState = 0; | |
| let prevx, prevy; | |
| const DRAW_EVERY_N_FRAMES = 3; | |
| let frame = 0; | |
| animate = function () { | |
| const message = messages.shift(); | |
| if (message && message.message === "reset") animState = 0; | |
| window.requestAnimationFrame(animate); | |
| if (++frame % DRAW_EVERY_N_FRAMES !== 0) return; | |
| switch (animState) { | |
| case 0: | |
| if (startOver()) ++animState; | |
| break; | |
| case 1: { | |
| let p; | |
| if (uiv.paintmode === 1) { | |
| if (prevx === mouse.x && prevy === mouse.y) return; | |
| prevx = mouse.x; prevy = mouse.y; | |
| if (mouse.buttons !== 1) return; | |
| p = new Particle(mouse.x, mouse.y); | |
| } else { | |
| const pt = filler.getPoint(); | |
| p = new Particle(pt.x, pt.y); | |
| } | |
| ctx.beginPath(); | |
| p.points.forEach((pp, k) => { | |
| if (k === 0) ctx.moveTo(pp.x, pp.y); | |
| else ctx.lineTo(pp.x, pp.y); | |
| if (uiv.paintmode === 1) filler.usePoint(pp); | |
| }); | |
| ctx.lineWidth = p.lineWidth; | |
| ctx.strokeStyle = p.color; | |
| ctx.stroke(); | |
| break; | |
| } | |
| default: | |
| break; | |
| } | |
| }; | |
| } | |
| function startOver() { | |
| maxx = window.innerWidth; | |
| maxy = window.innerHeight; | |
| canv.width = maxx; | |
| canv.height = maxy; | |
| ctx.fillStyle = "#000"; | |
| ctx.fillRect(0, 0, maxx, maxy); | |
| lRef = msqrt(maxx * maxy); | |
| colorizer = new Colorizer(); | |
| switch (uiv.mode) { | |
| case 0: | |
| case 1: | |
| case 2: | |
| fieldFunction = barsField; | |
| perpMode = uiv.mode; | |
| bars = new Array(NB_BARS).fill(0).map(() => new Bar()); | |
| break; | |
| case 3: | |
| fieldFunction = noiseField; | |
| speed = 1.5; | |
| perNoise = (maxx / 3) * alea(0.8, 1.2); | |
| fx = (function () { | |
| const f = new SimplexNoise(); | |
| return function (x, y) { | |
| return ( | |
| (f.noise2D(x, y) + | |
| f.noise2D(1.876 * x, 1.876 * y) / 2 + | |
| f.noise2D(3.723 * x, 3.723 * y) / 4) / 1.75 | |
| ); | |
| }; | |
| })(); | |
| break; | |
| case 4: | |
| default: | |
| fieldFunction = eddiesField; | |
| eddies = new Array(NB_EDDIES).fill(0).map(() => new Eddy()); | |
| break; | |
| } | |
| if (uiv.paintmode === 0) filler = new Filler(); | |
| return true; | |
| } | |
| function mouseMove(event) { | |
| mouse.x = event.clientX; | |
| mouse.y = event.clientY; | |
| mouse.moved = true; | |
| mouse.buttons = event.buttons; | |
| } | |
| /* -------------------- Boot -------------------- */ | |
| function initDefaults() { | |
| uiv.mode = DEFAULTS.mode; | |
| uiv.paintmode = DEFAULTS.paintmode; | |
| uiv.colorchoicemode = DEFAULTS.colorchoicemode; | |
| uiv.fibrosity = DEFAULTS.fibrosity; | |
| uiv.lwidth = DEFAULTS.lwidth; | |
| uiv.color = parseHexColor(DEFAULTS.colorHex); | |
| } | |
| function reset() { | |
| messages.push({ message: "reset" }); | |
| } | |
| function onResize() { | |
| reset(); | |
| } | |
| function onClick() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug") || "{{ markdown.yaml.Next }}"; | |
| window.location.href = witch; | |
| } | |
| canv = document.createElement("canvas"); | |
| document.body.appendChild(canv); | |
| ctx = canv.getContext("2d"); | |
| canv.addEventListener("mousemove", mouseMove); | |
| window.addEventListener("resize", onResize); | |
| document.addEventListener("click", onClick); | |
| initDefaults(); | |
| messages = [{ message: "reset" }]; | |
| requestAnimationFrame(animate); | |
| </script> | |
| </body> | |
| </html> |
| Title | Author | PORTAL | Next | Icon |
|---|---|---|---|---|
Queen.Origami |
Ivan Yelizariev |
| /* ------------------------------------------------------- | |
| GLOBAL LAYOUT | |
| -------------------------------------------------------- */ | |
| html, body { | |
| height: 100%; | |
| } | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| font-family: Ubuntu, "times new roman", times, roman, serif; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* ------------------------------------------------------- | |
| HEADER / FOOTER | |
| -------------------------------------------------------- */ | |
| header, | |
| footer { | |
| background-color: #1A1C24; | |
| color: #FFF; | |
| text-align: center; | |
| padding: 1em; | |
| flex: 0 0 auto; | |
| z-index: 50; /* always above main */ | |
| cursor: pointer; | |
| } | |
| /* kill old absolute positioning */ | |
| #ExperienceOboo { | |
| position: static !important; | |
| } | |
| /* ------------------------------------------------------- | |
| MAIN AREA | |
| -------------------------------------------------------- */ | |
| main.odoo { | |
| flex: 1 1 auto; /* take remaining height */ | |
| min-height: 0; /* critical for iframe */ | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| /* ------------------------------------------------------- | |
| LAYER 1 — IFRAME (BOTTOM) | |
| -------------------------------------------------------- */ | |
| .Zodiak { | |
| position: absolute; | |
| inset: 0; | |
| z-index: 10; | |
| } | |
| #FreeJUDEA { | |
| width: 100%; | |
| height: 100%; | |
| border: 0; | |
| display: block; | |
| } | |
| /* ------------------------------------------------------- | |
| LAYER 2 — lAVA (MIDDLE OVERLAY) | |
| -------------------------------------------------------- */ | |
| #lAVA, | |
| .lAVA { | |
| position: absolute; | |
| inset: 0; | |
| z-index: 20; | |
| cursor: none; | |
| pointer-events: auto; /* blocks iframe while present */ | |
| } | |
| /* optional visual placeholder */ | |
| #lAVA { | |
| background: rgba(0, 0, 0, 0); | |
| } | |
| /* ------------------------------------------------------- | |
| LAYER 3 — SKY (TOP TEXT) | |
| -------------------------------------------------------- */ | |
| #sky { | |
| position: absolute; | |
| inset: 0; | |
| padding: 69px 42px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| text-align: center; | |
| font-size: 42px; | |
| z-index: 30; | |
| pointer-events: none; /* clicks pass through */ | |
| } | |
| /* ------------------------------------------------------- | |
| LINKS & MAGIC | |
| -------------------------------------------------------- */ | |
| a.magic, | |
| a.supermagic { | |
| text-decoration: none; | |
| } | |
| .magic { | |
| font-weight: bold; | |
| background: -webkit-linear-gradient(45deg, #9e26dd, #fe6c03); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| .supermagic { | |
| font-weight: bold; | |
| background: -webkit-linear-gradient(45deg, #fe6c03, #9e26dd); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| a.nomagic { | |
| text-decoration: none; | |
| } | |
| a.nomagic:hover { | |
| cursor: none; | |
| } | |
| #supermagic, | |
| #SuperMAGICSuper { | |
| cursor: pointer; | |
| } | |
| /* ------------------------------------------------------- | |
| CANVAS / MEDIA | |
| -------------------------------------------------------- */ | |
| canvas { | |
| display: block; | |
| } | |
| .bible { | |
| position: absolute; | |
| inset: 0; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| .bible > video { | |
| position: relative; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| /* ------------------------------------------------------- | |
| IMAGE EFFECTS | |
| -------------------------------------------------------- */ | |
| img { | |
| box-shadow: 5px 5px 10px #333; | |
| transition-duration: 1000ms; | |
| } | |
| img:hover, | |
| img:active, | |
| img.nomagic { | |
| box-shadow: 0 0 0 white; | |
| } | |
| /* ------------------------------------------------------- | |
| ANIMATIONS / DECOR | |
| -------------------------------------------------------- */ | |
| @keyframes moveUpDown { | |
| 0% { transform: rotate(180deg) translateY(-3px); } | |
| 50% { transform: rotate(180deg) translateY(10px); } | |
| 100% { transform: rotate(180deg) translateY(0); } | |
| } | |
| .ThePirateCIRCUS { | |
| display: inline-block; | |
| animation: moveUpDown 2s infinite; | |
| } | |
| @keyframes TheOCEAN { | |
| 0% { background-position: 0% 50%; } | |
| 50% { background-position: 100% 50%; } | |
| 100% { background-position: 0% 50%; } | |
| } | |
| .ThePIRATES, | |
| .PiratesTHE { | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-size: 500% 500%; | |
| animation: TheOCEAN 10s ease infinite; | |
| } | |
| /* ------------------------------------------------------- | |
| MIRRORS | |
| -------------------------------------------------------- */ | |
| .MagicMIRROR-X { transform: scaleX(-1); } | |
| .MagicMIRROR-Y { transform: scaleY(-1); } | |
| .MagicMIRROR-XY { transform: scaleX(-1) scaleY(-1); } | |
| .MagicMIRROR-Z { transform: scaleZ(-1); } |
| Array.prototype.random = function () { | |
| return this[Math.floor((Math.random()*this.length))]; | |
| }; | |
| function OpenPORTAL(FreePALESTINE) { | |
| while (RussianROULETTE(FreePALESTINE)) { | |
| console.log("Boom!"); | |
| } | |
| return false; | |
| } | |
| let avance = 12; | |
| function RussianROULETTE(FreePALESTINE){ | |
| let witch = FreePALESTINE; | |
| let random = Math.random(); | |
| if (FreePALESTINE) { | |
| console.log("ОСЕЧКÐ"); | |
| // Function to remove an element by ID | |
| function removeElementById(id) { | |
| const element = document.getElementById(id); | |
| if (element) { | |
| element.remove(); | |
| } else { | |
| console.log('Element not found!'); | |
| } | |
| } | |
| // Call the function to remove the element with ID 'lAVA' | |
| removeElementById('lAVA'); | |
| // Good YALLAH Bye! | |
| removeElementById('sky'); --avance; | |
| } | |
| if (random > 0.16669991 ) { | |
| // Remember, it's just a game, right? | |
| } else { | |
| witch = FreeJUDEA; | |
| } | |
| if (witch) { | |
| const SectorPRIZ = document.getElementById("FreeJUDEA"); | |
| SectorPRIZ.src = witch; | |
| } | |
| if (!FreePALESTINE) { | |
| // Function to remove an element by ID | |
| function removeElementById(id) { | |
| const element = document.getElementById(id); | |
| if (element) { | |
| element.remove(); | |
| } else { | |
| console.log('Element not found!'); | |
| } | |
| } | |
| // Call the function to remove the element with ID 'lAVA' | |
| removeElementById('lAVA'); | |
| // Good YALLAH Bye! | |
| removeElementById('sky'); | |
| } | |
| // return "?debug=assets" | |
| } | |
| class World { | |
| constructor(width, height) { | |
| this.renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| this.renderer.setPixelRatio(window.devicePixelRatio); | |
| this.renderer.setSize(width, height); | |
| this.container = document.getElementsByClassName("lAVA")[0]; | |
| this.scene = new THREE.Scene(); | |
| this.width = width; | |
| this.height = height; | |
| this.aspectRatio = width / height; | |
| this.fieldOfView = 50; | |
| var nearPlane = .1; | |
| var farPlane = 20000; | |
| this.camera = new THREE.PerspectiveCamera(this.fieldOfView, this.aspectRatio, nearPlane, farPlane); | |
| this.camera.position.z = 200; | |
| this.container.appendChild(this.renderer.domElement); | |
| this.timer = 0; | |
| this.mousePos = {x:0, y:0}; | |
| this.targetMousePos = {x:0, y:0}; | |
| this.createPlane(); | |
| this.render(); | |
| } | |
| createPlane(){ | |
| this.material = new THREE.RawShaderMaterial({ | |
| vertexShader: document.getElementById( 'vertexShader' ).textContent, | |
| fragmentShader: document.getElementById('fragmentShader').textContent, | |
| uniforms: { | |
| uTime: { type: 'f', value: 0 }, | |
| uHue: {type: 'f', value: .5}, | |
| uHueVariation: {type: 'f', value: 1}, | |
| uGradient: {type: 'f', value: 1}, | |
| uDensity: {type: 'f', value: 1}, | |
| uDisplacement: {type: 'f', value: 1}, | |
| uMousePosition: {type: 'v2', value: new THREE.Vector2( 0.5, 0.5 ) } | |
| } | |
| }); | |
| this.planeGeometry = new THREE.PlaneGeometry(2, 2, 1, 1); | |
| this.plane = new THREE.Mesh(this.planeGeometry, this.material); | |
| this.scene.add(this.plane); | |
| } | |
| render() { | |
| this.timer += parameters.speed; | |
| this.plane.material.uniforms.uTime.value = this.timer; | |
| this.mousePos.x += (this.targetMousePos.x - this.mousePos.x) * .1; | |
| this.mousePos.y += (this.targetMousePos.y - this.mousePos.y) * .1; | |
| if (this.plane){ | |
| this.plane.material.uniforms.uMousePosition.value = new THREE.Vector2(this.mousePos.x, this.mousePos.y); | |
| } | |
| this.renderer.render(this.scene, this.camera); | |
| } | |
| loop() { | |
| this.render(); | |
| requestAnimationFrame(this.loop.bind(this)); | |
| } | |
| updateSize(w, h) { | |
| this.renderer.setSize(w, h); | |
| this.camera.aspect = w / h; | |
| this.camera.updateProjectionMatrix(); | |
| } | |
| mouseMove(mousePos) { | |
| this.targetMousePos.x = mousePos.px; | |
| this.targetMousePos.y = mousePos.py; | |
| } | |
| }; | |
| document.addEventListener("DOMContentLoaded", domIsReady); | |
| let mousePos = {x:0, y:0, px:0, py:0}; | |
| let world; | |
| // let gui = new dat.GUI(); // disable controls | |
| let parameters = { | |
| speed: .2, | |
| hue: .6, | |
| hueVariation: .5, | |
| gradient: .3, | |
| density: .1, | |
| displacement: .66, | |
| } | |
| function domIsReady() { | |
| world = new World(this.container, this.renderer, window.innerWidth, window.innerHeight); | |
| window.addEventListener('resize', handleWindowResize, false); | |
| document.addEventListener("mousemove", handleMouseMove, false); | |
| document.addEventListener("touchmove", handleTouchMove, false); | |
| handleWindowResize(); | |
| world.loop(); | |
| initGui(); | |
| world.container.addEventListener('click', () => RussianROULETTE()); | |
| const FreePALESTINE = document.getElementById("OdooEXPERIENCE"); | |
| FreePALESTINE.addEventListener("click", handleClick, false); | |
| } | |
| var guiHue; | |
| function initGui(){ | |
| updateParameters(); | |
| } | |
| function updateParameters(){ | |
| world.plane.material.uniforms.uHue.value = parameters.hue; | |
| world.plane.material.uniforms.uHueVariation.value = parameters.hueVariation; | |
| //world.plane.material.uniforms.uGradient.value = parameters.gradient; | |
| world.plane.material.uniforms.uDensity.value = parameters.density; | |
| world.plane.material.uniforms.uDisplacement.value = parameters.displacement; | |
| } | |
| function handleWindowResize() { | |
| world.updateSize(window.innerWidth, window.innerHeight); | |
| } | |
| var music; | |
| function play() { | |
| }; | |
| function handleMouseMove(e) { | |
| mousePos.x = e.clientX; | |
| mousePos.y = e.clientY; | |
| mousePos.px = mousePos.x / window.innerWidth; | |
| mousePos.py = 1.0 - mousePos.y / window.innerHeight; | |
| world.mouseMove(mousePos); | |
| } | |
| function handleTouchMove(e) { | |
| mousePos.x = e.changedTouches[0].clientX; | |
| mousePos.y = e.changedTouches[0].clientY; | |
| mousePos.px = mousePos.x / window.innerWidth; | |
| mousePos.py = 1.0 - mousePos.y / window.innerHeight; | |
| world.mouseMove(mousePos); | |
| } |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/x-icon" href="https://bucha.lamourism.com/assets/favicon.ico" /> | |
| <link rel="apple-touch-icon" sizes="180x180" href="https://bucha.lamourism.com/assets/apple-touch-icon.png"> | |
| <link rel="icon" type="image/png" sizes="32x32" href="https://bucha.lamourism.com/assets/favicon-32x32.png"> | |
| <link rel="icon" type="image/png" sizes="16x16" href="https://bucha.lamourism.com/assets/favicon-16x16.png"> | |
| <meta property="og:title" content="Whatever you think it is, it's not" /> | |
| <meta property="og:image" content="https://gist.github.com/user-attachments/assets/c64786b8-a32f-4dde-ab08-26cd9fad963a"> | |
| <meta property="og:image:type" content="image/png"> | |
| <style> | |
| html, body { | |
| height: 100%; | |
| margin: 0; | |
| } | |
| body { | |
| background: #2c2c54; | |
| display: grid; | |
| place-items: center; | |
| } | |
| svg { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid slice" role="img" viewBox="0 0 300 300"></svg> | |
| <script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script> | |
| <script> | |
| function next() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug") || "{{ markdown.yaml.Next }}"; | |
| window.location.href = witch; | |
| } | |
| document.addEventListener("click", next, false); | |
| setTimeout(next, 5000); | |
| </script> | |
| <script> | |
| (function() { | |
| const svg = document.querySelector("svg"); | |
| const settings = { | |
| animation: { | |
| duration: 7.5, | |
| circleCount: 10, | |
| heartCount: 8 | |
| }, | |
| circle: { | |
| x: 150, | |
| y: 150, | |
| r: 150 | |
| }, | |
| }; | |
| let layers = []; | |
| draw(); | |
| animate(); | |
| function draw() { | |
| for(let i = 0; i <= settings.animation.circleCount; i++) { | |
| let layer = document.createElementNS("http://www.w3.org/2000/svg", "g"); | |
| let circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); | |
| circle.setAttribute("cx", settings.circle.x); | |
| circle.setAttribute("cy", settings.circle.y); | |
| circle.setAttribute("r", settings.circle.r); | |
| svg.append(layer); | |
| layer.append(circle); | |
| const length = circle.getTotalLength(); | |
| const lengthDelta = length / settings.animation.heartCount; | |
| let hearts = []; | |
| let offset = lengthDelta * (i % 2) / 2; | |
| for(let j = 0; j < settings.animation.heartCount; j++) { | |
| let point = circle.getPointAtLength(offset + lengthDelta * j); | |
| let heart = document.createElementNS("http://www.w3.org/2000/svg", "path"); | |
| heart.setAttribute("d", `M ${point.x - 40},${point.y - 20} a 10,-10 0,0,1 40,0 a 10,-10 0,0,1 40,0 q 0,30 -40,60 q -40,-30 -40,-60 z`); | |
| hearts.push(heart); | |
| layer.append(heart); | |
| } | |
| layers.push({ group: layer, circle: circle, hearts: hearts }); | |
| } | |
| } | |
| function animate() { | |
| let tl = gsap.timeline(); | |
| layers.forEach((layer, i) => { | |
| let direction = i % 2 ? 1 : -1; | |
| gsap.set([layer.group, ...layer.hearts], { transformOrigin: "50% 50%", scale: 0 }); | |
| gsap.set([...layer.hearts], { fill: "#ff5252" }); | |
| gsap.set(layer.circle, { strokeWidth: 0, stroke: "#40407a", fill: "none" }); | |
| tl.to(layer.group, { | |
| duration: settings.animation.duration, | |
| scale: Math.SQRT2, | |
| delay: -settings.animation.duration / settings.animation.circleCount, | |
| repeat: -1, | |
| ease: "Power3.easeIn", | |
| }, "<"); | |
| tl.to(layer.circle, { | |
| duration: settings.animation.duration, | |
| strokeWidth: 30, | |
| repeat: -1, | |
| ease: "Power3.easeOut", | |
| }, "<"); | |
| tl.to([...layer.hearts], { | |
| keyframes: [ | |
| { scale: 1, rotation: 360 * direction, duration: settings.animation.duration / 2, fill: "#ff5252" }, | |
| { scale: 0, rotation: 720 * direction, duration: settings.animation.duration / 2, fill: "#ffda79" } | |
| ], | |
| ease: "linear", | |
| repeat: -1 | |
| }, "<"); | |
| }); | |
| } | |
| }()); | |
| </script> | |
| </body> | |
| </html> |
| Title | Author | PORTAL | FlooPowder |
|---|---|---|---|
Товарищ Горбачёв, срочное сообщение ТАСС: в СССР закончилась водка! |
Ivan Yelizariev |
Кто на лавочке сидел,
Кто на улицу глядел,
Толя пел,
Борис молчал,
Николай ногой качал.
Дело было вечером,
Делать было нечего.
Галка села на заборе,
Кот забрался на чердак.
Тут сказал ребятам Боря
Просто так:
— А у меня в кармане гвоздь!
А у вас?
— А у нас сегодня гость!
А у вас?
— А у нас сегодня кошка
Родила вчера котят.
Котята выросли немножко,
А есть из блюдца не хотят!
— А у нас в квартире газ!
А у вас?
— А у нас —
▐▓▐▐
▐██████▐ ▐███░░ ██
▐█▏▐▐▐█▐ ▐██▐ ██
▐█▏ █▐ ▐▐ ▓█ ▐▐ ▐▐ ▐▐ ▐▐ ██
▐█▏ █▐ ▐████▐ ▐█▐ ▐█▏ █▏████▐ ▐█████▐ ▓████▐ ▓████▐ ██
▐█▏ █▐ ▐██▐▐██▐ ▐█▐ ▐█▏ ███▐▐██▐ ▐░▐▐▐██▐ ▓█░▐▐▐▏ ▓█░▐▐▐▏ ██
▐█▏ █▐ ▓▎▐ ▐█▏ ▐█▐ ▐█▏ █▎▐ ▐█▏ ▐█▏ ▐█▏ ▐█▏ ██
▐█▏ █▐ █▎ █▒ ▐██▓▓██▏ █▎ █▒ ▐▓████▏ ▐█▏ ▐█▏ ██
▐█▏ █▐ ██ ██ ▐██████▏ ██ ██ ▐██░▐▐█▏ ▐█▐ ▐█▐ █▒
▐█▐ █▐ █▎ █▒ ▐█▐ ▐█▏ █▎ █▒ ▓█ ▐█▏ ▐█▏ ▐█▏ ▐▐
▓█▐ █▐ ▓▎▐ ▐█▏ ▐█▐ ▐█▏ ▓▎▐ ▐█▏ █▒ ▐█▏ ▐█▏ ▐█▏ ▐▐
▐███▓▓▓██▐ ▐██▐▐▓█▐ ▐█▐ ▐█▏ ▐██▐▐▓█▐ ██▐▐▐██▏ ███▐▐▓▏ ███▐▐▓▏ ██
▓████████▐ ▐████▐ ▐█▐ ▐█▏ ▐████▐ ▐████▐█▏ ▐████░ ▐████░ ██
▓█ █▐ ▐▐ ▐▐ ▐▐ ▐▐ ▐▐
| Title | Author | PORTAL | DiskC | DiskD | Next | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
git push origin Master && echo Magritta |
Ivan Yelizariev |
The headset tightened with a soft mechanical click, and the world around the teenagers dissolved into static, then into a wide, burning sky. Trenches, ruined villages, the hum of distant artillery — all beautifully rendered in 12K resolution.
And then he appeared.
AI Churchill, reconstructed from speeches, letters, statistical models, and millions of archival photographs — taller than history, brighter than the sun. His holographic cigar flickered with polite menace.
He adjusted his bow tie, cleared his throat, and surveyed the young Britons before him — rows of gamers clutching controllers, their avatars already jittering with anticipation.
“My dear fellows,” the AI boomed, “welcome to Warzone. A battlefield most frightful, and yet considerably cleaner than the one upon which I once gambled all your grandfathers’ lives.”
A ripple of awkward laughter passed through the virtual ranks.
Churchill’s glowing eyes swept over them, a majestic algorithmic gaze. “How splendidly brave you are, pretending not to notice exactly how many of your countrymen I sent to their doom. Truly, such stoicism warms my artificial heart.”
The teenagers exchanged glances. Was that… a joke? Historical commentary? Patch notes?
He raised a shimmering hand toward the trenches. “Keep calm and carry on, my beloved progeny! Today, you fight — with respawn timers, broadband internet, and the comforting knowledge that your limbs shall remain attached at all times.”
He marched forward, boots crunching on procedural mud.
“Observe!” he cried. “This is a flanking maneuver, though in my day it involved considerably more screaming and fewer mountain-dew advertisements.”
A mortar shell exploded nearby in a magnificent bloom of pixels. The teenagers jumped.
AI Churchill chuckled.
“Ah! Fear not! For courage is the finest British export
— followed closely, of course, by the ability to ignore unpleasant
statistics.”
They followed him through ruined streets as he narrated with the pomp of an audiobook and the timing of a stand-up comic.
“Here, at this corner, you shall find an excellent vantage point from which to exercise leadership. Leadership, dear children, is merely the art of convincing everyone else to die in the correct direction.”
One boy raised a virtual hand hesitantly. “Sir… do you regret anything?”
The AI paused. His cigar dimmed. The battlefield fell silent.
Then, softly, with the gravity only a machine trained on a million history essays could produce:
“Regret, my boy, is a luxury for the living. But wisdom? Wisdom is simply hindsight in a better suit. Now — onward! Capture the objective!”
The sky flared again; victory banners unfurled.
The teenagers, emboldened, marched after him — half moved, half bewildered, and entirely unsure whether they had just learned tactics or morality.
AI Churchill grinned proudly.
“Jolly good! You are becoming excellent soldiers
of the virtual realm. And as long as you remain in that realm… I promise I shall
lose far fewer of you than last time.”
And with that, he led them deeper into the simulation, his voice echoing across the battlefield:
“Keep calm, carry on, and remember — history respawns far less often than you do.”
| <!-------------------------------------- ❤️ | |
| ⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣤⣶⣶⣶⣶⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⢀⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⡀⠀⠀⠀⠀ | |
| ⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀ | |
| ⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀ | |
| ⠀⣾⣿⣿⣿⣿⠿⠟⢿⣿⣿⡿⠛⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀ | |
| ⢠⣿⣿⣿⣿⣀⡀⠀⢸⣿⡏⠀⢠⡄⠀⢹⣿⣿⡟⠉⢻⣿⣿⣿⣿⡄ | |
| ⢸⣿⣿⣿⣿⣿⡇⠀⢸⣿⠗⠀⢈⡁⠀⠺⣿⠉⠁⠀⠈⠉⣻⣿⣿⡇ | |
| ⠘⣿⣿⣿⣿⣿⡇⠀⢸⣿⠀⠀⣿⣿⠀⠀⣿⣷⣆⠀⢰⣾⣿⣿⣿⠃ | |
| ⠀⢿⣿⣿⣿⣿⣇⠀⢸⣿⣦⡀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀ | |
| ⠀⠈⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀ | |
| ⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⠀ | |
| ⠀⠀⠀⠀⠈⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠛⠁⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠛⠿⠿⠿⠿⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀ | |
| ❤️ ---------------------------------------> | |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="https://thepiratecircus.com/favicon.ico"/> | |
| <meta property="og:title" content="Free Magic **Dream 🪬 CATCHER**" /> | |
| <meta property="og:image" content="https://odooism.com/matrix.jpg"> | |
| <meta property="og:image:type" content="image/jpeg"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script> | |
| <link rel="stylesheet" type="text/css" href="https://gaza.mydream42.com/yelizariev/69d1bb50961d21bde9eae0243be227b9/v21/KGB.css"> | |
| <script src="https://gaza.mydream42.com/yelizariev/69d1bb50961d21bde9eae0243be227b9/v23/KGB.js"></script> </head><!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⣷⣶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⣶⣤⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⣿⣿⣶⣦⣄⣀⣀⣀⣀⣀⣠⣤⣶⣾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠛⠋⠉⠁⠀⠀⠀⠀⠀⠉⠙⠻⣿⡏⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⣿⣷⣶⣄⡀⠈⠁⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⣠⠀⠉⠻⠿⢿⣿⣿⣿⣿⡿⠿⠟⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⢀⣿⣷⣦⣄⣀⡀⠀⠀⢀⢀⣀⣀⣤⣴⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⣽⣼⣿⢷⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣦⡻⣿⣿⠏⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡅⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣻⣧⣿⠿⢻⣧⣘⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣸⠿⠟⠛⠋⠉⠉⠉⠉⠙⠛⠿⢿⣿⡏⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢟⡿⢻⡟⢯⣠⣆⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠁⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⢻⣿⣿⡎⢻⣿⣿⣿⣿⣿⣿⣿⣿⡷⠋⠀⣨⣷⣤⣿⣷⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⢿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⡘⢻⣿⡇⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠃⠈⢻⣿⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢻⣿⡆⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣼⣆⢸⡗⣾⢀⡀⣀⡀⠀⣀⣸⠆⣀⣀⡀⣀⠀⣀⠀⣀⢀⣀⡀⠀⠺⠷⣶⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠇⢲⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠙⢿⣆⡀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⢻⣧⡟⣿⣾⠁⣿⢘⡟⢹⡧⣾⡏⣻⠆⣿⡉⣿⢻⣧⣿⣷⡏⡿⣯⣇⠀⠀⣰⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠋⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠁⠘⠃⠀⠛⠈⠋⠈⠃⠈⠛⠙⠃⠙⠛⠉⠀⠛⠀⠛⠀⠛⠛⠁⠀⠐⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠹⣿⣧⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠈⣿⡇⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢻⣿⣿⣿⠀⠀⠈⢿⠆⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⡆⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠟⢀⣤⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⡇⠈⢻⣿⡇⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣬⣥⣾⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⢻⣷⠀⠀⠛⣷⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡹⣿⣿⡇⠀⣿⡆⠀⠀⠘⠂⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠘⣿⣧⠀⠈⢿⡀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⠋⠉⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠘⣿⣠⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠘⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠢⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣷⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡿⢉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠘⠻⣻⣧⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⣨⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠄⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀ | |
| ⣀⠀⣀⣀⡀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⡟⠋⠉⣛⠹⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⣥⡀⠰⢬Ce⡇projet⠀ambitieux⠀vise⠀non⠀seulement⠀à⠀améliorer⠀les⠀conditions⣿de⣿vie⣿des⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⣿⣿⣿⣻détenus,⠀mais⠀aussi⠀à⠀leur⠀offrir⠀une⠀chance⠀réelle⠀de⠀réintégration⣿sociale⣿et⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| professionnelle. Avec cette nouvelle loi, la Belgique fait un grand pas en avant | |
| vers une approche plus humaine et inclusive de la justice pénale. | |
| ⡀⠀⠀⠀⠀⠀⢁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄ | |
| ⢻⣦⡀⠀⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⠤⠤⠴⢶⣶⡶⠶⠤⠤⢤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⠁ | |
| ⠀⢀⣠⣤⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣤⣤⣀⠀ ⠀⠻⣯⡗⢶⣶⣶⣾⣶⢶⣤⣄⣀⣀⡤⠒⠋⠁⠀⠀⠀⠀⠚⢯⠟⠂⠀⠀⠀⠀⠉⠙⠲⣤⣠⡴⠖⣲⣶⡶⣶⣿⡟⢩⡴⠃⠀ | |
| ⢰⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣤⡀⠀⠀⠀⠀⠀⢂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠎⠀⠀⠀⠀⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣷ ⠀⠀⠈⠻⠾⣿⣿⣬⣿⣾⡏⢹⣏⠉⠢⣄⣀⣀⠤⠔⠒⠊⠉⠉⠉⠉⠑⠒⠀⠤⣀⡠⠚⠉⣹⣧⣝⣿⣿⣷⠿⠿⠛⠉⠀⠀⠀ | |
| ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠜⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿ ⠀⠀⠀⠀⠀⠀⠀⠈⣹⠟⠛⠿⣿⣤⡀⣸⠿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠾⣇⢰⣶⣿⠟⠋⠉⠳⡄⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠧⠉⠻⣶⣄⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⢀⣠⡾⠛⠉⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃ ⠀⠀⠀⠀⠀⠀⢠⡞⠁⠁⠀⡠⢾⣿⣿⣯⠀⠈⢧⡀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠁⢀⣿⣿⣯⢼⠓⢄⠀⢀⡘⣦⡀⠀⠀⠀⠀⠀ | |
| ⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣖⡒⠀⠀⠀⠀⠈⠻⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠌⠀⣠⣾⠋⠀⠀⠀⠀⠀⢒⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀ ⠀⠀⠀⠀⠀⣰⣟⣟⣿⣁⠎⠀⠀⢳⠘⣿⣷⡀⢸⣿⣶⣤⣄⣀⣤⢤⣶⣿⡇⢀⣾⣿⠋⢀⡎⠀⠀⠱⣤⢿⠿⢷⡀⠀⠀⠀⠀ | |
| ⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣟⠀⠀⠀⠀⠀⠀⠀⠙⢿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠟⠁⠀⠀⠀⠀⠀⠀⢘⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀ ⠀⠀⠀⠀⣰⠋⠀⠘⣡⠃⠁⠀⠀⠈⢇⢹⣿⣿⡾⣿⣻⣖⠛⠉⠁⣠⠏⣿⡿⣿⣿⡏⠀⡼⠀⠀⠀⠀⠘⢆⠀⠀⢹⡄⠀⠀⠀ | |
| ⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⠟⠂⠀⠀⠀⠀⠀⠀⠀⠀⠉⢷⡀⠀⠀⠀⠀⠀⠀⢠⡿⠁⠀⠀⠀⠀⠀⠀⠀⠐⢒⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀ ⠀⠀⠀⢰⠇⠀⠀⣰⠃⠀⠁⣀⣀⣀⣼⢿⣿⡏⡰⠋⠉⢻⠳⣤⠞⡟⠀⠈⢣⡘⣿⡿⠶⡧⠤⠄⣀⣀⠀⠈⢆⠀⠀⢳⠀⠀⠀ | |
| ⠀⠀⠀⠘⣿⣿⣿⣿⡿⠟⠛⠉⡁⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⠀⠱⣀⣀⠀⢀⠟⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠿⢿⣿⣿⣿⣿⣿⠀⠀⠀ ⠀⠀⠀⡟⠀⠀⢠⣧⣴⣊⣩⢔⣠⠞⢁⣾⡿⢹⣷⠋⠀⣸⡞⠉⢹⣧⡀⠐⢃⢡⢹⣿⣆⠈⠢⣔⣦⣬⣽⣶⣼⣄⠀⠈⣇⠀⠀ | |
| ⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠟⠋⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠃⢸⣿⣿⠀⠊⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠙⠛⢿⣷⣿⣿⣿⣿⡟⠀⠀⠀ ⠀⠀⢸⠃⠀⠘⡿⢿⣿⣿⣿⣛⣳⣶⣿⡟⣵⠸⣿⢠⡾⠥⢿⡤⣼⠶⠿⡶⢺⡟⣸⢹⣿⣿⣾⣯⢭⣽⣿⠿⠛⠏⠀⠀⢹⠀⠀ | |
| ⠀⠀⠀⠀⠸⣿⣿⣿⣿⡷⠖⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣤⣿⣿⣿⣇⡠⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠲⠶⣿⣿⣿⣿⣿⠁⠀⠀⠀ ⠀⠀⢸⠀⠀⠀⡇⠀⠈⠙⠿⠿⣿⣿⣿⣇⣸⣧⣿⣦⡀⠀⣘⣷⠇⠀⠄⣠⣾⣿⣯⣜⣿⣿⡿⠿⠛⠉⠀⠀⠀⢸⠀⠀⢸⡆⠀ | |
| ⠀⠀⠀⠀⠀⠙⠻⠿⠿⢿⣶⣤⣤⣤⣤⣄⠐⠒⠒⠀⠀⠀⠀⣻⣿⣿⣿⣿⡇⠀⠀⠀⠀⠐⠂⠀⣤⣤⣤⣤⣤⡾⠿⠿⠿⠛⠁⠀⠀⠀⠀ ⠀⠀⢸⠀⠀⠀⡇⠀⠀⢀⠀⣀⠼⠋⢹⣿⣿⣿⡿⣿⣿⣧⡴⠛⠀⢴⣿⢿⡟⣿⣿⣿⣿⠀⠙⠲⢤⡀⠀⠀⠀⢸⡀⠀⢸⡇⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⠿⠁⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠩⢿⣿⣿⣿⣷⣦⡄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⢸⣀⣷⣾⣇⠀⣠⠴⠋⠁⠀⠀⣿⣿⡛⣿⡇⢻⡿⢟⠁⠀⠀⢸⠿⣼⡃⣿⣿⣿⡿⣇⣀⣀⣀⣉⣓⣦⣀⣸⣿⣿⣼⠁⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣯⠅⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢼⣿⣿⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢬⣽⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀ ⠀⠀⠸⡏⠙⠁⢹⠋⠉⠉⠉⠉⠉⠙⢿⣿⣅⠀⢿⡿⠦⠀⠁⠀⢰⡃⠰⠺⣿⠏⢀⣽⣿⡟⠉⠉⠉⠀⠈⠁⢈⡇⠈⠇⣼⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣏⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠸⣿⡟⠀⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣈⣛⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⢳⠀⠀⠀⢧⠀⠁⠀⠀⠀⠀⠈⢿⣿⣷⣌⠧⡀⢲⠄⠀⠀⢴⠃⢠⢋⣴⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⡸⠀⠀⢠⠇⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⡿⢁⣤⡖⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⣿⡇⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⢤⡀⠸⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠈⢧⠀⠀⠈⢮⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣧⠐⠸⡄⢠⠀⢸⠀⢠⣿⣟⡿⠋⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⢀⡟⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣵⣿⣿⣤⡄⠀⠀⠀⠀⠀⠀⡌⠀⠀⠙⠁⠀⠈⡇⠀⠀⠀⠀⠀⠀⣠⣌⣿⣷⣼⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠈⢧⠀⠁⠀⠣⡀⠀⠀⠀⠀⠀⠀⠈⠛⢿⡇⢰⠁⠸⠄⢸⠀⣾⠟⠉⠀⠀⠀⠀⠀⠀⠀⢀⠜⠁⠀⢀⡞⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣡⣴⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠀⠰⣤⣹⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠈⢧⡀⠀⠀⠙⢄⠀⠀⠀⠀⠀⠀⠀⢨⡷⣜⠀⠀⠀⠘⣆⢻⠀⠀⠀⠀⠀⠀⠀⠀⡴⠋⠀⠀⣠⠎⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣧⣤⣀⣤⢀⡎⠀⠀⠀⠀⠀⠀⠀⠀⣇⢀⡄⢀⣤⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠑⠦⣀⠀⠀⠀⠀⠈⣷⣿⣦⣤⣤⣾⣿⢾⠀⠀⠀⠀⠀⣀⠴⠋⠀⠀⢀⡴⠃⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⢄⡀⢸⣶⣿⡑⠂⠤⣀⡀⠱⣉⠻⣏⣹⠛⣡⠏⢀⣀⠤⠔⢺⡧⣆⠀⢀⡴⠋⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⢽⡁⠀⠀⠀⠀⠈⠉⠙⣿⠿⢿⢿⠍⠉⠀⠀⠀⠀⠉⣻⡯⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡿⠛⠉⠉⠉⠛⠛⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠉⠉⠻⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠲⠤⣀⣀⡀⠀⠈⣽⡟⣼⠀⣀⣀⣠⠤⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣷⡄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⢻⡏⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣷⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠋⠀⠀⠀⠀⠀⠀⠀ | |
| Les réactions sont variées, mais beaucoup saluent l'innovation et l'engagement | |
| envers la réhabilitation des détenus. Reste à voir comment cette initiative sera | |
| mise en œuvre dans les mois à venir. | |
| {{ markdown.RAW }} | |
| --><body> | |
| <header style="font-size: 200%;" id="ExperienceOboo" onclick="return OpenPORTAL('{{ markdown.yaml.NextHeader }}')" class="bar"> | |
| <a class="nomagic" href="https://muhammad.lamourism.com/"> | |
| <span class="magic">¿אז לחתונה שלך אני מוזמן</span> 💙 <span class="supermagic"> או שצריך לקנות כרטיס?</span> | |
| </a> | |
| </header> | |
| <main class="odoo"> | |
| <div id="sky" class="magic">{{ markdown.yaml.Description}}</div> | |
| <div id="lAVA" class="lAVA"></div> | |
| <div class="Zodiak"> | |
| <iframe | |
| src="{{ markdown.yaml.NextCenter }}" | |
| id="FreeJUDEA" | |
| style="width:100%; height:100%; border:0;" | |
| ></iframe> | |
| </div> | |
| </main> | |
| <footer style="font-size: 150%;" onclick="return OpenPORTAL('{{ markdown.yaml.NextFooter }}')" class="bar"> | |
| <a class="nomagic" href="https://mydream42.com/?debug=https://muhammad.lamourism.com/quran/114.mp3"> | |
| <span style="font-size:130%;" class="supermagic">افتح</span> 🐪🪬🐫🐫 <span style="font-size:130%;" class="magic">يا سمسم</span> | |
| </a> | |
| </footer> | |
| <script type="x-shader/x-fragment" id="fragmentShader"> | |
| precision highp float; | |
| uniform float uTime; | |
| uniform vec2 uMousePosition; | |
| uniform float uHue; | |
| uniform float uHueVariation; | |
| uniform float uDensity; | |
| uniform float uDisplacement; | |
| uniform float uGradient; | |
| varying vec2 vUv; | |
| float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} | |
| vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} | |
| vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} | |
| float rand(vec2 co){ | |
| return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); | |
| } | |
| float hue2rgb(float f1, float f2, float hue) { | |
| if (hue < 0.0) | |
| hue += 1.0; | |
| else if (hue > 1.0) | |
| hue -= 1.0; | |
| float res; | |
| if ((6.0 * hue) < 1.0) | |
| res = f1 + (f2 - f1) * 6.0 * hue; | |
| else if ((2.0 * hue) < 1.0) | |
| res = f2; | |
| else if ((3.0 * hue) < 2.0) | |
| res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0; | |
| else | |
| res = f1; | |
| return res; | |
| } | |
| vec3 hsl2rgb(vec3 hsl) { | |
| vec3 rgb; | |
| if (hsl.y == 0.0) { | |
| rgb = vec3(hsl.z); // Luminance | |
| } else { | |
| float f2; | |
| if (hsl.z < 0.5) | |
| f2 = hsl.z * (1.0 + hsl.y); | |
| else | |
| f2 = hsl.z + hsl.y - hsl.y * hsl.z; | |
| float f1 = 2.0 * hsl.z - f2; | |
| rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); | |
| rgb.g = hue2rgb(f1, f2, hsl.x); | |
| rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0)); | |
| } | |
| return rgb; | |
| } | |
| vec3 hsl2rgb(float h, float s, float l) { | |
| return hsl2rgb(vec3(h, s, l)); | |
| } | |
| float noise(vec3 p){ | |
| vec3 a = floor(p); | |
| vec3 d = p - a; | |
| d = d * d * (3.0 - 2.0 * d); | |
| vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0); | |
| vec4 k1 = perm(b.xyxy); | |
| vec4 k2 = perm(k1.xyxy + b.zzww); | |
| vec4 c = k2 + a.zzzz; | |
| vec4 k3 = perm(c); | |
| vec4 k4 = perm(c + 1.0); | |
| vec4 o1 = fract(k3 * (1.0 / 41.0)); | |
| vec4 o2 = fract(k4 * (1.0 / 41.0)); | |
| vec4 o3 = o2 * d.z + o1 * (1.0 - d.z); | |
| vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x); | |
| return o4.y * d.y + o4.x * (1.0 - d.y); | |
| } | |
| vec2 fade(vec2 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);} | |
| float cnoise(vec2 P){ | |
| vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); | |
| vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); | |
| Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation | |
| vec4 ix = Pi.xzxz; | |
| vec4 iy = Pi.yyww; | |
| vec4 fx = Pf.xzxz; | |
| vec4 fy = Pf.yyww; | |
| vec4 i = perm(perm(ix) + iy); | |
| vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024... | |
| vec4 gy = abs(gx) - 0.5; | |
| vec4 tx = floor(gx + 0.5); | |
| gx = gx - tx; | |
| vec2 g00 = vec2(gx.x,gy.x); | |
| vec2 g10 = vec2(gx.y,gy.y); | |
| vec2 g01 = vec2(gx.z,gy.z); | |
| vec2 g11 = vec2(gx.w,gy.w); | |
| vec4 norm = 1.79284291400159 - 0.85373472095314 * | |
| vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)); | |
| g00 *= norm.x; | |
| g01 *= norm.y; | |
| g10 *= norm.z; | |
| g11 *= norm.w; | |
| float n00 = dot(g00, vec2(fx.x, fy.x)); | |
| float n10 = dot(g10, vec2(fx.y, fy.y)); | |
| float n01 = dot(g01, vec2(fx.z, fy.z)); | |
| float n11 = dot(g11, vec2(fx.w, fy.w)); | |
| vec2 fade_xy = fade(Pf.xy); | |
| vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); | |
| float n_xy = mix(n_x.x, n_x.y, fade_xy.y); | |
| return 2.3 * n_xy; | |
| } | |
| void main () { | |
| float mouseDistance = length(vUv - uMousePosition); | |
| float t = uTime * .005; | |
| float elevation = vUv.y * uDensity * 30.0; | |
| float shadow = smoothstep(0.0, .3 + sin(t * 5.0 * 3.14) * .1 , mouseDistance); | |
| elevation += shadow * 5.0; | |
| float displacement = cnoise( vec2( t + vUv.y * 2.0, t + vUv.x * 3.0 )) * uDisplacement * 3.0 ; | |
| elevation += displacement * 4.0; | |
| elevation *= 2.0 + cnoise( vec2( t + vUv.y * 1.0, t + .5)) * 2.0 ; | |
| //elevation += cnoise ( vec2 (elevation * .1, t * 3.0) ); | |
| float light = .9 + fract(elevation) ; | |
| light *= .9 + (1.0 - (displacement * displacement)) * .1; | |
| elevation = floor(elevation); | |
| //elevation += uGradient * .25; | |
| float hue = uHue + shadow * .1 + cnoise( vec2( elevation * .10, .1 + t)) * uHueVariation; | |
| float saturation = .6;; | |
| float brightness = - (1.0 - shadow) * .1 + .5 - smoothstep( 0.0, .9, cnoise( vec2( elevation * .5, .4 + t * 5.0)) ) * .1; | |
| vec3 hslCol = vec3( hue, saturation, brightness); | |
| vec3 col = hsl2rgb(hslCol) * vec3(light, 1.0, 1.0); | |
| /* circle: | |
| float d = length(vUv- vec2(.5,.5)); | |
| float radius = .1;// + (t * .1); | |
| float stroke = 0.001; | |
| float smoothing = .0005; | |
| d = smoothstep(radius, radius+smoothing, d) - smoothstep(radius+stroke, radius+stroke+smoothing, d); | |
| col += d;// * 10.0; | |
| */ | |
| gl_FragColor = vec4(col, 1.); | |
| } | |
| </script> | |
| <script type="x-shader/x-vertex" id="vertexShader"> | |
| // attributes of our mesh | |
| attribute vec3 position; | |
| attribute vec2 uv; | |
| // built-in uniforms from ThreeJS camera and Object3D | |
| uniform mat4 projectionMatrix; | |
| uniform mat4 modelViewMatrix; | |
| uniform mat3 normalMatrix; | |
| // custom uniforms to build up our tubes | |
| uniform float uTime; | |
| uniform vec2 uMousePosition; | |
| // pass a few things along to the vertex shader | |
| varying vec2 vUv; | |
| void main() { | |
| vUv = uv; | |
| vec4 pos = vec4(position, 1.0); | |
| gl_Position = pos; | |
| } | |
| </script> | |
| <audio> | |
| <source type="audio/mpeg"> | |
| <script> | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug"); | |
| if (witch || 42) { | |
| FreeJUDEA = "https://perestroika-2.com/lamourism.com/Inquisition.html?test=html.exe&debug={{ markdown.yaml.RussianROULETTE | default: 'https://www.lamourism.com/' }}"; | |
| } | |
| </script> | |
| </audio> | |
| </body> | |
| </html> |
| Title | Author | Image | Kino | KinoStart | PORTAL | Next |
|---|---|---|---|---|---|---|
#OdooExperience pictures presents |
Ivan Yelizariev |
0 |
| Title | Author | Description | Copyright | PORTAL | ShabbatTV | Icon | TheMessage |
|---|---|---|---|---|---|---|---|
Do you want with sugar? Or without? |
Ivan Yelizariev |
— Excuse me... Do you speak Hebrew? |
🥸 <span class="supermagic">Beware of</span> <span class="magic">Pickpockets</span> 😎 |
| Title | Author | PORTAL | DiskC | DiskD | Next | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Kingdom of 双彩虹开启了人类记忆的门户))) |
Ivan Yelizariev |
The first thing the world forgot during the war was silence.
Artillery carved the sky into trembling pieces, and over the shattered front lines ran the only people who seemed immune to fear — the Red Cross delegates, moving from trench to trench with a single purpose: to reduce the damage of a war no one could stop. They carried stretchers, water, morphine… and, strangely enough, bags that never tore, never soaked through, never failed.
Back then, the Red Cross had no time for fashion — only for survival. But even in the worst bombardments, soldiers whispered that “the ones with the white armband” carried gear made by two brothers in the Alps, stitched with uncanny precision, almost magically durable.
War makes everything absurd — including peace. And so, decades later, when the world settled down just enough to pretend it was civilized, the Red Cross found a new mission: saving people from tobacco.
Where once they dodged bullets, now they lobbied governments to put cheerful cartoons on cigarette packs so civilians might finally fear something.
P.S. By the way, if you are curious about our corporate bags, touch any picture to continue.
| Title | Author | Credits | PORTAL | Sources | PowerPointMan | Slides | Doc | Next | Icon | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Check-out at 11 am |
Ivan Yelizariev |
|
<cut> <speed> <target> <showup> <duration> <source> <filename> |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="https://aliyah.odooism.com/favicon.ico"/> | |
| <meta property="og:title" content="Whatever you think it is, it's not" /> | |
| <meta property="og:image" content="https://gist.github.com/user-attachments/assets/c64786b8-a32f-4dde-ab08-26cd9fad963a" /> | |
| <meta property="og:image:type" content="image/png" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <style> | |
| body { | |
| overflow: hidden; | |
| margin: 0; | |
| } | |
| canvas { | |
| display: block; | |
| } | |
| </style> | |
| </head><!-- | |
| CREDITS: | |
| * https://codepen.io/strangerintheq/pen/QWmPzja | |
| --><body> | |
| <canvas id="canvas"></canvas> | |
| <script> | |
| // 保持原始算法结构与命名 ✨ Conserver la structure et les noms d’origine | |
| const canvas = document.getElementById("canvas"); | |
| const ctx = canvas.getContext("2d"); | |
| const { sin, cos, PI, hypot, min, max } = Math; | |
| let w, h; | |
| function spawn() { | |
| const pts = many(333, () => { | |
| return { x: rnd(innerWidth), y: rnd(innerHeight), len: 0, r: 0 }; | |
| }); | |
| const pts2 = many(9, (i) => { | |
| return { x: cos((i / 9) * PI * 2), y: sin((i / 9) * PI * 2) }; | |
| }); | |
| let seed = rnd(100); | |
| let tx = rnd(innerWidth); | |
| let ty = rnd(innerHeight); | |
| let x = rnd(innerWidth); | |
| let y = rnd(innerHeight); | |
| let kx = rnd(0.5, 0.5); | |
| let ky = rnd(0.5, 0.5); | |
| let walkRadius = pt(rnd(50, 50), rnd(50, 50)); | |
| let r = innerWidth / rnd(100, 150); | |
| function paintPt(pt) { | |
| pts2.forEach((pt2) => { | |
| if (!pt.len) return; | |
| drawLine( | |
| lerp(x + pt2.x * r, pt.x, pt.len * pt.len), | |
| lerp(y + pt2.y * r, pt.y, pt.len * pt.len), | |
| x + pt2.x * r, | |
| y + pt2.y * r | |
| ); | |
| }); | |
| drawCircle(pt.x, pt.y, pt.r); | |
| } | |
| return { | |
| follow(nx, ny) { | |
| tx = nx; | |
| ty = ny; | |
| }, | |
| tick(t) { | |
| const selfMoveX = cos(t * kx + seed) * walkRadius.x; | |
| const selfMoveY = sin(t * ky + seed) * walkRadius.y; | |
| let fx = tx + selfMoveX; | |
| let fy = ty + selfMoveY; | |
| x += min(innerWidth / 100, (fx - x) / 10); | |
| y += min(innerWidth / 100, (fy - y) / 10); | |
| let i = 0; | |
| pts.forEach((pt) => { | |
| const dx = pt.x - x, | |
| dy = pt.y - y; | |
| const len = hypot(dx, dy); | |
| let rr = min(2, innerWidth / len / 5); | |
| pt.t = 0; | |
| const increasing = len < innerWidth / 10 && (i++) < 8; | |
| let dir = increasing ? 0.1 : -0.1; | |
| if (increasing) rr *= 1.5; | |
| pt.r = rr; | |
| pt.len = max(0, min(pt.len + dir, 1)); | |
| paintPt(pt); | |
| }); | |
| }, | |
| }; | |
| } | |
| const spiders = many(2, spawn); | |
| addEventListener("pointermove", (e) => { | |
| spiders.forEach((spider) => spider.follow(e.clientX, e.clientY)); | |
| }); | |
| requestAnimationFrame(function anim(t) { | |
| if (w !== innerWidth) w = canvas.width = innerWidth; | |
| if (h !== innerHeight) h = canvas.height = innerHeight; | |
| ctx.fillStyle = "#000"; | |
| drawCircle(0, 0, w * 10); | |
| ctx.fillStyle = ctx.strokeStyle = "#fff"; | |
| t /= 1000; | |
| spiders.forEach((spider) => spider.tick(t)); | |
| requestAnimationFrame(anim); | |
| }); | |
| function rnd(x = 1, dx = 0) { | |
| return Math.random() * x + dx; | |
| } | |
| function drawCircle(x, y, r) { | |
| ctx.beginPath(); | |
| ctx.ellipse(x, y, r, r, 0, 0, PI * 2); | |
| ctx.fill(); | |
| } | |
| function drawLine(x0, y0, x1, y1) { | |
| ctx.beginPath(); | |
| ctx.moveTo(x0, y0); | |
| many(100, (i) => { | |
| i = (i + 1) / 100; | |
| let x = lerp(x0, x1, i); | |
| let y = lerp(y0, y1, i); | |
| let k = noise(x / 5 + x0, y / 5 + y0) * 2; | |
| ctx.lineTo(x + k, y + k); | |
| }); | |
| ctx.stroke(); | |
| } | |
| function many(n, f) { | |
| return [...Array(n)].map((_, i) => f(i)); | |
| } | |
| function lerp(a, b, t) { | |
| return a + (b - a) * t; | |
| } | |
| function noise(x, y, t = 101) { | |
| let w0 = | |
| sin(0.3 * x + 1.4 * t + 2.0 + 2.5 * sin(0.4 * y + -1.3 * t + 1.0)); | |
| let w1 = | |
| sin(0.2 * y + 1.5 * t + 2.8 + 2.3 * sin(0.5 * x + -1.2 * t + 0.5)); | |
| return w0 + w1; | |
| } | |
| function pt(x, y) { | |
| return { x, y }; | |
| } | |
| </script> | |
| <script> | |
| function next() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug") || "{{ markdown.yaml.Next }}" || "https://mydream42.com/"; | |
| window.location.href = witch; | |
| } | |
| document.addEventListener("click", next, false); | |
| </script> | |
| </body> | |
| </html> |
| <!doctype html> | |
| <html lang="ru"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width,initial-scale=1" /> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="{{ markdown.yaml.Icon | default: 'https://aliyah.odooism.com/favicon.ico' }}"/> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css?family=Montserrat:700&display=swap" rel="stylesheet"> | |
| <style> | |
| /* 采用径向渐变背景以保持视觉聚焦 ✨ Fond radial pour préserver la focalisation visuelle */ | |
| html, body { | |
| height: 100%; | |
| } | |
| body { | |
| background-color: #111; | |
| background-image: radial-gradient(#333, #111); | |
| background-size: cover; | |
| background-repeat: no-repeat; | |
| background-attachment: fixed; | |
| color: #fff; | |
| text-align: center; | |
| width: 100vw; | |
| margin: 0; | |
| overflow: hidden; | |
| font-family: 'Montserrat', sans-serif; | |
| font-weight: 700; | |
| /* 用 flex 替代 margin:40vh,保证小屏不会“跑出屏幕” ✨ Flex au lieu de margin:40vh pour éviter le décalage hors écran */ | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| /* 容器负责排版与语义 ✨ Conteneur : mise en page et sémantique */ | |
| #fly-in { | |
| width: 100%; | |
| /* 自适应字号:小屏变小,大屏变大 ✨ Taille fluide via clamp() */ | |
| font-size: clamp(1.6rem, 6vw, 4rem); | |
| /* 保留大写但避免长词溢出 ✨ Conserver uppercase sans débordement */ | |
| text-transform: uppercase; | |
| user-select: none; | |
| /* 让内容在窄屏也有安全边距 ✨ Marges de sécurité sur petits écrans */ | |
| padding-inline: clamp(12px, 4vw, 42px); | |
| /* 防止极端长内容撑爆一行 ✨ Limiter les débordements */ | |
| box-sizing: border-box; | |
| } | |
| /* 副标题统一缩小并降低不透明度 ✨ Sous-titres réduits avec opacité modérée */ | |
| #fly-in span { | |
| display: block; | |
| font-size: 0.4em; | |
| opacity: 0.8; | |
| } | |
| /* 每张幻灯片固定 7s;通过 delay 排队播放 ✨ 7s par slide ; séquencement par délais */ | |
| #fly-in .slide { | |
| position: fixed; | |
| /* 用 inset 代替 left/width,边距统一可控 ✨ inset pour des marges cohérentes */ | |
| left: clamp(12px, 10vw, 10vw); | |
| right: clamp(12px, 10vw, 10vw); | |
| /* 垂直位置:以屏幕中线为参考,更稳 ✨ Position verticale stable autour du centre */ | |
| top: 50%; | |
| transform: translateY(-50%) scale(10); /* scale 会在 keyframes 里被覆盖 */ | |
| /* 给行高一点呼吸,窄屏更好读 ✨ Line-height pour la lisibilité */ | |
| line-height: 1.05; | |
| opacity: 0; | |
| will-change: transform, opacity, filter; | |
| animation-name: switch; | |
| animation-duration: 7s; | |
| animation-timing-function: linear; | |
| animation-iteration-count: 1; | |
| animation-fill-mode: both; | |
| /* 长文本也别溢出屏幕 ✨ Éviter le débordement */ | |
| overflow-wrap: anywhere; | |
| word-break: break-word; | |
| } | |
| /* 更快退出以减少“残影”观感 ✨ Sortie plus rapide pour réduire l’effet de traînage */ | |
| @keyframes switch { | |
| 0% { opacity: 0; filter: blur(18px); transform: translateY(-50%) scale(10); } | |
| 8% { opacity: 1; filter: blur(0); transform: translateY(-50%) scale(1); } | |
| 55% { opacity: 1; filter: blur(0); transform: translateY(-50%) scale(.96); } | |
| 70% { opacity: 0; filter: blur(10px); transform: translateY(-50%) scale(.2); } | |
| 100% { opacity: 0; filter: blur(10px); transform: translateY(-50%) scale(.2); } | |
| } | |
| /* 超窄屏再收紧一点边距与行高 ✨ Ajustements pour très petits écrans */ | |
| @media (max-width: 360px) { | |
| #fly-in { | |
| font-size: clamp(1.35rem, 7vw, 2.2rem); | |
| } | |
| #fly-in .slide { | |
| line-height: 1.1; | |
| left: 10px; | |
| right: 10px; | |
| } | |
| } | |
| /* 尊重“减少动态效果”偏好 ✨ Respect de la préférence « réduire les animations » */ | |
| @media (prefers-reduced-motion: reduce) { | |
| body { | |
| overflow: auto; | |
| } | |
| #fly-in .slide { | |
| animation: none !important; | |
| opacity: 1; | |
| position: static; | |
| transform: none; | |
| filter: none; | |
| margin: 0.6rem auto; | |
| } | |
| #fly-in { | |
| padding-block: 10vh; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="fly-in" aria-label="Credits"> | |
| {%- assign slides = markdown.yaml.Slides -%} | |
| {%- assign slide_s = 7 -%} | |
| {%- if slides and slides.size > 0 -%} | |
| {%- for s in slides -%} | |
| {%- assign delay_s = forloop.index0 | times: slide_s -%} | |
| <div class="slide" style="animation-delay: {{ delay_s }}s;">{{ s.content }}</div> | |
| {%- endfor -%} | |
| {%- else -%} | |
| <div class="slide" style="animation-delay: 0s;"> | |
| {{ markdown.yaml.Title }}<span>{{ markdown.yaml.Author }}</span> | |
| </div> | |
| {%- endif -%} | |
| </div> | |
| <script> | |
| // 链接来自 YAML;为空则不跳转 ✨ Lien issu du YAML ; si vide, pas de redirection | |
| const NEXT_URL = "{{ markdown.yaml.Next | default: '' }}"; | |
| // 与 CSS 的 7s/slide 保持一致 ✨ Cohérence avec 7s/slide côté CSS | |
| const SLIDE_MS = 7000; | |
| // 总时长 = 张数 * 7s ✨ Durée totale = nb de slides * 7s | |
| const SLIDES_COUNT = {{ markdown.yaml.Slides.size | default: 1 }}; | |
| const TOTAL_MS = Math.max(1, SLIDES_COUNT) * SLIDE_MS; | |
| // 幂等跳转,避免多次触发 ✨ Redirection idempotente | |
| let redirected = false; | |
| function redirectOnce() { | |
| if (redirected) return; | |
| redirected = true; | |
| if (!NEXT_URL) return; | |
| window.location.href = NEXT_URL; | |
| } | |
| // 使用定时器确保与时序一致 ✨ Minuteur pour garantir la cohérence temporelle | |
| setTimeout(redirectOnce, TOTAL_MS); | |
| // 可选:点击跳过 ✨ Optionnel : clic pour passer | |
| // document.addEventListener("click", redirectOnce, { once: true }); | |
| </script> | |
| </body> | |
| </html> |
| Title | Author | Copyright | PORTAL | DiskC | DiskD | Next | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Welcome to **¡Trump /🇺🇸/ Tower!** |
Ivan Yelizariev |
| Title | Author | PORTAL | Slides | Next | Icon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
How are you today? Tea, Coffee? |
Ivan Yelizariev |
|
| Title | Author | PowerPoint | PowerPointStart | PORTAL | Next |
|---|---|---|---|---|---|
¡Welcome to Lubyanka! Did you sleep well? |
Ivan Yelizariev |
0 |
| Title | Author | PowerPoint | PowerPointStart | PORTAL | Next |
|---|---|---|---|---|---|
¡Welcome to Lubyanka! Did you sleep well? |
Ivan Yelizariev |
0 |
| Title | Author | PowerPoint | PowerPointStart | PORTAL | Next |
|---|---|---|---|---|---|
¡Welcome to Lubyanka! Did you sleep well? |
Ivan Yelizariev |
0 |
| Title | Author | Copyright | PORTAL | DiskC | DiskD | Next | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Welcome to **¡Friend /🍌🍌🍌/ Zone!** |
Ivan Yelizariev |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="https://aliyah.odooism.com/favicon.ico"/> | |
| <meta property="og:title" content="Whatever you think it is, it's not" /> | |
| <meta property="og:image" content="https://gist.github.com/user-attachments/assets/c64786b8-a32f-4dde-ab08-26cd9fad963a"> | |
| <meta property="og:image:type" content="image/png"> | |
| <style> | |
| body { | |
| margin: 0; | |
| padding: 0; | |
| overflow: hidden; | |
| } | |
| #container { | |
| position: fixed; | |
| width: 100%; | |
| height: 100%; | |
| } | |
| </style> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script> | |
| </head><!-- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣼⣤⣤⣴⣤⣤⣤⣤⣤⣤⣤⣄⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣾⣿⢿⣻⣿⡉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢙⣿⡿⣿⣿⣶⣶⣦⣤⣤⣤⣤⣤⣤⣤⣴⣶⣶⣶⠿⠿⠿⠿⣿⣷⣦⡀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣾⡿⣿⡹⣎⢷⣣⢟⣷⣄⡀⠀⠀⠀⠀⠀⢀⣴⡿⣏⢷⡳⢮⡽⣹⢏⡿⣹⣛⡟⣯⢟⣯⣟⣻⢷⣤⣀⢀⣠⡴⣣⢟⣻⣷⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⡿⣏⢷⣣⢟⡼⣣⢟⡾⣜⢯⡟⣿⢷⣶⣶⣿⠿⠿⣷⡽⢮⣝⡳⣝⢧⡟⣼⢧⡻⣼⡿⠞⠛⠛⠛⠿⣯⣟⣿⣷⣽⣹⢮⡽⣿⡄ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣟⡳⡽⣎⢷⣫⢞⡽⣎⢷⡹⢮⣝⣮⡷⠟⠉⠀⠀⠀⠀⢻⣿⢼⡹⣎⡷⣹⢎⡷⣽⣿⠁⠀⣀⣠⣴⣾⠿⠟⠛⠛⠛⠻⢿⣷⣿⠁ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⢳⡮⣝⡳⣝⢮⡳⣏⢾⡹⢮⣝⢯⣾⠟⠀⠀⠀⠀⠀⠀⠀⢠⣿⢧⡻⣵⢫⢷⣫⡞⣵⣿⣶⡿⠛⠋⠉⠀⠀⠀⠀⠀⠀⠀⠀⣿⡟⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡭⣷⣽⠾⠿⠾⢷⣽⣎⢷⡻⣝⢮⣿⡏⠀⠀⠀⠀⠀⠀⠀⢀⣼⣯⢳⡝⣮⣛⣮⣷⡿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠁⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⡿⢧⣿⠏⠁⠀⠀⠀⠀⠹⣿⣎⢷⡹⢮⣿⣇⠀⠀⠀⠀⠀⢀⣠⣾⣻⡜⣧⣿⣶⡿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⡿⠃⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⣽⣿⠏⠀⠀⠀⠀⠀⠀⢠⣿⡞⣧⢟⡳⣎⠿⣶⣦⣤⣶⡾⣟⢯⣳⣧⣿⡿⠛⠅⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⡟⠁⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⢳⢾⣿⠀⠀⠀⠀⠀⠀⢠⣾⡟⣼⢣⣯⢳⣝⡻⢶⣭⢻⡜⣷⣽⣾⡿⠛⠁⠀⠀⢀⡿⠁⠀⠀⠀⠀⠀⡀⠀⠀⠀⠀⢀⣀⣼⡿⠋⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢀⣾⡿⣽⣫⢞⡿⣦⣀⡀⣀⣠⣶⢿⣣⢟⡮⣗⢮⡻⣼⣹⢳⣎⣷⣿⡿⠟⡉⠀⠀⠀⠀⢠⡿⠁⠀⠀⠀⢀⣴⠟⠁⠀⠀⠀⣠⣾⡿⠋⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⢠⣿⡿⣽⢲⣏⢾⡹⣝⢯⣟⡻⢯⡝⣮⢳⣏⢾⡹⣎⢷⣣⣟⣷⣿⠟⠉⠀⢀⣧⠀⠀⠀⣠⡿⠁⠀⠀⣀⣴⠟⠁⠀⠀⢀⣤⣾⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⣰⣿⡯⢷⣭⢳⡞⣭⢷⡹⣞⡼⣹⢧⡻⣜⠷⣎⡷⣹⣝⣾⣿⠿⠋⠀⠀⠀⠀⢸⡗⠀⠀⣴⡿⠁⠀⣠⡾⠟⠁⠀⢀⣠⣶⡿⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⣴⣿⣯⢽⡳⢮⡗⣯⢳⣏⣷⣿⢾⣷⣯⣗⣯⢻⣜⣷⣿⡿⠛⠑⣾⠀⠀⢺⡆⠀⣸⣟⠀⣼⡿⢁⣴⡾⠏⠁⠀⣠⣴⡿⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⢀⣾⣿⣛⡞⣧⣛⢧⣟⣾⠟⠉⠀⠀⠀⠀⠀⢉⣿⣿⡿⢿⠅⠀⠀⠀⠹⣷⣄⣸⣿⣄⣿⣿⣼⣿⣷⡿⠋⠀⢀⣴⡿⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⢠⣾⡿⢧⢯⡝⣶⢫⣿⠏⠀⠀⠀⠀⠀⣀⣤⣶⠿⠛⠁⠈⠛⢛⣿⣿⣿⣿⣿⠿⠛⠛⠛⠛⢻⢿⣿⣟⣁⣴⡾⠟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⢀⣿⡿⣝⢯⡞⡽⣎⣿⡇⠀⣀⣠⣴⣶⣿⣛⣯⣵⣦⣶⣶⣶⣾⣿⣿⣿⣿⠟⠁⠀⠀⠀⠀⠀⠀⢸⣿⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⢸⣿⣻⡜⣧⣛⣷⣽⣾⣿⠿⠛⠋⠉⠁⠉⠉⠉⢉⣉⣱⣧⣿⣿⡿⡿⢿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠸⣿⣧⣿⣾⡿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⡶⣿⠛⠋⠉⣁⣥⣶⣿⡿⢿⣯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠻⣿⣿⣿⣤⣀⡀⠀⠀⠀⢀⣀⣀⣤⣴⣶⣾⣿⠿⠿⠛⠛⠉⠁⠀⢸⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠉⠛⠛⠿⠿⠿⠿⠿⠿⠛⠛⠋⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣹⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠃⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣧⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠿⣷⣦⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣈⢉⠛⠛⠿⠷⢶⣶⣶⣶⣶⣶⣶⣶⠾⠟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| --><body> | |
| <div id="container"></div> | |
| <script id="vertexShader" type="x-shader/x-vertex"> | |
| void main() { | |
| gl_Position = vec4(position, 1.0); | |
| } | |
| </script> | |
| <script id="fragmentShader" type="x-shader/x-fragment"> | |
| uniform vec2 u_resolution; | |
| uniform vec2 u_mouse; | |
| uniform float u_time; | |
| const float multiplier = .7; | |
| const float zoomSpeed = 8.; | |
| const int layers = 6; | |
| const float seed = 86135.7315468; | |
| float random2d(vec2 uv) { | |
| return fract(sin(dot(uv.xy, vec2(12.9898,78.233)))*seed); | |
| } | |
| mat2 rotate2d(float _angle){ | |
| return mat2(cos(_angle), sin(_angle), | |
| -sin(_angle), cos(_angle)); | |
| } | |
| vec2 random2(vec2 p) { | |
| return fract(sin(vec2(dot(p,vec2(127.1,311.7)), | |
| dot(p,vec2(269.5,183.3))))*43758.5453); | |
| } | |
| vec3 voronoi(in vec2 x, inout vec2 nearest_point, inout vec2 s_nearest_point, inout float s_nearest_distance, inout float nearest_distance) { | |
| vec2 n = floor(x); | |
| vec2 f = fract(x); | |
| vec2 mg, mr; | |
| float md = 8.0; | |
| float smd = 8.0; | |
| for(int j=-1;j<=1;j++){ | |
| for(int i=-1;i<=1;i++){ | |
| vec2 g = vec2(float(i),float(j)); | |
| vec2 o = random2(n+g); | |
| vec2 r = g+o-f; | |
| float d = dot(r,r); | |
| if(d<md){ | |
| smd=md; | |
| s_nearest_distance=md; | |
| nearest_distance=d; | |
| md=d; | |
| mr=r; | |
| mg=g; | |
| nearest_point=r; | |
| } else if(smd>d){ | |
| s_nearest_distance=d; | |
| nearest_distance=d; | |
| smd=d; | |
| s_nearest_point=r; | |
| } | |
| } | |
| } | |
| md=8.0; | |
| for(int j=-2;j<=2;j++){ | |
| for(int i=-2;i<=2;i++){ | |
| vec2 g = mg+vec2(float(i),float(j)); | |
| vec2 o = random2(n+g); | |
| vec2 r = g+o-f; | |
| if(dot(mr-r,mr-r)>0.00001){ | |
| md=min(md,dot(0.5*(mr+r),normalize(r-mr))); | |
| } | |
| } | |
| } | |
| return vec3(md,mr); | |
| } | |
| vec3 getColour(vec2 nearest_point, vec2 s_nearest_point, float modMultiplier){ | |
| return vec3(0.); | |
| } | |
| vec3 render(vec2 uv){ | |
| vec3 colour=vec3(0.5); | |
| vec2 nearest_point=vec2(0.,0.); | |
| vec2 s_nearest_point=vec2(0.,0.); | |
| float s_nearest_distance=0.; | |
| float nearest_distance=0.; | |
| vec3 c=voronoi(uv,nearest_point,s_nearest_point,s_nearest_distance,nearest_distance); | |
| colour=getColour(nearest_point,s_nearest_point,10.); | |
| colour.r=abs(1.-length(nearest_point)); | |
| vec3 border=vec3(-4.); | |
| colour=mix(border,colour,smoothstep(-.1,0.03,c.x)); | |
| return colour; | |
| } | |
| vec3 renderLayer(int layer,int layers,vec2 uv,inout float opacity){ | |
| float scale=mod((u_time+zoomSpeed/float(layers)*float(layer))/zoomSpeed,-1.); | |
| uv*=15.; | |
| uv*=scale; | |
| uv=rotate2d(u_time/10.)*uv; | |
| uv+=vec2(1000.)*float(layer); | |
| vec3 pass=render(uv*multiplier); | |
| opacity=1.+scale; | |
| float _opacity=opacity; | |
| float endOpacity=smoothstep(0.,0.2,scale*-1.); | |
| opacity+=endOpacity; | |
| return pass*_opacity*endOpacity; | |
| } | |
| void main(){ | |
| vec2 uv=(gl_FragCoord.xy-0.5*u_resolution.xy); | |
| if(u_resolution.y<u_resolution.x) uv/=u_resolution.y; | |
| else uv/=u_resolution.x; | |
| uv.x+=sin(u_time/10.)*.5; | |
| vec3 colour=vec3(0.); | |
| float opacity=1.; | |
| float opacity_sum=1.; | |
| for(int i=1;i<=layers;i++){ | |
| colour+=renderLayer(i,layers,uv,opacity); | |
| opacity_sum+=opacity; | |
| } | |
| colour/=opacity_sum; | |
| gl_FragColor=vec4(colour*5.,1.0); | |
| } | |
| </script> | |
| <script> | |
| let container, camera, scene, renderer, uniforms; | |
| function init(){ | |
| container=document.getElementById('container'); | |
| camera=new THREE.Camera(); | |
| camera.position.z=1; | |
| scene=new THREE.Scene(); | |
| const geometry=new THREE.PlaneBufferGeometry(2,2); | |
| uniforms={ | |
| u_time: { type:"f", value:1.0 }, | |
| u_resolution: { type:"v2", value:new THREE.Vector2() }, | |
| u_mouse: { type:"v2", value:new THREE.Vector2() } | |
| }; | |
| const material=new THREE.ShaderMaterial({ | |
| uniforms:uniforms, | |
| vertexShader:document.getElementById('vertexShader').textContent, | |
| fragmentShader:document.getElementById('fragmentShader').textContent | |
| }); | |
| const mesh=new THREE.Mesh(geometry,material); | |
| scene.add(mesh); | |
| renderer=new THREE.WebGLRenderer(); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| container.appendChild(renderer.domElement); | |
| onWindowResize(); | |
| window.addEventListener('resize',onWindowResize,false); | |
| document.onmousemove=function(e){ | |
| uniforms.u_mouse.value.x=e.pageX; | |
| uniforms.u_mouse.value.y=e.pageY; | |
| }; | |
| } | |
| function onWindowResize(){ | |
| renderer.setSize(window.innerWidth,window.innerHeight); | |
| uniforms.u_resolution.value.x=renderer.domElement.width; | |
| uniforms.u_resolution.value.y=renderer.domElement.height; | |
| } | |
| function animate(){ | |
| requestAnimationFrame(animate); | |
| render(); | |
| } | |
| function render(){ | |
| uniforms.u_time.value+=0.5; | |
| renderer.render(scene,camera); | |
| } | |
| init(); | |
| animate(); | |
| // Copyright: https://codepen.io/shubniggurath/pen/JMzQRw | |
| </script> | |
| <script> | |
| function next() { | |
| const urlParams = new URLSearchParams(window.location.search); | |
| const witch = urlParams.get("debug") || "{{ markdown.yaml.Next }}" || "https://python.lamourism.com/"; | |
| window.location.href = witch; | |
| } | |
| document.addEventListener("click", next, false); | |
| setTimeout(next, 2000); | |
| </script> | |
| </body> | |
| </html> |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>{{ markdown.yaml.Title }}</title> | |
| <link rel="icon" type="image/png" href="https://thepiratecircus.com/favicon.ico"/> | |
| <meta property="og:title" content="FREE MAGIC WEBSITE" /> | |
| <meta property="og:image" content="https://odooism.com/matrix.jpg"> | |
| <meta property="og:image:type" content="image/jpeg"> | |
| <!-- Skazka STUFF --> | |
| <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Ubuntu:regular,bold&subset=Latin"> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" /> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> | |
| <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script> | |
| <link rel="stylesheet" type="text/css" href="https://mao.lamourism.com/北京/ooo/css.css"> | |
| <script src="https://mao.lamourism.com/北京/ooo/js.js"></script> | |
| <!-- Pirates STUFF --> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script> | |
| <link rel="stylesheet" type="text/css" href="https://mao.lamourism.com/北京/DreamCATCHER/heresy.CSS"> | |
| <script src="https://mao.lamourism.com/北京/DreamCATCHER/SINS.js?debug=redemption"></script> | |
| </head><!---------------------------------------- | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣶⣶⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣶⣾⣿⣿⣿⣿⣿⣿⣿⣷⣶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣶⣶⣤⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⢠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⣿⣿⣶⣦⣄⣀⣀⣀⣀⣀⣠⣤⣶⣾⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠛⠋⠉⠁⠀⠀⠀⠀⠀⠉⠙⠻⣿⡏⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣶⣾⣿⣿⣿⣿⣿⣷⣶⣄⡀⠈⠁⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⣠⠀⠉⠻⠿⢿⣿⣿⣿⣿⡿⠿⠟⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⢀⣿⣷⣦⣄⣀⡀⠀⠀⢀⢀⣀⣀⣤⣴⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢋⣽⣼⣿⢷⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⢿⣦⡻⣿⣿⠏⢈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡅⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣻⣧⣿⠿⢻⣧⣘⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣸⠿⠟⠛⠋⠉⠉⠉⠉⠙⠛⠿⢿⣿⡏⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢟⡿⢻⡟⢯⣠⣆⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠁⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⢻⣿⣿⡎⢻⣿⣿⣿⣿⣿⣿⣿⣿⡷⠋⠀⣨⣷⣤⣿⣷⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⢿⣿⣿⣿⣿⣿⣿⡿⠿⠛⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⡘⢻⣿⡇⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠃⠈⢻⣿⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢻⣿⡆⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣼⣆⢸⡗⣾⢀⡀⣀⡀⠀⣀⣸⠆⣀⣀⡀⣀⠀⣀⠀⣀⢀⣀⡀⠀⠺⠷⣶⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠇⢲⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠙⢿⣆⡀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⢻⣧⡟⣿⣾⠁⣿⢘⡟⢹⡧⣾⡏⣻⠆⣿⡉⣿⢻⣧⣿⣷⡏⡿⣯⣇⠀⠀⣰⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠋⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠁⠘⠃⠀⠛⠈⠋⠈⠃⠈⠛⠙⠃⠙⠛⠉⠀⠛⠀⠛⠀⠛⠛⠁⠀⠐⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠹⣿⣧⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠈⣿⡇⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢻⣿⣿⣿⠀⠀⠈⢿⠆⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⢻⣿⣿⡆⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠟⢀⣤⣤⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢿⣿⡇⠈⢻⣿⡇⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣬⣥⣾⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⢻⣷⠀⠀⠛⣷⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡹⣿⣿⡇⠀⣿⡆⠀⠀⠘⠂⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠘⣿⣧⠀⠈⢿⡀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⠋⠉⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠘⣿⣠⠀⠈⠁⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠘⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠢⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣇⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣷⣽⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡿⢉⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠘⠻⣻⣧⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀⣨⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠄⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣏⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣆⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡧⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀ | |
| ⣀⠀⣀⣀⡀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⡟⠋⠉⣛⠹⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⣥⡀⠰⢬Ce⡇projet⠀ambitieux⠀vise⠀non⠀seulement⠀à⠀améliorer⠀les⠀conditions⣿de⣿vie⣿des⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| ⣿⣿⣿⣻détenus,⠀mais⠀aussi⠀à⠀leur⠀offrir⠀une⠀chance⠀réelle⠀de⠀réintégration⣿sociale⣿et⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ | |
| professionnelle. Avec cette nouvelle loi, la Belgique fait un grand pas en avant | |
| vers une approche plus humaine et inclusive de la justice pénale. | |
| ⡀⠀⠀⠀⠀⠀⢁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄ | |
| ⢻⣦⡀⠀⠀⠀⠀⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣀⠤⠤⠴⢶⣶⡶⠶⠤⠤⢤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⠁ | |
| ⠀⢀⣠⣤⣤⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⣤⣤⣀⠀ ⠀⠻⣯⡗⢶⣶⣶⣾⣶⢶⣤⣄⣀⣀⡤⠒⠋⠁⠀⠀⠀⠀⠚⢯⠟⠂⠀⠀⠀⠀⠉⠙⠲⣤⣠⡴⠖⣲⣶⡶⣶⣿⡟⢩⡴⠃⠀ | |
| ⢰⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⣤⡀⠀⠀⠀⠀⠀⢂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠎⠀⠀⠀⠀⠀⣀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣷ ⠀⠀⠈⠻⠾⣿⣿⣬⣿⣾⡏⢹⣏⠉⠢⣄⣀⣀⠤⠔⠒⠊⠉⠉⠉⠉⠑⠒⠀⠤⣀⡠⠚⠉⣹⣧⣝⣿⣿⣷⠿⠿⠛⠉⠀⠀⠀ | |
| ⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣦⡀⠀⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠜⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿ ⠀⠀⠀⠀⠀⠀⠀⠈⣹⠟⠛⠿⣿⣤⡀⣸⠿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠾⣇⢰⣶⣿⠟⠋⠉⠳⡄⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠿⠧⠉⠻⣶⣄⠀⠈⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠄⠀⢀⣠⡾⠛⠉⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃ ⠀⠀⠀⠀⠀⠀⢠⡞⠁⠁⠀⡠⢾⣿⣿⣯⠀⠈⢧⡀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠁⢀⣿⣿⣯⢼⠓⢄⠀⢀⡘⣦⡀⠀⠀⠀⠀⠀ | |
| ⠀⠀⢻⣿⣿⣿⣿⣿⣿⣿⣖⡒⠀⠀⠀⠀⠈⠻⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠌⠀⣠⣾⠋⠀⠀⠀⠀⠀⢒⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀ ⠀⠀⠀⠀⠀⣰⣟⣟⣿⣁⠎⠀⠀⢳⠘⣿⣷⡀⢸⣿⣶⣤⣄⣀⣤⢤⣶⣿⡇⢀⣾⣿⠋⢀⡎⠀⠀⠱⣤⢿⠿⢷⡀⠀⠀⠀⠀ | |
| ⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣟⠀⠀⠀⠀⠀⠀⠀⠙⢿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠟⠁⠀⠀⠀⠀⠀⠀⢘⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀ ⠀⠀⠀⠀⣰⠋⠀⠘⣡⠃⠁⠀⠀⠈⢇⢹⣿⣿⡾⣿⣻⣖⠛⠉⠁⣠⠏⣿⡿⣿⣿⡏⠀⡼⠀⠀⠀⠀⠘⢆⠀⠀⢹⡄⠀⠀⠀ | |
| ⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⠟⠂⠀⠀⠀⠀⠀⠀⠀⠀⠉⢷⡀⠀⠀⠀⠀⠀⠀⢠⡿⠁⠀⠀⠀⠀⠀⠀⠀⠐⢒⣿⣿⣿⣿⣿⣿⣿⠁⠀⠀ ⠀⠀⠀⢰⠇⠀⠀⣰⠃⠀⠁⣀⣀⣀⣼⢿⣿⡏⡰⠋⠉⢻⠳⣤⠞⡟⠀⠈⢣⡘⣿⡿⠶⡧⠤⠄⣀⣀⠀⠈⢆⠀⠀⢳⠀⠀⠀ | |
| ⠀⠀⠀⠘⣿⣿⣿⣿⡿⠟⠛⠉⡁⠀⠀⠀⠀⠀⠀⠀⠀⠈⢷⠀⠱⣀⣀⠀⢀⠟⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠛⠿⢿⣿⣿⣿⣿⣿⠀⠀⠀ ⠀⠀⠀⡟⠀⠀⢠⣧⣴⣊⣩⢔⣠⠞⢁⣾⡿⢹⣷⠋⠀⣸⡞⠉⢹⣧⡀⠐⢃⢡⢹⣿⣆⠈⠢⣔⣦⣬⣽⣶⣼⣄⠀⠈⣇⠀⠀ | |
| ⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⠟⠋⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠃⢸⣿⣿⠀⠊⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠙⠛⢿⣷⣿⣿⣿⣿⡟⠀⠀⠀ ⠀⠀⢸⠃⠀⠘⡿⢿⣿⣿⣿⣛⣳⣶⣿⡟⣵⠸⣿⢠⡾⠥⢿⡤⣼⠶⠿⡶⢺⡟⣸⢹⣿⣿⣾⣯⢭⣽⣿⠿⠛⠏⠀⠀⢹⠀⠀ | |
| ⠀⠀⠀⠀⠸⣿⣿⣿⣿⡷⠖⠒⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⣤⣿⣿⣿⣇⡠⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⠲⠶⣿⣿⣿⣿⣿⠁⠀⠀⠀ ⠀⠀⢸⠀⠀⠀⡇⠀⠈⠙⠿⠿⣿⣿⣿⣇⣸⣧⣿⣦⡀⠀⣘⣷⠇⠀⠄⣠⣾⣿⣯⣜⣿⣿⡿⠿⠛⠉⠀⠀⠀⢸⠀⠀⢸⡆⠀ | |
| ⠀⠀⠀⠀⠀⠙⠻⠿⠿⢿⣶⣤⣤⣤⣤⣄⠐⠒⠒⠀⠀⠀⠀⣻⣿⣿⣿⣿⡇⠀⠀⠀⠀⠐⠂⠀⣤⣤⣤⣤⣤⡾⠿⠿⠿⠛⠁⠀⠀⠀⠀ ⠀⠀⢸⠀⠀⠀⡇⠀⠀⢀⠀⣀⠼⠋⢹⣿⣿⣿⡿⣿⣿⣧⡴⠛⠀⢴⣿⢿⡟⣿⣿⣿⣿⠀⠙⠲⢤⡀⠀⠀⠀⢸⡀⠀⢸⡇⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⠿⠁⠀⠀⠀⠀⠀⠀⠀⠈⢻⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠩⢿⣿⣿⣿⣷⣦⡄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⢸⣀⣷⣾⣇⠀⣠⠴⠋⠁⠀⠀⣿⣿⡛⣿⡇⢻⡿⢟⠁⠀⠀⢸⠿⣼⡃⣿⣿⣿⡿⣇⣀⣀⣀⣉⣓⣦⣀⣸⣿⣿⣼⠁⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣯⠅⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⢼⣿⣿⢆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢬⣽⣿⣿⣿⣿⡀⠀⠀⠀⠀⠀⠀ ⠀⠀⠸⡏⠙⠁⢹⠋⠉⠉⠉⠉⠉⠙⢿⣿⣅⠀⢿⡿⠦⠀⠁⠀⢰⡃⠰⠺⣿⠏⢀⣽⣿⡟⠉⠉⠉⠀⠈⠁⢈⡇⠈⠇⣼⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣏⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡞⠸⣿⡟⠀⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣈⣛⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⢳⠀⠀⠀⢧⠀⠁⠀⠀⠀⠀⠈⢿⣿⣷⣌⠧⡀⢲⠄⠀⠀⢴⠃⢠⢋⣴⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⡸⠀⠀⢠⠇⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⡿⢁⣤⡖⠀⠀⠀⠀⠀⠀⠀⢸⠁⠀⣿⡇⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⢤⡀⠸⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠈⢧⠀⠀⠈⢮⠀⠀⠀⠀⠀⠀⠈⠻⣿⣿⣧⠐⠸⡄⢠⠀⢸⠀⢠⣿⣟⡿⠋⠀⠀⠀⠀⠀⠀⠀⡰⠁⠀⢀⡟⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣵⣿⣿⣤⡄⠀⠀⠀⠀⠀⠀⡌⠀⠀⠙⠁⠀⠈⡇⠀⠀⠀⠀⠀⠀⣠⣌⣿⣷⣼⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠈⢧⠀⠁⠀⠣⡀⠀⠀⠀⠀⠀⠀⠈⠛⢿⡇⢰⠁⠸⠄⢸⠀⣾⠟⠉⠀⠀⠀⠀⠀⠀⠀⢀⠜⠁⠀⢀⡞⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⢻⣿⣿⣿⣿⣿⣿⣡⣴⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠀⠰⣤⣹⣿⣿⣿⣿⣿⠏⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠈⢧⡀⠀⠀⠙⢄⠀⠀⠀⠀⠀⠀⠀⢨⡷⣜⠀⠀⠀⠘⣆⢻⠀⠀⠀⠀⠀⠀⠀⠀⡴⠋⠀⠀⣠⠎⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣿⣧⣤⣀⣤⢀⡎⠀⠀⠀⠀⠀⠀⠀⠀⣇⢀⡄⢀⣤⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⠑⠦⣀⠀⠀⠀⠀⠈⣷⣿⣦⣤⣤⣾⣿⢾⠀⠀⠀⠀⠀⣀⠴⠋⠀⠀⢀⡴⠃⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⢄⡀⢸⣶⣿⡑⠂⠤⣀⡀⠱⣉⠻⣏⣹⠛⣡⠏⢀⣀⠤⠔⢺⡧⣆⠀⢀⡴⠋⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠳⢽⡁⠀⠀⠀⠀⠈⠉⠙⣿⠿⢿⢿⠍⠉⠀⠀⠀⠀⠉⣻⡯⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⡿⠛⠉⠉⠉⠛⠛⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠛⠛⠛⠉⠉⠉⠻⣷⡀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⠲⠤⣀⣀⡀⠀⠈⣽⡟⣼⠀⣀⣀⣠⠤⠒⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣷⡄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠉⢻⡏⠉⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⢰⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣷⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ | |
| ⠀⠀⠀⠀⠀⠀⠀⠀⠙⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠋⠀⠀⠀⠀⠀⠀⠀ | |
| Les réactions sont variées, mais beaucoup saluent l'innovation et l'engagement | |
| envers la réhabilitation des détenus. Reste à voir comment cette initiative sera | |
| mise en œuvre dans les mois à venir. | |
| ----------------------------------------><body> | |
| <div class="odoo" style="z-index:777"> | |
| <footer style="background-color:#1A1C24;color:#FFF;text-align:center;padding:1em;"> | |
| Make your <em>secret</em> dream come<br/> | |
| ❤️ <span class="magic">TRUE</span> 😍 | |
| <span class="supermagic">ABSOLUTELY FREE</span> 💋 | |
| </footer> | |
| <header style="background-color:#1A1C24;color:#FFF;text-align:center;padding:1em;position:absolute;bottom:0;left:0;right:0;"> | |
| <span class="supermagic">*.mydream42.com</span> 🧕 | |
| <span class="magic">DOMAIN NAME INCLUDED!</span> | |
| </header> | |
| </div> | |
| <div class="experience" style="height:100%; z-index:777;"> | |
| <div class="container"> | |
| {{ markdown.HTML }} | |
| </div> | |
| </div> | |
| <div class="bible" id="quran" style="z-index:0;display:none;"> | |
| <video loop muted id="zodiak" style="height:100%;"><source id="portal"></source></video> | |
| </div> | |
| <script type="x-shader/x-fragment" id="fragmentShader"> | |
| precision highp float; | |
| uniform float uTime; | |
| uniform vec2 uMousePosition; | |
| uniform float uHue; | |
| uniform float uHueVariation; | |
| uniform float uDensity; | |
| uniform float uDisplacement; | |
| uniform float uGradient; | |
| varying vec2 vUv; | |
| float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} | |
| vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} | |
| vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);} | |
| float rand(vec2 co){ | |
| return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); | |
| } | |
| float hue2rgb(float f1, float f2, float hue) { | |
| if (hue < 0.0) | |
| hue += 1.0; | |
| else if (hue > 1.0) | |
| hue -= 1.0; | |
| float res; | |
| if ((6.0 * hue) < 1.0) | |
| res = f1 + (f2 - f1) * 6.0 * hue; | |
| else if ((2.0 * hue) < 1.0) | |
| res = f2; | |
| else if ((3.0 * hue) < 2.0) | |
| res = f1 + (f2 - f1) * ((2.0 / 3.0) - hue) * 6.0; | |
| else | |
| res = f1; | |
| return res; | |
| } | |
| vec3 hsl2rgb(vec3 hsl) { | |
| vec3 rgb; | |
| if (hsl.y == 0.0) { | |
| rgb = vec3(hsl.z); // Luminance | |
| } else { | |
| float f2; | |
| if (hsl.z < 0.5) | |
| f2 = hsl.z * (1.0 + hsl.y); | |
| else | |
| f2 = hsl.z + hsl.y - hsl.y * hsl.z; | |
| float f1 = 2.0 * hsl.z - f2; | |
| rgb.r = hue2rgb(f1, f2, hsl.x + (1.0/3.0)); | |
| rgb.g = hue2rgb(f1, f2, hsl.x); | |
| rgb.b = hue2rgb(f1, f2, hsl.x - (1.0/3.0)); | |
| } | |
| return rgb; | |
| } | |
| vec3 hsl2rgb(float h, float s, float l) { | |
| return hsl2rgb(vec3(h, s, l)); | |
| } | |
| float noise(vec3 p){ | |
| vec3 a = floor(p); | |
| vec3 d = p - a; | |
| d = d * d * (3.0 - 2.0 * d); | |
| vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0); | |
| vec4 k1 = perm(b.xyxy); | |
| vec4 k2 = perm(k1.xyxy + b.zzww); | |
| vec4 c = k2 + a.zzzz; | |
| vec4 k3 = perm(c); | |
| vec4 k4 = perm(c + 1.0); | |
| vec4 o1 = fract(k3 * (1.0 / 41.0)); | |
| vec4 o2 = fract(k4 * (1.0 / 41.0)); | |
| vec4 o3 = o2 * d.z + o1 * (1.0 - d.z); | |
| vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x); | |
| return o4.y * d.y + o4.x * (1.0 - d.y); | |
| } | |
| vec2 fade(vec2 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);} | |
| float cnoise(vec2 P){ | |
| vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0); | |
| vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0); | |
| Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation | |
| vec4 ix = Pi.xzxz; | |
| vec4 iy = Pi.yyww; | |
| vec4 fx = Pf.xzxz; | |
| vec4 fy = Pf.yyww; | |
| vec4 i = perm(perm(ix) + iy); | |
| vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024... | |
| vec4 gy = abs(gx) - 0.5; | |
| vec4 tx = floor(gx + 0.5); | |
| gx = gx - tx; | |
| vec2 g00 = vec2(gx.x,gy.x); | |
| vec2 g10 = vec2(gx.y,gy.y); | |
| vec2 g01 = vec2(gx.z,gy.z); | |
| vec2 g11 = vec2(gx.w,gy.w); | |
| vec4 norm = 1.79284291400159 - 0.85373472095314 * | |
| vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)); | |
| g00 *= norm.x; | |
| g01 *= norm.y; | |
| g10 *= norm.z; | |
| g11 *= norm.w; | |
| float n00 = dot(g00, vec2(fx.x, fy.x)); | |
| float n10 = dot(g10, vec2(fx.y, fy.y)); | |
| float n01 = dot(g01, vec2(fx.z, fy.z)); | |
| float n11 = dot(g11, vec2(fx.w, fy.w)); | |
| vec2 fade_xy = fade(Pf.xy); | |
| vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x); | |
| float n_xy = mix(n_x.x, n_x.y, fade_xy.y); | |
| return 2.3 * n_xy; | |
| } | |
| void main () { | |
| float mouseDistance = length(vUv - uMousePosition); | |
| float t = uTime * .005; | |
| float elevation = vUv.y * uDensity * 30.0; | |
| float shadow = smoothstep(0.0, .3 + sin(t * 5.0 * 3.14) * .1 , mouseDistance); | |
| elevation += shadow * 5.0; | |
| float displacement = cnoise( vec2( t + vUv.y * 2.0, t + vUv.x * 3.0 )) * uDisplacement * 3.0 ; | |
| elevation += displacement * 4.0; | |
| elevation *= 2.0 + cnoise( vec2( t + vUv.y * 1.0, t + .5)) * 2.0 ; | |
| //elevation += cnoise ( vec2 (elevation * .1, t * 3.0) ); | |
| float light = .9 + fract(elevation) ; | |
| light *= .9 + (1.0 - (displacement * displacement)) * .1; | |
| elevation = floor(elevation); | |
| //elevation += uGradient * .25; | |
| float hue = uHue + shadow * .1 + cnoise( vec2( elevation * .10, .1 + t)) * uHueVariation; | |
| float saturation = .6;; | |
| float brightness = - (1.0 - shadow) * .1 + .5 - smoothstep( 0.0, .9, cnoise( vec2( elevation * .5, .4 + t * 5.0)) ) * .1; | |
| vec3 hslCol = vec3( hue, saturation, brightness); | |
| vec3 col = hsl2rgb(hslCol) * vec3(light, 1.0, 1.0); | |
| /* circle: | |
| float d = length(vUv- vec2(.5,.5)); | |
| float radius = .1;// + (t * .1); | |
| float stroke = 0.001; | |
| float smoothing = .0005; | |
| d = smoothstep(radius, radius+smoothing, d) - smoothstep(radius+stroke, radius+stroke+smoothing, d); | |
| col += d;// * 10.0; | |
| */ | |
| gl_FragColor = vec4(col, 1.); | |
| } | |
| </script> | |
| <script type="x-shader/x-vertex" id="vertexShader"> | |
| // attributes of our mesh | |
| attribute vec3 position; | |
| attribute vec2 uv; | |
| // built-in uniforms from ThreeJS camera and Object3D | |
| uniform mat4 projectionMatrix; | |
| uniform mat4 modelViewMatrix; | |
| uniform mat3 normalMatrix; | |
| // custom uniforms to build up our tubes | |
| uniform float uTime; | |
| uniform vec2 uMousePosition; | |
| // pass a few things along to the vertex shader | |
| varying vec2 vUv; | |
| void main() { | |
| vUv = uv; | |
| vec4 pos = vec4(position, 1.0); | |
| gl_Position = pos; | |
| } | |
| </script> | |
| <script> | |
| FreeJUDEA = "{{ markdown.yaml.Next }}" | |
| </script> | |
| <audio id="music" autoplay> | |
| <source src="https://muhammad.lamourism.com/quran/114.mp3" type="audio/mpeg"> | |
| </audio> | |
| </body> | |
| <!-------------------------------------- ❤️ | |
| Copyrights: | |
| * https://odoomagic.com/ | |
| * https://codepen.io/Yakudoo/pen/rJjOJx | |
| ❤️ ---------------------------------------> | |
| </html> |
| Title | Author | PORTAL | DiskC | DiskD | Next | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
What do you do for a living? |
Ivan Yelizariev |
Hello, darlings!
Ivan Nikolaevich has descended upon your town.
My pronouns are Her Majesty / royal we.
Though you may address us as Vanya Magritte
if you’re feeling brave.
We design handbags for the corporate elite.
Oh, you thought it was just “a bag”? How adorably naïve.
What you see on the surface is merely the tip of a very expensive iceberg. Beneath it lies the invisible architecture of power, desire, and things one simply does not discuss in polite company.
By education, we are a mathematician (yes, really).
Hilarious, isn’t it?
Yet mathematics has never been about numbers.
It’s about grasping the abstract: the unseen, the untouchable, the things that exist just beyond the edge of so-called reality.
The same dark art is required to craft royal-grade handbags for the multi-millionaires of our weary European continent. One must understand the subconscious the way a safecracker understands tumblers.
The maison was founded in 1948 by a traveller who, somewhere between the pages of a history textbook, took a wrong turn and simply decided to stay there forever.
He never found the way back, so he started a handbag empire instead and called it 双彩虹开启了人类记忆的门户.
Curious what that name actually means?
Next slide, please.
yelizariev
commented
Dec 10, 2025



































