File size: 21,495 Bytes
0d4f2e7
 
 
 
 
2a36b5f
0d4f2e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
966bfa1
 
0d4f2e7
 
966bfa1
 
 
 
 
 
 
 
 
 
 
 
0d4f2e7
 
 
 
 
 
bf18ca5
0d4f2e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13ef09e
 
f847f34
13ef09e
0d4f2e7
 
 
652070a
 
 
 
966bfa1
652070a
 
0d4f2e7
 
f847f34
6742a32
f847f34
966bfa1
f847f34
 
0d4f2e7
 
8abbee5
 
 
966bfa1
8abbee5
 
0d4f2e7
 
1d0f63b
 
 
966bfa1
1d0f63b
966bfa1
 
0d4f2e7
966bfa1
126d647
966bfa1
 
 
126d647
 
0d4f2e7
126d647
 
 
 
 
 
0d4f2e7
e9e0609
 
 
 
 
 
0d4f2e7
1a53677
 
 
 
 
8707601
 
0d4f2e7
8707601
dedcdf5
8707601
 
 
 
695e204
0d4f2e7
 
695e204
 
 
 
 
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
966bfa1
 
0d4f2e7
 
 
86d51ae
20ca842
86d51ae
b971f48
20ca842
 
 
 
 
 
f847f34
8abbee5
ad2a2e4
966bfa1
126d647
1a53677
 
8707601
695e204
20ca842
 
 
 
 
 
0d4f2e7
 
 
 
20ca842
 
 
 
 
 
 
 
 
 
0d4f2e7
20ca842
0d4f2e7
 
20ca842
f847f34
ad2a2e4
20ca842
0d4f2e7
 
 
 
 
 
 
695e204
0d4f2e7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
652070a
 
966bfa1
 
652070a
20ca842
 
 
 
 
 
 
 
 
 
 
 
 
0d4f2e7
 
