PageSourceSearch

https://avs4you.github.io/

html avs4you.github.io collected 2026-10-03 08:40:40 UTC 42,211 bytes, 1,477 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <!-- Google Tag Manager -->
5  
5<script>
vendor: 323 bytes, line 5
5(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);})(window,document,'script','dataLayer','
5GTM-WMB2TZX
vendor: 3 bytes, line 5
5');
5</script>
5
6  <!-- End Google Tag Manager -->
7
8  <meta charset="UTF-8">
9  <meta name="viewport" content="width=device-width, initial-scale=1.0">
10  <link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
11  <link rel="preconnect" href="https://fonts.googleapis.com">
12  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
13  <link href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800;900&family=Mulish:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
14  <title>AVS4YOU Plugins Marketplace</title>
15  <style>
16    :root {
17      --accent: #1577e0;
18      --accent-dark: #1463c4;
19      --bg: #f4f7fb;
20      --panel: #ffffff;
21      --line: #e1e9f2;
22      --line-soft: #e7edf4;
23      --text: #16202e;
24      --muted: #5b6b7e;
25      --faint: #8494a8;
26      --shadow: 0 2px 8px rgba(16, 32, 46, 0.06);
27    }
28
29    * {
30      box-sizing: border-box;
31    }
32
33    html,
34    body {
35      height: 100%;
36      overflow: hidden;
37    }
38
39    body {
40      margin: 0;
41      font-family: Mulish, "Segoe UI", Roboto, Arial, sans-serif;
42      color: var(--text);
43      background: var(--bg);
44    }
45
46    button,
47    input {
48      font: inherit;
49    }
50
51    button {
52      border: 0;
53    }
54
55    a {
56      color: inherit;
57    }
58
59    .app-shell {
60      height: 100vh;
61      display: flex;
62      background: var(--bg);
63      overflow: hidden;
64    }
65
66    .sidebar {
67      width: 250px;
68      flex: 0 0 250px;
69      display: flex;
70      flex-direction: column;
71      background: var(--panel);
72      border-right: 1px solid var(--line);
73      overflow-y: auto;
74    }
75
76    .brand {
77      padding: 18px 18px 16px;
78      line-height: 1;
79    }
80
81    .brand-title {
82      font-family: Manrope, Mulish, sans-serif;
83      font-size: 14.5px;
84      font-weight: 900;
85    }
86
87    .brand-subtitle {
88      margin-top: 3px;
89      color: var(--accent);
90      font-family: Manrope, Mulish, sans-serif;
91      font-size: 10px;
92      font-weight: 800;
93      letter-spacing: 1.2px;
94      text-transform: uppercase;
95    }
96
97    .rail-section {
98      padding: 6px 12px 0;
99    }
100
101    .rail-section + .rail-section {
102      padding-top: 18px;
103    }
104
105    .rail-title {
106      padding: 0 8px 8px;
107      color: #9aa8bc;
108      font-size: 10.5px;
109      font-weight: 800;
110      letter-spacing: 1px;
111      text-transform: uppercase;
112    }
113
114    .rail-button {
115      width: 100%;
116      display: flex;
117      align-items: center;
118      gap: 10px;
119      min-height: 38px;
120      padding: 9px 11px;
121      margin-bottom: 2px;
122      border-radius: 9px;
123      color: #46566b;
124      background: transparent;
125      font-size: 13.5px;
126      font-weight: 600;
127      cursor: pointer;
128      text-align: left;
129    }
130
131    .rail-button.active {
132      color: var(--accent-dark);
133      background: #eef4fc;
134      font-weight: 800;
135    }
136
137    .rail-button .rail-icon {
138      width: 20px;
139      height: 20px;
140      flex: 0 0 20px;
141      display: inline-flex;
142      align-items: center;
143      justify-content: center;
144      color: #9aa8bc;
145      font-size: 13px;
146    }
147
148    .rail-button.active .rail-icon {
149      color: var(--accent);
150    }
151
152    .rail-button .rail-label {
153      flex: 1;
154      min-width: 0;
155      overflow: hidden;
156      text-overflow: ellipsis;
157      white-space: nowrap;
158    }
159
160    .rail-count {
161      color: #a6b3c4;
162      font-family: "JetBrains Mono", "Courier New", monospace;
163      font-size: 10.5px;
164      font-weight: 700;
165    }
166
167    .rail-button.active .rail-count {
168      color: var(--accent);
169    }
170
171    .app-badge {
172      width: 20px;
173      height: 20px;
174      flex: 0 0 20px;
175      display: inline-flex;
176      align-items: center;
177      justify-content: center;
178      border-radius: 6px;
179      color: #fff;
180      font-family: Mulish, sans-serif;
181      font-size: 8.5px;
182      font-weight: 900;
183      letter-spacing: 0.3px;
184    }
185    .app-badge.app-icon {
186      object-fit: contain;
187      background: transparent;
188    }
189
190
191    .main {
192      height: 100vh;
193      min-width: 0;
194      flex: 1;
195      display: flex;
196      flex-direction: column;
197      overflow: hidden;
198    }
199
200    .toolbar {
201      min-height: 64px;
202      flex: 0 0 auto;
203      display: flex;
204      align-items: center;
205      gap: 14px;
206      padding: 14px 22px;
207      background: var(--panel);
208      border-bottom: 1px solid var(--line);
209    }
210
211    .heading {
212      min-width: 145px;
213      line-height: 1;
214    }
215
216    .heading-title {
217      font-size: 16px;
218      font-weight: 800;
219    }
220
221    .heading-subtitle {
222      margin-top: 5px;
223      color: var(--faint);
224      font-size: 11.5px;
225      font-weight: 600;
226    }
227
228    .toolbar-spacer {
229      flex: 1;
230    }
231
232    .search {
233      width: min(260px, 32vw);
234      height: 38px;
235      display: flex;
236      align-items: center;
237      gap: 8px;
238      padding: 0 13px;
239      border: 1px solid var(--line);
240      border-radius: 8px;
241      background: var(--bg);
242    }
243
244    .search span {
245      display: inline-flex;
246      align-items: center;
247      justify-content: center;
248      color: #9aa8bc;
249    }
250
251    .svg-icon {
252      width: 16px;
253      height: 16px;
254      display: block;
255      fill: none;
256      stroke: currentColor;
257      stroke-width: 2;
258      stroke-linecap: round;
259      stroke-linejoin: round;
260    }
261
262    .rail-icon .svg-icon {
263      width: 15px;
264      height: 15px;
265    }
266
267    .view-button .svg-icon {
268      width: 17px;
269      height: 17px;
270    }
271
272    .search input {
273      min-width: 0;
274      width: 100%;
275      border: 0;
276      outline: 0;
277      background: transparent;
278      color: var(--text);
279      font-size: 13.5px;
280      font-weight: 500;
281    }
282
283    .segmented {
284      flex: 0 0 auto;
285      display: flex;
286      gap: 3px;
287      padding: 3px;
288      border: 1px solid var(--line);
289      border-radius: 8px;
290      background: #f0f4f9;
291    }
292
293    .view-button {
294      width: 30px;
295      height: 30px;
296      display: inline-flex;
297      align-items: center;
298      justify-content: center;
299      border-radius: 7px;
300      background: transparent;
301      color: #9aa8bc;
302      font-size: 15px;
303      cursor: pointer;
304    }
305
306    .view-button.active {
307      background: #fff;
308      color: var(--accent);
309      box-shadow: 0 1px 3px rgba(16, 32, 46, 0.14);
310    }
311
312    .content {
313      flex: 1;
314      display: flex;
315      flex-direction: column;
316      overflow-y: auto;
317      padding: 20px 22px 26px;
318    }
319
320    .plugins {
321      flex: 0 0 auto;
322      display: grid;
323      grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
324      gap: 18px;
325      align-items: stretch;
326    }
327
328    .plugins.list {
329      display: flex;
330      flex-direction: column;
331      gap: 10px;
332    }
333
334    .plugin-card {
335      min-width: 0;
336      display: flex;
337      flex-direction: column;
338      overflow: hidden;
339      border: 1px solid var(--line-soft);
340      border-radius: 8px;
341      background: var(--panel);
342      box-shadow: var(--shadow);
343    }
344
345    .preview {
346      position: relative;
347      height: 158px;
348      overflow: hidden;
349      background: #0e1b2b;
350    }
351
352    .preview-bg,
353    .preview img {
354      position: absolute;
355      inset: 0;
356    }
357
358    .preview-bg {
359      z-index: 0;
360    }
361
362    .preview img {
363      z-index: 1;
364      width: 100%;
365      height: 100%;
366      object-fit: cover;
367    }
368
369    .preview img.icon-media {
370      width: 88px;
371      height: 88px;
372      margin: auto;
373      object-fit: contain;
374    }
375
376    .preview-badges {
377      position: absolute;
378      top: 11px;
379      left: 11px;
380      z-index: 2;
381      display: flex;
382      flex-direction: column;
383      align-items: flex-start;
384      gap: 6px;
385    }
386
387    .preview-ai {
388      position: absolute;
389      top: 11px;
390      right: 11px;
391      z-index: 2;
392    }
393
394    .badge {
395      display: inline-flex;
396      align-items: center;
397      gap: 4px;
398      height: 21px;
399      padding: 0 9px;
400      border-radius: 7px;
401      background: rgba(255, 255, 255, 0.92);
402      color: var(--accent-dark);
403      font-size: 10px;
404      font-weight: 800;
405      letter-spacing: 0.2px;
406      white-space: nowrap;
407      backdrop-filter: blur(4px);
408    }
409
410    .badge.key {
411      color: #b5701a;
412    }
413
414    .badge.ai {
415      background: rgba(15, 16, 30, 0.55);
416      color: #ffd9ae;
417    }
418
419    .dot {
420      width: 5px;
421      height: 5px;
422      border-radius: 999px;
423      background: #fda050;
424    }
425
426    .card-body {
427      flex: 1;
428      display: flex;
429      flex-direction: column;
430      gap: 9px;
431      padding: 15px 16px 16px;
432    }
433
434    .plugin-title {
435      margin: 0;
436      overflow: hidden;
437      color: var(--text);
438      font-size: 15.5px;
439      font-weight: 800;
440      text-overflow: ellipsis;
441      white-space: nowrap;
442    }
443
444    .plugin-desc {
445      margin: 0;
446      overflow: hidden;
447      display: -webkit-box;
448      -webkit-box-orient: vertical;
449      -webkit-line-clamp: 2;
450      color: var(--muted);
451      font-size: 12.5px;
452      font-weight: 500;
453      line-height: 1.5;
454    }
455
456    .card-bottom {
457      margin-top: auto;
458      display: flex;
459      align-items: center;
460      justify-content: space-between;
461      gap: 10px;
462      padding-top: 13px;
463      border-top: 1px solid #eef2f7;
464    }
465
466    .meta {
467      min-width: 0;
468      display: flex;
469      align-items: center;
470      gap: 8px;
471      flex-wrap: wrap;
472    }
473
474    .meta-text {
475      color: #9aa8bc;
476      font-family: "JetBrains Mono", "Courier New", monospace;
477      font-size: 10.5px;
478      font-weight: 600;
479      white-space: nowrap;
480    }
481
482    .platforms {
483      display: inline-flex;
484      gap: 2px;
485      padding: 2px;
486      border: 1px solid var(--line);
487      border-radius: 7px;
488      background: #f0f4f9;
489    }
490
491    .platform-chip {
492      padding: 3px 9px;
493      border-radius: 5px;
494      background: transparent;
495      color: var(--faint);
496      font-family: "JetBrains Mono", "Courier New", monospace;
497      font-size: 10px;
498      font-weight: 700;
499      cursor: pointer;
500    }
501
502    .platform-chip.active {
503      background: var(--accent);
504      color: #fff;
505    }
506
507    .download-btn {
508      height: 34px;
509      flex: 0 0 auto;
510      display: inline-flex;
511      align-items: center;
512      justify-content: center;
513      padding: 0 18px;
514      border-radius: 8px;
515      color: #fff;
516      background: linear-gradient(135deg, #2b9bf4, #1577e0);
517      box-shadow: 0 3px 8px rgba(21, 119, 224, 0.28);
518      font-size: 12.5px;
519      font-weight: 800;
520      text-decoration: none;
521      white-space: nowrap;
522      cursor: pointer;
523    }
524
525    .plugins.list .plugin-card {
526      min-height: 88px;
527      flex-direction: row;
528      align-items: center;
529      gap: 18px;
530      padding: 14px 18px;
531    }
532
533    .plugins.list .preview {
534      width: 60px;
535      height: 60px;
536      flex: 0 0 60px;
537      border-radius: 8px;
538    }
539
540    .plugins.list .preview-badges,
541    .plugins.list .preview-ai {
542      display: none;
543    }
544
545    .plugins.list .preview img.icon-media {
546      width: 100%;
547      height: 100%;
548      transform: scale(1.25);
549    }
550
551    .plugins.list .card-body {
552      min-width: 0;
553      flex: 1;
554      display: grid;
555      grid-template-columns: minmax(180px, 300px) minmax(160px, 1fr) auto;
556      align-items: center;
557      gap: 18px;
558      padding: 0;
559    }
560
561    .plugins.list .plugin-heading {
562      min-width: 0;
563    }
564
565    .plugins.list .plugin-title {
566      font-size: 15px;
567    }
568
569    .plugins.list .plugin-desc {
570      min-width: 0;
571      -webkit-line-clamp: 2;
572    }
573
574    .plugins.list .card-bottom {
575      flex: 0 0 auto;
576      flex-direction: column;
577      align-items: flex-end;
578      gap: 7px;
579      margin: 0;
580      padding: 0;
581      border: 0;
582    }
583
584    .empty {
585      flex: 1;
586      display: none;
587      text-align: center;
588      padding: 56px 20px;
589    }
590
591    .empty.visible {
592      display: block;
593    }
594
595    .empty h3 {
596      margin: 0;
597      color: var(--text);
598      font-size: 16px;
599      font-weight: 800;
600    }
601
602    .empty p {
603      margin: 7px 0 18px;
604      color: #62718a;
605      font-size: 13px;
606    }
607
608    .reset-btn {
609      height: 38px;
610      padding: 0 18px;
611      border-radius: 8px;
612      background: var(--accent);
613      color: #fff;
614      font-size: 13px;
615      font-weight: 700;
616      cursor: pointer;
617    }
618
619    .footer {
620      display: flex;
621      align-items: center;
622      justify-content: space-between;
623      gap: 16px;
624      margin: auto -22px -26px;
625      padding: 15px 22px;
626      border-top: 1px solid var(--line);
627      background: var(--panel);
628    }
629
630    .footer[hidden] {
631      display: none;
632    }
633
634    .footer.after-scroll {
635      margin-top: 34px;
636    }
637
638    .footer-note {
639      color: var(--faint);
640      font-size: 12px;
641      font-weight: 600;
642    }
643
644    .footer-links {
645      display: flex;
646      align-items: center;
647      gap: 16px;
648      font-size: 12.5px;
649      font-weight: 700;
650    }
651
652    .footer-links a {
653      color: var(--accent);
654      text-decoration: none;
655    }
656
657    .footer-sep {
658      width: 1px;
659      height: 13px;
660      background: #dce4ee;
661    }
662
663    .toast {
664      position: fixed;
665      right: 18px;
666      bottom: 18px;
667      z-index: 10;
668      max-width: min(420px, calc(100vw - 36px));
669      padding: 12px 14px;
670      border-radius: 8px;
671      background: #16202e;
672      color: #fff;
673      box-shadow: 0 12px 30px rgba(15, 23, 42, 0.22);
674      font-size: 13px;
675      font-weight: 700;
676      opacity: 0;
677      transform: translateY(8px);
678      pointer-events: none;
679      transition: opacity 0.18s ease, transform 0.18s ease;
680    }
681
682    .toast.visible {
683      opacity: 1;
684      transform: translateY(0);
685    }
686
687    @media (max-width: 1080px) {
688      .plugins.list .card-body {
689        grid-template-columns: minmax(160px, 260px) minmax(140px, 1fr);
690      }
691
692      .plugins.list .card-bottom {
693        grid-column: 1 / -1;
694        flex-direction: row;
695        align-items: center;
696        justify-content: space-between;
697      }
698    }
699
700    @media (max-width: 900px) {
701      .toolbar {
702        flex-wrap: wrap;
703        gap: 10px;
704      }
705
706      .toolbar-spacer {
707        display: none;
708      }
709
710      .search {
711        order: 3;
712        width: 100%;
713      }
714    }
715
716    @media (max-width: 720px) {
717      .toolbar,
718      .content {
719        padding-left: 14px;
720        padding-right: 14px;
721      }
722
723      .plugins {
724        grid-template-columns: 1fr;
725      }
726
727      .plugins.list .plugin-card {
728        flex-direction: column;
729        align-items: stretch;
730      }
731
732      .plugins.list .preview {
733        width: 100%;
734        height: 120px;
735        flex-basis: auto;
736      }
737
738      .plugins.list .preview-badges,
739      .plugins.list .preview-ai {
740        display: flex;
741      }
742
743      .plugins.list .card-body {
744        display: flex;
745        flex-direction: column;
746        align-items: stretch;
747        gap: 9px;
748      }
749
750      .plugins.list .card-bottom {
751        padding-top: 13px;
752        border-top: 1px solid #eef2f7;
753      }
754
755      .footer {
756        align-items: flex-start;
757        flex-direction: column;
758        margin-left: -14px;
759        margin-right: -14px;
760        padding-left: 14px;
761        padding-right: 14px;
762      }
763
764      .footer-links {
765        flex-wrap: wrap;
766        gap: 10px;
767      }
768
769      .footer-sep {
770        display: none;
771      }
772    }
773  </style>
774</head>
775<body>
776  <!-- Google Tag Manager (noscript) -->
vendor: 70 bytes, lines 776-777
776
777  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
777GTM-WMB2TZX
vendor: 85 bytes, lines 777-778
777" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
778  
778<!-- End Google Tag Manager (noscript) -->
779  <div class="app-shell" id="shell">
780    <aside class="sidebar" aria-label="Marketplace filters">
781      <div class="brand">
782        <div class="brand-title">AVS4YOU</div>
783        <div class="brand-subtitle">Plugin Marketplace</div>
784      </div>
785
786      <div class="rail-section">
787        <div class="rail-title">Categories</div>
788        <div id="categories"></div>
789      </div>
790
791      <div class="rail-section">
792        <div class="rail-title">Applications</div>
793        <div id="apps"></div>
794      </div>
795    </aside>
796
797    <main class="main">
798      <header class="toolbar">
799        <div class="heading">
800          <div class="heading-title" id="currentTitle">All plugins</div>
801          <div class="heading-subtitle" id="resultLabel">0 plugins available</div>
802        </div>
803        <div class="toolbar-spacer"></div>
804        <label class="search">
805          <span aria-hidden="true" data-icon="search"></span>
806          <input id="search" type="search" placeholder="Search plugins..." autocomplete="off">
807        </label>
808        <div class="segmented" aria-label="View">
809          <button class="view-button active" id="gridView" type="button" title="Grid view" aria-label="Grid view"></button>
810          <button class="view-button" id="listView" type="button" title="List view" aria-label="List view"></button>
811        </div>
812      </header>
813
814      <section class="content">
815        <div class="plugins" id="plugins"></div>
816        <div class="empty" id="empty">
817          <h3>No plugins match</h3>
818          <p>Try another category, app, or search.</p>
819          <button class="reset-btn" id="reset" type="button">Reset filters</button>
820        </div>
821        <footer class="footer" id="footer">
822          <div class="footer-note">All plugins are open source and available on GitHub</div>
823          <div class="footer-links">
824            <a href="https://github.com/avs4you/avs4you.github.io" target="_blank" rel="noopener">View on GitHub</a>
825            <span class="footer-sep"></span>
826            <a href="docs">Documentation</a>
827            <span class="footer-sep"></span>
828            <a href="https://avs4you.com" target="_blank" rel="noopener">Visit AVS4YOU</a>
829          </div>
830        </footer>
831      </section>
832    </main>
833  </div>
834  <div class="toast" id="toast" role="status" aria-live="polite"></div>
835
836  
836<script type="application/json" id="plugins-data">
837[
838  {
839    "slug": "effect-restoration-gaterv3",
840    "pluginId": "EffectGaterv3.plugin",
841    "name": "Restoration Gaterv3",
842    "desc": "A 1x restoration model for improving image quality, including noise, resizing, JPEG compression and mild blur.",
843    "apps": [
844      "Image Converter",
845      "Video Converter",
846      "Video Editor"
847    ],
848    "version": "v1.0.0",
849    "type": "effect",
850    "typeLabel": "Image Effect",
851    "aiPowered": true,
852    "requiresKey": false,
853    "tint": "linear-gradient(135deg,#1FA85C,#0FB5C9)",
854    "media": "plugins/effect-restoration-gaterv3/Effect Restoration Gaterv3.gif",
855    "basePath": "plugins/effect-restoration-gaterv3",
856    "downloads": {
857      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-restoration-gaterv3-v1.0.0/effect-restoration-gaterv3-v1.0.0-x86.avsp",
858      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-restoration-gaterv3-v1.0.0/effect-restoration-gaterv3-v1.0.0-x64.avsp"
859    }
860  },
861  {
862    "slug": "effect-spiral",
863    "pluginId": "EffectSpiral.plugin",
864    "name": "Effect Spiral",
865    "desc": "Dynamic spiral distortion with an outward explosion effect. Radial twist and expansion animations for stunning visuals.",
866    "apps": [
867      "Video Converter",
868      "Video Editor"
869    ],
870    "version": "v1.0.1",
871    "type": "effect",
872    "typeLabel": "Image Effect",
873    "aiPowered": false,
874    "requiresKey": false,
875    "tint": "linear-gradient(135deg,#3B4FE0,#7C5CFF)",
876    "media": "plugins/effect-spiral/Effect Spiral.gif",
877    "basePath": "plugins/effect-spiral",
878    "downloads": {
879      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-spiral-v1.0.1/effect-spiral-v1.0.1-x86.avsp",
880      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-spiral-v1.0.1/effect-spiral-v1.0.1-x64.avsp"
881    }
882  },
883  {
884    "slug": "effect-vhs",
885    "pluginId": "EffectVHS.plugin",
886    "name": "Effect VHS",
887    "desc": "Authentic VHS tape effect with noise, color degradation, tracking errors and chromatic aberration for a retro 80s-90s feel.",
888    "apps": [
889      "Video Converter",
890      "Video Editor",
891      "Image Converter"
892    ],
893    "version": "v1.0.1",
894    "type": "effect",
895    "typeLabel": "Image Effect",
896    "aiPowered": false,
897    "requiresKey": false,
898    "tint": "linear-gradient(135deg,#E0398E,#7C2BD6)",
899    "media": "plugins/effect-vhs/Effect VHS.gif",
900    "basePath": "plugins/effect-vhs",
901    "downloads": {
902      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-vhs-v1.0.1/effect-vhs-v1.0.1-x86.avsp",
903      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/effect-vhs-v1.0.1/effect-vhs-v1.0.1-x64.avsp"
904    }
905  },
906  {
907    "slug": "heygen",
908    "pluginId": "heygen.plugin",
909    "name": "HeyGen AI Video Generator",
910    "desc": "The best online AI video generator and creator for professionals and marketers who value ease of use.",
911    "apps": [
912      "Video Converter",
913      "Video Editor"
914    ],
915    "version": "v1.0.0",
916    "type": "content",
917    "typeLabel": "Content Plugin",
918    "aiPowered": true,
919    "requiresKey": true,
920    "tint": "linear-gradient(135deg,#FF9A2E,#F2552E)",
921    "media": "plugins/heygen/res/icons/app-icon.ico",
922    "basePath": "plugins/heygen",
923    "downloads": {
924      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/heygen-v1.0.0/heygen-v1.0.0-x86.avsp",
925      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/heygen-v1.0.0/heygen-v1.0.0-x64.avsp"
926    }
927  },
928  {
929    "slug": "nano-banana",
930    "pluginId": "NanoBanana.plugin",
931    "name": "Nano Banana Image Generator",
932    "desc": "Generate, edit, ground, and iterate images with Google Nano Banana models through the Gemini API.",
933    "apps": [
934      "Video Converter",
935      "Video Editor",
936      "Photo Editor"
937    ],
938    "version": "v1.0.0",
939    "type": "content",
940    "typeLabel": "Content Plugin",
941    "aiPowered": true,
942    "requiresKey": true,
943    "tint": "linear-gradient(135deg,#FFD33D,#22B8A8)",
944    "media": "plugins/nano-banana/icon.ico",
945    "basePath": "plugins/nano-banana",
946    "downloads": {
947      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/nano-banana-v1.0.0/nano-banana-v1.0.0-x86.avsp",
948      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/nano-banana-v1.0.0/nano-banana-v1.0.0-x64.avsp"
949    }
950  },
951  {
952    "slug": "sora2",
953    "pluginId": "Sora2.plugin",
954    "name": "Sora2 Video Generator",
955    "desc": "AI-powered video generation using OpenAI's Sora 2 API. Create high-quality videos from text directly in your AVS workflow.",
956    "apps": [
957      "Video Converter",
958      "Video Editor"
959    ],
960    "version": "v1.0.0",
961    "type": "content",
962    "typeLabel": "Content Plugin",
963    "aiPowered": true,
964    "requiresKey": true,
965    "tint": "linear-gradient(135deg,#0FB5C9,#1577E0)",
966    "media": "plugins/sora2/icon.ico",
967    "basePath": "plugins/sora2",
968    "downloads": {
969      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sora2-v1.0.0/sora2-v1.0.0-x86.avsp",
970      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sora2-v1.0.0/sora2-v1.0.0-x64.avsp"
971    }
972  },
973  {
974    "slug": "stableaudio3",
975    "pluginId": "StableAudio3.plugin",
976    "name": "Stable Audio 3 Generator",
977    "desc": "Generate audio locally with Stable Audio 3 using CPU or NVIDIA CUDA acceleration.",
978    "apps": [
979      "Audio Editor",
980      "Video Editor"
981    ],
982    "version": "v1.0.0",
983    "type": "content",
984    "typeLabel": "Content Plugin",
985    "aiPowered": true,
986    "requiresKey": false,
987    "tint": "linear-gradient(135deg,#6B5CE7,#2E9CCA)",
988    "media": "plugins/StableAudio3/icon.ico",
989    "basePath": "plugins/StableAudio3",
990    "downloads": {
991      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/stableaudio3-v1.0.0/stableaudio3-v1.0.0-x86.avsp",
992      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/stableaudio3-v1.0.0/stableaudio3-v1.0.0-x64.avsp"
993    }
994  },
995  {
996    "slug": "sunoapi",
997    "pluginId": "SunoApi.plugin",
998    "name": "Suno API Music Generator",
999    "desc": "Generate songs, lyrics and sounds, extend or transform audio with Suno API.",
1000    "apps": [
1001      "Audio Editor",
1002      "Audio Converter",
1003      "Video Editor",
1004      "Video Converter"
1005    ],
1006    "version": "v1.0.0",
1007    "type": "content",
1008    "typeLabel": "Content Plugin",
1009    "aiPowered": true,
1010    "requiresKey": true,
1011    "tint": "linear-gradient(135deg,#7C3AED,#EC4899)",
1012    "media": "plugins/sunoapi/icon.ico",
1013    "basePath": "plugins/sunoapi",
1014    "downloads": {
1015      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sunoapi-v1.0.0/sunoapi-v1.0.0-x86.avsp",
1016      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/sunoapi-v1.0.0/sunoapi-v1.0.0-x64.avsp"
1017    }
1018  },
1019  {
1020    "slug": "supertonic3",
1021    "pluginId": "Supertonic3.plugin",
1022    "name": "Supertonic 3 Text to Speech",
1023    "desc": "Generate natural multilingual speech locally with Supertonic 3 and ONNX Runtime directly in AVS Audio Editor and AVS Video Editor.",
1024    "apps": [
1025      "Audio Editor",
1026      "Video Editor"
1027    ],
1028    "version": "v1.0.0",
1029    "type": "content",
1030    "typeLabel": "Content Plugin",
1031    "aiPowered": true,
1032    "requiresKey": false,
1033    "tint": "linear-gradient(135deg,#7756E8,#3478F6)",
1034    "media": "plugins/Supertonic3/icon.ico",
1035    "basePath": "plugins/Supertonic3",
1036    "downloads": {
1037      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/supertonic3-v1.0.0/supertonic3-v1.0.0-x86.avsp",
1038      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/supertonic3-v1.0.0/supertonic3-v1.0.0-x64.avsp"
1039    }
1040  },
1041  {
1042    "slug": "veo3",
1043    "pluginId": "Veo3.plugin",
1044    "name": "Veo3 Video Generator",
1045    "desc": "AI-powered video creation with Google Veo 3. Turn your ideas into polished, cinematic clips from simple text prompts inside your AVS workflow.",
1046    "apps": [
1047      "Video Converter",
1048      "Video Editor"
1049    ],
1050    "version": "v1.0.0",
1051    "type": "content",
1052    "typeLabel": "Content Plugin",
1053    "aiPowered": true,
1054    "requiresKey": true,
1055    "tint": "linear-gradient(135deg,#0FB5C9,#1577E0)",
1056    "media": "plugins/veo3/icon.ico",
1057    "basePath": "plugins/veo3",
1058    "downloads": {
1059      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/veo3-v1.0.0/veo3-v1.0.0-x86.avsp",
1060      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/veo3-v1.0.0/veo3-v1.0.0-x64.avsp"
1061    }
1062  },
1063  {
1064    "slug": "youtube",
1065    "pluginId": "Youtube.plugin",
1066    "name": "YouTube Video Downloader",
1067    "desc": "Download video and audio from YouTube, Twitch and other sites supported by yt-dlp directly into your AVS workflow.",
1068    "apps": [
1069      "Video Converter",
1070      "Video Editor"
1071    ],
1072    "version": "v1.0.0",
1073    "type": "content",
1074    "typeLabel": "Content Plugin",
1075    "aiPowered": false,
1076    "requiresKey": false,
1077    "tint": "linear-gradient(135deg,#FF0000,#CC0000)",
1078    "media": "plugins/youtube/icon.ico",
1079    "basePath": "plugins/youtube",
1080    "downloads": {
1081      "x86": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/youtube-v1.0.0/youtube-v1.0.0-x86.avsp",
1082      "x64": "https://github.com/AVS4YOU/avs4you.github.io/releases/download/youtube-v1.0.0/youtube-v1.0.0-x64.avsp"
1083    }
1084  }
1085]
1086</script>
1086
1087
1088  
1088<script>
1089    let PLUGINS = [];
1090
1091    const ICON_PLUGIN_BACKGROUND = "linear-gradient(135deg,#0FB5C9,#1577E0)";
1092    const X86_ONLY = true;
1093    // Architectures come from the data (package.py writes plugin.downloads),
1094    // so adding one only means adding it to ARCHS in release.py.
1095    const DEFAULT_ARCH = "x86";
1096
1097    const ICONS = {
1098      search: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>',
1099      grid: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="7" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="14" width="7" height="7" rx="1.5"/></svg>',
1100      list: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M8 6h13M8 12h13M8 18h13"/><path d="M3 6h.01M3 12h.01M3 18h.01"/></svg>',
1101      all: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="3"/></svg>',
1102      ai: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2v4M12 18v4M2 12h4M18 12h4M4.9 4.9l2.8 2.8M16.3 16.3l2.8 2.8M19.1 4.9l-2.8 2.8M7.7 16.3l-2.8 2.8"/><circle cx="12" cy="12" r="3"/></svg>',
1103      effect: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m12 3 1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3Z"/><path d="m19 15 .8 2.2L22 18l-2.2.8L19 21l-.8-2.2L16 18l2.2-.8L19 15Z"/></svg>',
1104      content: '<svg class="svg-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 5h16M4 12h16M4 19h16"/><path d="M8 5v14"/></svg>'
1105    };
1106
1107    const CATEGORIES = [
1108      { key: "all", label: "All plugins", icon: "all" },
1109      { key: "ai", label: "AI Powered", icon: "ai" },
1110      { key: "effect", label: "Effects", icon: "effect" },
1111      { key: "content", label: "Content", icon: "content" }
1112    ];
1113
1114    const APPS = [
1115      { key: "all", label: "All apps", icon: "all" },
1116      { key: "Video Converter", label: "AVS Video Converter", asset: "assets/AVSVideoConverter_Icon.png" },
1117      { key: "Video Editor", label: "AVS Video Editor", asset: "assets/AVSVideoEditor_Icon.png" },
1118      { key: "Image Converter", label: "AVS Image Converter", asset: "assets/AVSImageConverter_Icon.png" },
1119      { key: "Audio Editor", label: "AVS Audio Editor", asset: "assets/AVSAudioEditor_Icon.png" },
1120      { key: "Audio Converter", label: "AVS Audio Converter", asset: "assets/AVSAudioConverter_Icon.png" },
1121      { key: "Video ReMaker", label: "AVS Video ReMaker", asset: "assets/AVSVideoReMaker_Icon.png" }
1122    ];
1123
1124    function getAppLabel(appKey) {
1125      const app = APPS.find((item) => item.key === appKey);
1126      return app ? app.label : appKey;
1127    }
1128
1129    const params = new URLSearchParams(window.location.search);
1130    const typeParam = (params.get("type") || "").toLowerCase();
1131    const typeAppFilter = {
1132      vc: "Video Converter",
1133      ve: "Video Editor",
1134      ic: "Image Converter",
1135      ae: "Audio Editor",
1136      ac: "Audio Converter",
1137      rm: "Video ReMaker"
1138    };
1139    const initialAppFilter = typeAppFilter[typeParam] || "all";
1140    const state = {
1141      isApp: typeParam === "app" || initialAppFilter !== "all",
1142      appPlatform: params.get("platform") || DEFAULT_ARCH,
1143      category: "all",
1144      app: initialAppFilter,
1145      search: "",
1146      view: "grid",
1147      platform: {}
1148    };
1149
1150    const els = {
1151      brand: document.querySelector(".brand"),
1152      categories: document.getElementById("categories"),
1153      apps: document.getElementById("apps"),
1154      plugins: document.getElementById("plugins"),
1155      empty: document.getElementById("empty"),
1156      reset: document.getElementById("reset"),
1157      search: document.getElementById("search"),
1158      currentTitle: document.getElementById("currentTitle"),
1159      resultLabel: document.getElementById("resultLabel"),
1160      gridView: document.getElementById("gridView"),
1161      listView: document.getElementById("listView"),
1162      footer: document.getElementById("footer"),
1163      toast: document.getElementById("toast")
1164    };
1165
1166    let toastTimer = null;
1167
1168    function renderStaticIcons() {
1169      els.gridView.innerHTML = ICONS.grid;
1170      els.listView.innerHTML = ICONS.list;
1171      document.querySelectorAll("[data-icon]").forEach((element) => {
1172        element.innerHTML = ICONS[element.dataset.icon] || "";
1173      });
1174    }
1175
1176    function loadPlugins() {
1177      const node = document.getElementById("plugins-data");
1178      if (!node) throw new Error("Missing plugins-data");
1179      PLUGINS = JSON.parse(node.textContent || "[]");
1180    }
1181
1182    function matchCategory(plugin, category) {
1183      if (category === "all") return true;
1184      if (category === "effect") return plugin.type === "effect";
1185      if (category === "ai") return plugin.aiPowered;
1186      if (category === "content") return plugin.type === "content";
1187      return true;
1188    }
1189
1190    function getHref(plugin, platform) {
1191      // Absolute GitHub release links baked in by package.py, keyed by arch.
1192      const downloads = plugin.downloads || {};
1193      return downloads[platform] || downloads[DEFAULT_ARCH] || "";
1194    }
1195
1196    function getFilteredPlugins() {
1197      const query = state.search.trim().toLowerCase();
1198      return PLUGINS.filter((plugin) => {
1199        if (!matchCategory(plugin, state.category)) return false;
1200        if (state.app !== "all" && !plugin.apps.includes(state.app)) return false;
1201        if (!query) return true;
1202        return (
1203          plugin.name.toLowerCase().includes(query) ||
1204          plugin.desc.toLowerCase().includes(query) ||
1205          plugin.typeLabel.toLowerCase().includes(query)
1206        );
1207      });
1208    }
1209
1210    function makeButton(item, active, count, onClick) {
1211      const button = document.createElement("button");
1212      button.type = "button";
1213      button.className = "rail-button" + (active ? " active" : "");
1214      button.addEventListener("click", onClick);
1215
1216      const icon = document.createElement(item.asset ? "img" : "span");
1217      if (item.asset) {
1218        icon.className = "app-badge app-icon";
1219        icon.src = item.asset;
1220        icon.alt = "";
1221        icon.setAttribute("aria-hidden", "true");
1222      } else {
1223        icon.className = "rail-icon";
1224        icon.innerHTML = ICONS[item.icon] || "";
1225      }
1226
1227      const label = document.createElement("span");
1228      label.className = "rail-label";
1229      label.textContent = item.label;
1230
1231      const counter = document.createElement("span");
1232      counter.className = "rail-count";
1233      counter.textContent = count;
1234
1235      button.append(icon, label, counter);
1236      return button;
1237    }
1238
1239    function renderFilters() {
1240      els.categories.replaceChildren();
1241      CATEGORIES.forEach((item) => {
1242        const count = PLUGINS.filter((plugin) => matchCategory(plugin, item.key)).length;
1243        els.categories.appendChild(makeButton(item, state.category === item.key, count, () => {
1244          state.category = item.key;
1245          render();
1246        }));
1247      });
1248
1249      els.apps.replaceChildren();
1250      APPS.forEach((item) => {
1251        const count = item.key === "all"
1252          ? PLUGINS.length
1253          : PLUGINS.filter((plugin) => plugin.apps.includes(item.key)).length;
1254        els.apps.appendChild(makeButton(item, state.app === item.key, count, () => {
1255          state.app = item.key;
1256          render();
1257        }));
1258      });
1259    }
1260
1261    function makeBadge(text, className) {
1262      const badge = document.createElement("span");
1263      badge.className = "badge" + (className ? " " + className : "");
1264      badge.textContent = text;
1265      return badge;
1266    }
1267
1268    function makeAiBadge() {
1269      const badge = makeBadge("AI", "ai");
1270      const dot = document.createElement("span");
1271      dot.className = "dot";
1272      badge.prepend(dot);
1273      return badge;
1274    }
1275
1276    function makePlatformChips(plugin, activePlatform) {
1277      if (state.isApp || X86_ONLY) return null;
1278
1279      const wrap = document.createElement("span");
1280      wrap.className = "platforms";
1281
1282      Object.keys(plugin.downloads || {}).forEach((platform) => {
1283        const chip = document.createElement("button");
1284        chip.type = "button";
1285        chip.className = "platform-chip" + (platform === activePlatform ? " active" : "");
1286        chip.textContent = platform;
1287        chip.addEventListener("click", () => {
1288          state.platform[plugin.slug] = platform;
1289          renderPlugins();
1290        });
1291        wrap.appendChild(chip);
1292      });
1293
1294      return wrap;
1295    }
1296
1297    function showToast(message) {
1298      els.toast.textContent = message;
1299      els.toast.classList.add("visible");
1300      clearTimeout(toastTimer);
1301      toastTimer = setTimeout(() => {
1302        els.toast.classList.remove("visible");
1303      }, 2800);
1304    }
1305
1306    function handleAction(event, href) {
1307      if (!state.isApp) return;
1308
1309      event.preventDefault();
1310      try {
1311        if (window.chrome && window.chrome.webview) {
1312          window.chrome.webview.postMessage("download|" + href);
1313        }
1314      } catch (error) {
1315        // WebView messaging is only available inside the host application.
1316      }
1317      showToast("Install requested: " + href.split("/").pop());
1318    }
1319
1320    function makeCard(plugin) {
1321      const activePlatform = state.isApp
1322        ? state.appPlatform
1323        : (X86_ONLY ? DEFAULT_ARCH : (state.platform[plugin.slug] || state.appPlatform));
1324      const href = getHref(plugin, activePlatform);
1325      const card = document.createElement("article");
1326      card.className = "plugin-card";
1327
1328      const preview = document.createElement("div");
1329      preview.className = "preview";
1330
1331      const previewBg = document.createElement("div");
1332      previewBg.className = "preview-bg";
1333      previewBg.style.background = /\.ico$/i.test(plugin.media || "")
1334        ? ICON_PLUGIN_BACKGROUND
1335        : plugin.tint;
1336      preview.appendChild(previewBg);
1337
1338      if (plugin.media) {
1339        const image = document.createElement("img");
1340        image.src = plugin.media;
1341        image.alt = plugin.name;
1342        if (/\.ico$/i.test(plugin.media)) image.className = "icon-media";
1343        preview.appendChild(image);
1344      }
1345
1346      const badges = document.createElement("div");
1347      badges.className = "preview-badges";
1348      badges.appendChild(makeBadge(plugin.typeLabel));
1349      if (plugin.requiresKey) badges.appendChild(makeBadge("API key", "key"));
1350      preview.appendChild(badges);
1351
1352      if (plugin.aiPowered) {
1353        const ai = document.createElement("div");
1354        ai.className = "preview-ai";
1355        ai.appendChild(makeAiBadge());
1356        preview.appendChild(ai);
1357      }
1358
1359      const body = document.createElement("div");
1360      body.className = "card-body";
1361
1362      const heading = document.createElement("div");
1363      heading.className = "plugin-heading";
1364
1365      const title = document.createElement("h3");
1366      title.className = "plugin-title";
1367      title.textContent = plugin.name;
1368      heading.appendChild(title);
1369
1370      const desc = document.createElement("p");
1371      desc.className = "plugin-desc";
1372      desc.textContent = plugin.desc;
1373
1374      const bottom = document.createElement("div");
1375      bottom.className = "card-bottom";
1376
1377      const meta = document.createElement("div");
1378      meta.className = "meta";
1379
1380      const metaText = document.createElement("span");
1381      metaText.className = "meta-text";
1382      metaText.textContent = state.isApp
1383        ? activePlatform + " \u00b7 " + plugin.version
1384        : plugin.version;
1385
1386      const platformChips = makePlatformChips(plugin, activePlatform);
1387      meta.append(metaText);
1388      if (platformChips) meta.append(platformChips);
1389
1390      const link = document.createElement("a");
1391      link.className = "download-btn";
1392      link.href = state.isApp ? "#" : href;
1393      link.textContent = state.isApp ? "Install" : "Download";
1394      if (!state.isApp) link.setAttribute("download", "");
1395      link.addEventListener("click", (event) => handleAction(event, href));
1396
1397      bottom.append(meta, link);
1398      body.append(heading, desc, bottom);
1399      card.append(preview, body);
1400      return card;
1401    }
1402
1403    function renderPlugins() {
1404      const filtered = getFilteredPlugins();
1405      els.plugins.className = "plugins" + (state.view === "list" ? " list" : "");
1406      els.plugins.replaceChildren(...filtered.map(makeCard));
1407      els.empty.classList.toggle("visible", filtered.length === 0);
1408      els.plugins.style.display = filtered.length === 0 ? "none" : "";
1409      requestAnimationFrame(() => {
1410        const content = document.querySelector(".content");
1411        const canScroll = content.scrollHeight > content.clientHeight + 1;
1412        els.footer.classList.toggle("after-scroll", canScroll);
1413      });
1414
1415      const currentCategory = CATEGORIES.find((item) => item.key === state.category);
1416      els.currentTitle.textContent = state.app !== "all"
1417        ? getAppLabel(state.app)
1418        : (currentCategory ? currentCategory.label : "All plugins");
1419      els.resultLabel.textContent = filtered.length === PLUGINS.length
1420        ? PLUGINS.length + " plugins available"
1421        : filtered.length + " of " + PLUGINS.length + " shown";
1422    }
1423
1424    function render() {
1425      els.gridView.classList.toggle("active", state.view === "grid");
1426      els.listView.classList.toggle("active", state.view === "list");
1427      els.footer.hidden = state.isApp;
1428      els.brand.hidden = state.isApp;
1429      renderFilters();
1430      renderPlugins();
1431    }
1432
1433    els.gridView.addEventListener("click", () => {
1434      state.view = "grid";
1435      render();
1436    });
1437
1438    els.listView.addEventListener("click", () => {
1439      state.view = "list";
1440      render();
1441    });
1442
1443    els.search.addEventListener("input", (event) => {
1444      state.search = event.target.value;
1445      renderPlugins();
1446    });
1447
1448    els.reset.addEventListener("click", () => {
1449      state.category = "all";
1450      state.app = "all";
1451      state.search = "";
1452      els.search.value = "";
1453      render();
1454    });
1455
1456    async function init() {
1457      renderStaticIcons();
1458      try {
1459        loadPlugins();
1460      } catch (error) {
1461        console.warn(error);
1462        els.currentTitle.textContent = "Plugins unavailable";
1463        els.resultLabel.textContent = "Could not load plugin data";
1464        els.empty.classList.add("visible");
1465        els.empty.querySelector("h3").textContent = "Plugins unavailable";
1466        els.empty.querySelector("p").textContent = "Run package.py and reload the page.";
1467        els.reset.hidden = true;
1468        els.footer.hidden = true;
1469        return;
1470      }
1471      render();
1472    }
1473
1474    init();
1475  </script>
1475
1476</body>
1477</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.