695e204
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>🤗 Open-source AI: year in review 2024</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            background: #f8f9fa;
            margin: 0;
            padding: 20px;
            min-height: 100vh;
        }

        h1 {
        color: #1a1a1a;
            margin-bottom: 20px;
        }

        .intro {
            max-width: 800px;
            margin: 0 auto 40px;
            text-align: center;
            line-height: 1.6;
            color: #374151;
        }

        .calendar {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }

        .card {
            aspect-ratio: 1;
            background: #6B7280;
            border-radius: 12px;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            font-weight: bold;
            color: white;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .card.active {
            background: #FFD21E;
            transform: translateY(-2px);
            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
        }

        .card.opened {
            background: #FF9D00;
        }

        .card-content {
            display: none;
            padding: 20px;
            text-align: center;
        }

        .modal {
            display: none;
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            z-index: 1000;
            justify-content: center;
            align-items: center;
        }

        .modal-content {
            background: white;
            padding: 40px;
            border-radius: 12px;
            max-width: 800px;
            width: 90%;
            max-height: 90vh;
            overflow-y: auto;
            position: relative;
        }

        .close-button {
            position: absolute;
            top: 20px;
            right: 20px;
            background: none;
            border: none;
            font-size: 24px;
            cursor: pointer;
        }
        .responsive-iframe-container {
            position: relative;
            width: 100%;
            height: 500px; /* Default height */
            transition: all 0.3s ease;
        }
        .responsive-iframe-container iframe {
            width: 100%;
            height: 100%;
            border: none;
        }
        .browser-fullscreen {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 9999;
            background: white;
        }
    </style>
</head>
<body>
    <div class="intro">
        <h1>🤗 Open-source AI: year in review 2024</h1>
        <p>We're excited to share what's been happening in AI this year—with a twist! In collaboration with <a href="https://aiworld.eu" target="_blank">aiworld.eu</a>, starting December 2, we'll release fresh content daily to share insights on what happened in open-source AI in 2024. Like the space to be notified when we release the next data! <img src="logos/huggingface_logo-noborder.svg" width="20"> <img src="logos/aiworld.svg" width="20"></p>
    </div>

    <div class="calendar">
        <!-- Cards will be generated here -->
    </div>

    <div class="modal">
        <div class="modal-content">
            <button class="close-button">&times;</button>
            <div class="modal-body"></div>
        </div>
    </div>

    <script>
        const calendar = document.querySelector('.calendar');
        const modal = document.querySelector('.modal');
        const modalContent = document.querySelector('.modal-body');
        const closeButton = document.querySelector('.close-button');

        // Add the cardContents object here
        const cardContents = {
    1: `
        <h2>Day 1 - Six Predictions for AI in 2025 (and a review of how my 2024 predictions turned out)</h2>
        <div style="display: flex; align-items: center; margin-bottom: 20px;">
            <img src="https://cdn-avatars.huggingface.co/v1/production/uploads/1583857146757-5e67bdd61009063689407479.jpeg" style="width: 60px; height: 60px; border-radius: 50%; margin-right: 15px;">
            <div>
                <strong><a href="https://huggingface.co/clem" style="color: inherit; text-decoration: underline;">Clément Delangue</a></strong><br>
                <em>Hugging Face CEO</em>
            </div>
        </div>
            <h3>Predictions for 2025</h3>
            <ol>
                <li>There will be the first major public protest related to AI</li>
                <li>A big company will see its market cap divided by two or more because of AI</li>
                <li>At least 100,000 personal AI robots will be pre-ordered</li>
                <li>China will start to lead the AI race (as a consequence of leading the open-source AI race)</li>
                <li>There will be big breakthroughs in AI for biology and chemistry</li>
                <li>We will begin to see the economic and employment growth potential of AI, with 15M AI builders on Hugging Face</li>
            </ol>

            <h3>2024 Predictions Review</h3>
            <ul>
                <li>A hyped AI company will go bankrupt or get acquired for a ridiculously low price<br>
                ✅ (Inflexion, AdeptAI,...)</li>
                <li>Open-source LLMs will reach the level of the best closed-source LLMs<br>
                ✅ with QwQ and dozens of others</li>
                <li>Big breakthroughs in AI for video, time-series, biology and chemistry<br>
                ✅ for video 🔴for time-series, biology and chemistry</li>
                <li>We will talk much more about the cost (monetary and environmental) of AI<br>
                ✅Monetary 🔴Environmental (😢)</li>
                <li>A popular media will be mostly AI-generated<br>
                ✅ with NotebookLM by Google</li>
                <li>10 millions AI builders on Hugging Face leading to no increase of unemployment<br>
                🔜currently 7M of AI builders on Hugging Face</li>
            </ul>

            <p style="margin-top: 30px;"><i>Join the conversation about Clem's predictions for 2025:</i></p>
            <ul style="list-style-type: none; padding-left: 0;">
                <li><a href="https://huggingface.co/posts/clem/703679306559358" style="color: inherit; text-decoration: underline;" target="_blank">Hugging Face</a></li>
                <li><a href="https://x.com/ClementDelangue/status/1863576648253091934" style="color: inherit; text-decoration: underline;" target="_blank">X</a></li>
                <li><a href="https://www.linkedin.com/in/clementdelangue/" style="color: inherit; text-decoration: underline;" target="_blank">LinkedIn</a></li>
                <li><a href="https://bsky.app/profile/clem.hf.co/post/3lcdceiv7vk2h" style="color: inherit; text-decoration: underline;"  target="_blank">Bluesky</a></li>
            </ul>
    `,
    2: `
        <h2>Most liked and downloaded models, from 2022 to today</h2>
        <p>Explore the community's favourite models, ranging from tasks, likes to downloads, since 2022. What we're seeing: smol models are on the rise.📈👀</p>
        <p><em style="font-size: 0.8em;">💡Tip: Click the small square icon in the top right corner to access full screen view!</em></p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/model/treemap" allowfullscreen></iframe>
        </div>
    `,
    3: `
        <h2>Fast & Furious model releases</h2>
        <p>This race chart shows cumulative likes for models over the first 48 weeks of 2024, with Meta (US), Stability (UK) and Black Forest Labs (GER) leading the pack.</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/author/racechart" allowfullscreen></iframe>
        </div>
    `,
    4: `
        <h2>Zero to One (Million Models)</h2>
        <p>This exponential growth chart tracks the Hugging Face community's journey from just a few thousand models in 2022 to surpassing the million-model milestone today.</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/tag/stacked-model-count-other" allowfullscreen></iframe>
        </div>
    `,
    5: `
        <h2>The HF Network: What your likes say about you</h2>
        <p>Network connections between users’ favourite models.</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/model/network-small" allowfullscreen></iframe>
        </div>    
        `,
    6: `
        <h2>33 Months of Models, per Task</h2>
        <p>Over the last 33 months, more than 1.1M models have been created for 53 specialized tasks. Watch until the end to see which task reigns supreme. 👀 <em>(Hint: this task makes up nearly half the models on the Hub.)</em></p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/pipeline/racechart2" allowfullscreen></iframe>
        </div>         
        `,
    7: `
        <h2>The global top 500 model creators on the Hub</h2>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/map_country_data" allowfullscreen></iframe>
        </div>
        `,
    8: `
        <h2>Average daily downloads for the top 100 trending models for Dec 9 2024</h2>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/model/treemap-top-100-trending" allowfullscreen></iframe>
        </div>
        `,
    9: `
        <h2>NeurIPS Noel: Unwrapping the Keywords of AI's Holiday Spirit</h2>
        <p>Analyzing keywords from 4,495 papers accepted at NeurIPS 2024 and how the top 40 words co-occur within the same papers.</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/model/model/keywords-neurips" allowfullscreen></iframe>
        </div>    
        `,
    10: `
        <h2>The Great AI Bake-Off: Which Field is Rising?</h2>
        <p>This stacked chart shows the evolution of the number of research papers on Hugging Face</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/api/paper/hf_papers_stacked" allowfullscreen></iframe>
        </div> 

    `,
    11: `
        <h2>Paper Trail: Top upvoted papers on the Hub</h2>
        <p>This table presents the top most upvoted papers on HF, along with the top 20 presented at this year's NeurIPS.</p>
        <div class="responsive-iframe-container">
            <button onclick="toggleBrowserFullscreen(this.parentElement)" style="position: absolute; top: 10px; right: 10px; z-index: 10; padding: 8px; background: rgba(0,0,0,0.6); color: white; border: none; border-radius: 4px; cursor: pointer;"></button>
            <iframe src="https://aiworld.eu/embed/api/paper/top-20-hf-papers-at-neurips" allowfullscreen></iframe>
        </div> 
    `,
    12: `
        <h2>Day 12</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    13: `
        <h2>Day 13</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    14: `
        <h2>Day 14</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    15: `
        <h2>Day 15</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    16: `
        <h2>Day 16</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    17: `
        <h2>Day 17</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    18: `
        <h2>Day 18</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    19: `
        <h2>Day 19</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    20: `
        <h2>Day 20</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    21: `
        <h2>Day 21</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    22: `
        <h2>Day 22</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    23: `
        <h2>Day 23</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `,
    24: `
        <h2>Day 24</h2>
        <p>Wondering what tomorrow’s visualization will be? Like the space to get notified when we reveal it 🤗</p>
        <img src="/images/day3-teaser.png" style="width: 100%; margin: 20px 0;">
    `
};

        // Update the getCardLink function
        function getCardLink(day) {
            const rootUrl = "https://huggingface.co/spaces/huggingface/open-source-ai-year-in-review-2024";
            return `${rootUrl}?day=${day}" target="_blank`;
        }

        // Add this object before the card creation loop to define custom text labels
        const cardLabels = {
            1: "🔮<br>Clem's2025 predictions",
            2: "❤️<br>Most liked & downloaded models",
            3: "🏎️<br>Fast & Furious model releases",
            4: "🚀<br>Zero to One (Million Models)",
            5: "🤗<br>What your likes say about you?",
            6: "🏷️<br>Tasks on tasks on tasks",
            7: "🌍<br>Global top 500 model creators",
            8: "📈<br>Average daily downloads",
            9: "🎄<br>NeurIPS Noel",
            10: "🎂<br>The Great AI Bake-Off",
            11: "📄<br>Top upvoted papers on the Hub"
            // Add more custom labels as needed
            // 3: "Custom Text",
            // 4: "Another Label",
        };

        // Modify the card creation loop
        for (let i = 1; i <= 24; i++) {
            const card = document.createElement('div');
            card.className = 'card';
            card.dataset.day = i;
            card.dataset.link = getCardLink(i);

            // Define a condition to use a thumbnail for specific cards
            const useThumbnail = [].includes(i);
            
            // Get custom label if it exists, otherwise use the number
            const cardContent = useThumbnail 
                ? `<img src="images/${i}.png" style="width: 75%; height: 75%; object-fit: cover; border-radius: 12px;">`
                : `<div style="text-align: center; margin: 0 20%;">${cardLabels[i] || i}</div>`;

            card.innerHTML = `
                ${cardContent}
                <div class="card-content">
                    ${cardContents[i]}
                    <div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #eee;">
                        <p><em style="font-size: 0.8em;">💡Tip: Click the small square icon in the top right corner to access full screen view!</em></p>
                        <p style="font-size: 0.8em;">🔗 Share this card:</p><input type="text" value="${getCardLink(i)}" readonly style="width: 100%; padding: 8px; margin: px 0; border: 1px solid #ddd; border-radius: 4px; background: #f5f5f5; font-size: 0.8em;" onclick="this.select(); document.execCommand('copy');">
                    </div>
                </div>
            `;
            calendar.appendChild(card);
        }

        // Handle card clicks
        const cards = document.querySelectorAll('.card');
        const activeDays = [1,2,3,4,5,6,7,8,9,10,11]; // Add the day numbers you want to highlight

        cards.forEach(card => {
            const day = parseInt(card.dataset.day);
            
            // Only add active class to specific cards
            if (activeDays.includes(day)) {
                card.classList.add('active');
            }
            
            // Keep click functionality for all cards
            card.addEventListener('click', () => {
                card.classList.add('opened');
                modalContent.innerHTML = card.querySelector('.card-content').innerHTML;
                modal.style.display = 'flex';
            });
        });

        // Close modal
        closeButton.addEventListener('click', () => {
            modal.style.display = 'none';
        });

        modal.addEventListener('click', (e) => {
            if (e.target === modal) {
                modal.style.display = 'none';
            }
        });

        // Add fullscreen function
        function toggleBrowserFullscreen(container) {
            container.classList.toggle('browser-fullscreen');
        }

        // Add this code after your existing event listeners
        // Handle direct links to cards
        window.addEventListener('load', () => {
            const params = new URLSearchParams(window.location.search);
            const day = params.get('day');
            if (day) {
                const card = document.querySelector(`[data-day="${day}"]`);
                if (card) {
                    card.click(); // Automatically open the modal for the linked card
                }
            }
        });
    </script>
</body>
</html>