pinokiod 7.2.12 → 7.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/Dockerfile +0 -2
  2. package/kernel/api/index.js +14 -1
  3. package/kernel/api/process/index.js +99 -44
  4. package/kernel/api/uri/index.js +51 -0
  5. package/kernel/git.js +0 -13
  6. package/kernel/index.js +4 -0
  7. package/kernel/plugin.js +6 -58
  8. package/kernel/plugin_sources.js +236 -0
  9. package/kernel/util.js +60 -0
  10. package/package.json +1 -1
  11. package/server/features/drafts/public/drafts.js +35 -12
  12. package/server/index.js +110 -142
  13. package/server/lib/content_validation.js +28 -25
  14. package/server/public/common.js +95 -29
  15. package/server/public/create-launcher.js +4 -31
  16. package/server/public/electron.css +1 -1
  17. package/server/public/style.css +337 -0
  18. package/server/public/task-launcher.js +5 -32
  19. package/server/public/universal-launcher.js +3 -26
  20. package/server/views/app.ejs +8 -29
  21. package/server/views/d.ejs +0 -33
  22. package/server/views/editor.ejs +25 -4
  23. package/server/views/shell.ejs +11 -3
  24. package/server/views/terminal.ejs +15 -3
  25. package/spec/INSTRUCTION_SYNC.md +5 -5
  26. package/system/plugin/antigravity/antigravity.png +0 -0
  27. package/system/plugin/antigravity/pinokio.js +37 -0
  28. package/system/plugin/claude/claude.png +0 -0
  29. package/system/plugin/claude/pinokio.js +63 -0
  30. package/system/plugin/claude-auto/claude.png +0 -0
  31. package/system/plugin/claude-auto/pinokio.js +74 -0
  32. package/system/plugin/claude-desktop/icon.jpeg +0 -0
  33. package/system/plugin/claude-desktop/pinokio.js +39 -0
  34. package/system/plugin/codex/openai.webp +0 -0
  35. package/system/plugin/codex/pinokio.js +58 -0
  36. package/system/plugin/codex-auto/openai.webp +0 -0
  37. package/system/plugin/codex-auto/pinokio.js +65 -0
  38. package/system/plugin/codex-desktop/icon.png +0 -0
  39. package/system/plugin/codex-desktop/pinokio.js +39 -0
  40. package/system/plugin/crush/crush.png +0 -0
  41. package/system/plugin/crush/pinokio.js +31 -0
  42. package/system/plugin/cursor/cursor.jpeg +0 -0
  43. package/system/plugin/cursor/pinokio.js +39 -0
  44. package/system/plugin/gemini/gemini.jpeg +0 -0
  45. package/system/plugin/gemini/pinokio.js +40 -0
  46. package/system/plugin/gemini-auto/gemini.jpeg +0 -0
  47. package/system/plugin/gemini-auto/pinokio.js +43 -0
  48. package/system/plugin/qwen/pinokio.js +50 -0
  49. package/system/plugin/qwen/qwen.png +0 -0
  50. package/system/plugin/vscode/pinokio.js +36 -0
  51. package/system/plugin/vscode/vscode.png +0 -0
  52. package/system/plugin/windsurf/pinokio.js +39 -0
  53. package/system/plugin/windsurf/windsurf.png +0 -0
@@ -1,6 +1,7 @@
1
1
  const fs = require("fs")
2
2
  const path = require("path")
3
3
  const clearModule = require("clear-module")
4
+ const PluginSources = require("../../kernel/plugin_sources")
4
5
 
5
6
  const {
6
7
  TASK_CONFIG_FILENAME,
@@ -117,23 +118,7 @@ function createContentValidationService({ kernel }) {
117
118
  }
118
119
 
119
120
  const normalizePluginPath = (value) => {
120
- let normalized = typeof value === "string" ? value.trim() : ""
121
- if (!normalized) {
122
- return ""
123
- }
124
- normalized = normalized.replace(/\\/g, "/")
125
- normalized = normalized.replace(/^\/run(?=\/)/, "")
126
- if (!normalized.startsWith("/")) {
127
- normalized = `/${normalized}`
128
- }
129
- normalized = normalized.replace(/\/{2,}/g, "/").replace(/\/+$/, "")
130
- if (!normalized) {
131
- return ""
132
- }
133
- if (!normalized.endsWith("/pinokio.js")) {
134
- normalized = `${normalized}/pinokio.js`
135
- }
136
- return normalized
121
+ return PluginSources.normalizePluginPath(value)
137
122
  }
138
123
 
139
124
  const normalizeBundledPluginSpec = (value) => {
@@ -169,9 +154,9 @@ function createContentValidationService({ kernel }) {
169
154
  }
170
155
 
171
156
  if (config && typeof config.icon === "string" && config.icon.trim()) {
172
- if (normalizedPath.startsWith("/plugin/")) {
173
- const relativeDir = path.posix.dirname(normalizedPath.slice(1))
174
- context.image = `/asset/${relativeDir}/${config.icon.trim()}`
157
+ const pluginImage = PluginSources.pluginAssetHrefForIcon(normalizedPath, config.icon)
158
+ if (pluginImage) {
159
+ context.image = pluginImage
175
160
  } else if (normalizedPath.startsWith("/api/")) {
176
161
  const segments = normalizedPath.replace(/^\/+/, "").split("/")
177
162
  const appName = segments[1] || ""
@@ -192,7 +177,10 @@ function createContentValidationService({ kernel }) {
192
177
  const fallbackTitle = normalizedPath
193
178
  ? path.basename(path.posix.dirname(normalizedPath))
194
179
  : "Plugin"
195
- if (!normalizedPath || (!normalizedPath.startsWith("/plugin/") && !normalizedPath.startsWith("/api/"))) {
180
+ const isSystemPlugin = PluginSources.isSystemPluginPath(normalizedPath)
181
+ const isHomePlugin = normalizedPath.startsWith("/plugin/")
182
+ const isApiPlugin = normalizedPath.startsWith("/api/")
183
+ if (!normalizedPath || (!isSystemPlugin && !isHomePlugin && !isApiPlugin)) {
196
184
  return buildInvalid({
197
185
  type: "plugin",
198
186
  subjectTitle: fallbackTitle,
@@ -205,8 +193,21 @@ function createContentValidationService({ kernel }) {
205
193
  detailUrl: "/plugins",
206
194
  })
207
195
  }
196
+ if (PluginSources.isLegacyPluginCodePath(normalizedPath)) {
197
+ return buildInvalid({
198
+ type: "plugin",
199
+ subjectTitle: fallbackTitle,
200
+ errors: [
201
+ buildError(
202
+ "This managed plugin path is no longer used.",
203
+ "Open the built-in Pinokio plugin instead."
204
+ ),
205
+ ],
206
+ detailUrl: "/plugins",
207
+ })
208
+ }
208
209
 
209
- const absolutePath = kernel.path(normalizedPath.replace(/^\/+/, ""))
210
+ const absolutePath = PluginSources.pluginPathToAbsolute(kernel, normalizedPath)
210
211
  const folderPath = path.dirname(absolutePath)
211
212
  const loaded = await loadJsFile(absolutePath)
212
213
  if (!loaded.exists) {
@@ -267,9 +268,8 @@ function createContentValidationService({ kernel }) {
267
268
  ))
268
269
  }
269
270
  if (normalizedPath.startsWith("/plugin/")) {
270
- const isManagedDefaultPlugin = normalizedPath.startsWith("/plugin/code/")
271
271
  const declaredPath = typeof config.path === "string" ? config.path.trim() : ""
272
- if (!isManagedDefaultPlugin && declaredPath !== "plugin") {
272
+ if (declaredPath !== "plugin") {
273
273
  errors.push(buildError(
274
274
  'Standalone plugins must set `path: "plugin"`.',
275
275
  'Add `path: "plugin"` to pinokio.js.',
@@ -567,7 +567,7 @@ function createContentValidationService({ kernel }) {
567
567
  })
568
568
  }
569
569
 
570
- const validateRunPath = async (pathComponents) => {
570
+ const validateRunPath = async (pathComponents, options = {}) => {
571
571
  if (!Array.isArray(pathComponents) || pathComponents.length === 0) {
572
572
  return buildValid()
573
573
  }
@@ -576,6 +576,9 @@ function createContentValidationService({ kernel }) {
576
576
  return buildValid()
577
577
  }
578
578
  if (normalized[0] === "plugin") {
579
+ if (options && options.system) {
580
+ return validatePluginByPath(`${PluginSources.SYSTEM_RUN_PREFIX}/${normalized.join("/")}`)
581
+ }
579
582
  return validatePluginByPath(`/${normalized.join("/")}`)
580
583
  }
581
584
  if (normalized[0] === "api" && normalized.length > 1) {
@@ -16,6 +16,7 @@ const requirementsGuardedRoutePrefixes = [
16
16
  '/api/',
17
17
  '/_api/',
18
18
  '/run/',
19
+ '/pinokio/run/',
19
20
  '/tools',
20
21
  '/bundle/',
21
22
  '/connect/',
@@ -104,6 +105,96 @@ function createMinimalLoadingSwal () {
104
105
  });
105
106
  return close;
106
107
  }
108
+
109
+ const PINOKIO_WAIT_FOOTER_ID = 'pinokio-process-wait-footer-status'
110
+ const PINOKIO_INSTALL_SPINNER_VARIANTS = ["grid-shift", "single-vacancy", "pulse-swap", "corner-chase", "flip-2x2", "stack-ripple", "pixel-orbit", "binary-shuffle"]
111
+ const PINOKIO_INSTALL_STATUS_SPINNER_HTML = `
112
+ <span class="install-status-spinner" aria-hidden="true">
113
+ <span class="install-status-grid-anchor install-status-grid-anchor-1"></span>
114
+ <span class="install-status-grid-anchor install-status-grid-anchor-2"></span>
115
+ <span class="install-status-grid-anchor install-status-grid-anchor-3"></span>
116
+ <span class="install-status-grid-anchor install-status-grid-anchor-4"></span>
117
+ <span class="install-status-grid-tile install-status-grid-tile-1"></span>
118
+ <span class="install-status-grid-tile install-status-grid-tile-2"></span>
119
+ <span class="install-status-grid-tile install-status-grid-tile-3"></span>
120
+ <span class="install-status-grid-tile install-status-grid-tile-4"></span>
121
+ <span class="install-status-grid-chaser"></span>
122
+ <span class="install-status-grid-pixel"></span>
123
+ </span>`
124
+ let lastPinokioWaitSpinnerVariant = null
125
+
126
+ function escapePinokioStatusHtml(value) {
127
+ return String(value == null ? '' : value)
128
+ .replace(/&/g, '&amp;')
129
+ .replace(/</g, '&lt;')
130
+ .replace(/>/g, '&gt;')
131
+ .replace(/"/g, '&quot;')
132
+ .replace(/'/g, '&#39;')
133
+ }
134
+
135
+ function ensurePinokioWaitFooterStatus() {
136
+ let status = document.getElementById(PINOKIO_WAIT_FOOTER_ID)
137
+ if (status) {
138
+ return status
139
+ }
140
+ status = document.createElement('div')
141
+ status.id = PINOKIO_WAIT_FOOTER_ID
142
+ status.className = 'pinokio-install-inline-status pinokio-process-wait-footer-status'
143
+ status.hidden = true
144
+ status.setAttribute('aria-live', 'polite')
145
+
146
+ const anchor = document.querySelector('.terminal-container')
147
+ || document.querySelector('main')
148
+ || document.querySelector('#terminal')?.parentElement
149
+ || document.querySelector('footer')
150
+ || document.body
151
+
152
+ if (anchor && anchor !== document.body) {
153
+ anchor.insertAdjacentElement('afterend', status)
154
+ } else {
155
+ document.body.appendChild(status)
156
+ }
157
+ return status
158
+ }
159
+
160
+ function showPinokioWaitFooterStatus(data = {}) {
161
+ const title = data.title || 'Waiting'
162
+ const description = data.description || data.message || ''
163
+ const status = ensurePinokioWaitFooterStatus()
164
+ const candidates = PINOKIO_INSTALL_SPINNER_VARIANTS.filter((variant) => variant !== lastPinokioWaitSpinnerVariant)
165
+ const pool = candidates.length > 0 ? candidates : PINOKIO_INSTALL_SPINNER_VARIANTS
166
+ lastPinokioWaitSpinnerVariant = pool[Math.floor(Math.random() * pool.length)]
167
+ document.documentElement.dataset.installSpinnerVariant = lastPinokioWaitSpinnerVariant
168
+ status.className = 'pinokio-install-inline-status pinokio-process-wait-footer-status is-progress'
169
+ status.innerHTML = `
170
+ <div class="install-status-shell">
171
+ ${PINOKIO_INSTALL_STATUS_SPINNER_HTML}
172
+ <div class="install-status-copy">
173
+ <div class="install-status-title">${escapePinokioStatusHtml(title)}</div>
174
+ ${description ? `<div class="install-status-detail">${escapePinokioStatusHtml(description)}</div>` : ''}
175
+ </div>
176
+ </div>
177
+ `
178
+ status.hidden = false
179
+ document.body.classList.add('pinokio-install-status-visible')
180
+ }
181
+
182
+ function hidePinokioWaitFooterStatus() {
183
+ const status = document.getElementById(PINOKIO_WAIT_FOOTER_ID)
184
+ if (!status) {
185
+ return
186
+ }
187
+ status.hidden = true
188
+ status.innerHTML = ''
189
+ document.body.classList.remove('pinokio-install-status-visible')
190
+ }
191
+
192
+ if (typeof window !== 'undefined') {
193
+ window.PinokioWaitFooterStatus = {
194
+ show: showPinokioWaitFooterStatus,
195
+ hide: hidePinokioWaitFooterStatus
196
+ }
197
+ }
107
198
  function check_ready (targetUrl = null, options = {}) {
108
199
  createLauncherDebugLog('check_ready start');
109
200
  return fetch("/pinokio/requirements_ready").then((res) => {
@@ -3490,32 +3581,6 @@ document.addEventListener("DOMContentLoaded", () => {
3490
3581
  tools: null,
3491
3582
  toolsPromise: null
3492
3583
  };
3493
- const ASK_AI_FALLBACK_TOOLS = [
3494
- {
3495
- value: 'claude',
3496
- label: 'Claude Code',
3497
- iconSrc: '/asset/plugin/code/claude/claude.png',
3498
- href: '/run/plugin/code/claude/pinokio.js',
3499
- category: 'CLI',
3500
- isDefault: true
3501
- },
3502
- {
3503
- value: 'codex',
3504
- label: 'OpenAI Codex',
3505
- iconSrc: '/asset/plugin/code/codex/openai.webp',
3506
- href: '/run/plugin/code/codex/pinokio.js',
3507
- category: 'CLI',
3508
- isDefault: false
3509
- },
3510
- {
3511
- value: 'gemini',
3512
- label: 'Google Gemini CLI',
3513
- iconSrc: '/asset/plugin/code/gemini/gemini.jpeg',
3514
- href: '/run/plugin/code/gemini/pinokio.js',
3515
- category: 'CLI',
3516
- isDefault: false
3517
- }
3518
- ];
3519
3584
 
3520
3585
  initializeUniversalLauncherIntegration();
3521
3586
  initializeCreateLauncherIntegration();
@@ -3928,6 +3993,7 @@ document.addEventListener("DOMContentLoaded", () => {
3928
3993
  return typeof pathname === 'string'
3929
3994
  && (
3930
3995
  pathname.startsWith('/run/plugin/')
3996
+ || pathname.startsWith('/pinokio/run/plugin/')
3931
3997
  || (pathname.startsWith('/run/api/') && /\/pinokio\.js$/i.test(pathname))
3932
3998
  );
3933
3999
  }
@@ -4019,11 +4085,11 @@ document.addEventListener("DOMContentLoaded", () => {
4019
4085
  })
4020
4086
  .then((payload) => {
4021
4087
  const mapped = mapPluginMenuToAskAiTools(payload && Array.isArray(payload.menu) ? payload.menu : []);
4022
- return mapped.length > 0 ? mapped : ASK_AI_FALLBACK_TOOLS.slice();
4088
+ return mapped;
4023
4089
  })
4024
4090
  .catch((error) => {
4025
- console.warn('Failed to load Ask AI plugins, using fallback list', error);
4026
- return ASK_AI_FALLBACK_TOOLS.slice();
4091
+ console.warn('Failed to load Ask AI plugins', error);
4092
+ return [];
4027
4093
  })
4028
4094
  .finally(() => {
4029
4095
  askAiState.toolsPromise = null;
@@ -5,33 +5,6 @@
5
5
  return;
6
6
  }
7
7
 
8
- const FALLBACK_TOOLS = [
9
- {
10
- value: 'claude',
11
- label: 'Claude Code',
12
- iconSrc: '/asset/plugin/code/claude/claude.png',
13
- isDefault: true,
14
- href: '/run/plugin/code/claude/pinokio.js',
15
- category: 'CLI',
16
- },
17
- {
18
- value: 'codex',
19
- label: 'OpenAI Codex',
20
- iconSrc: '/asset/plugin/code/codex/openai.webp',
21
- isDefault: false,
22
- href: '/run/plugin/code/codex/pinokio.js',
23
- category: 'CLI',
24
- },
25
- {
26
- value: 'gemini',
27
- label: 'Google Gemini CLI',
28
- iconSrc: '/asset/plugin/code/gemini/gemini.jpeg',
29
- isDefault: false,
30
- href: '/run/plugin/code/gemini/pinokio.js',
31
- category: 'CLI',
32
- },
33
- ];
34
-
35
8
  const CATEGORY_ORDER = ['CLI', 'IDE'];
36
9
  const MODAL_VARIANTS = {
37
10
  CREATE: 'create',
@@ -83,7 +56,7 @@
83
56
 
84
57
  let value = '';
85
58
  if (href) {
86
- // Normalize href to a plugin-relative path for the backend (e.g., code/codex)
59
+ // Normalize href to a launcher tool path for the backend.
87
60
  const normalized = href.replace(/^\/run/, '').replace(/^\/+/, '');
88
61
  const parts = normalized.split('/').filter(Boolean);
89
62
  // Expect /plugin/<path...>/pinokio.js -> want <path...>
@@ -139,11 +112,11 @@
139
112
  .then((data) => {
140
113
  const menu = data && Array.isArray(data.menu) ? data.menu : [];
141
114
  const tools = mapPluginMenuToCreateLauncherTools(menu);
142
- return tools.length > 0 ? tools : FALLBACK_TOOLS.slice();
115
+ return tools;
143
116
  })
144
117
  .catch((error) => {
145
- console.warn('Falling back to default plugins for create launcher modal', error);
146
- return FALLBACK_TOOLS.slice();
118
+ console.warn('Failed to load create launcher plugins', error);
119
+ return [];
147
120
  })
148
121
  .finally(() => {
149
122
  loadingTools = null;
@@ -28,8 +28,8 @@ aside {
28
28
  header.grabbable {
29
29
  /*
30
30
  padding: 32px 10px 0 !important;
31
- padding: 26px 0px 0 !important;
32
31
  */
32
+ padding: 26px 0px 0 !important;
33
33
  }
34
34
  /*
35
35
  header {
@@ -2857,6 +2857,343 @@ body.dark .swal2-popup.pinokio-download-modal .pinokio-download-cancel.swal2-can
2857
2857
  body.dark .swal2-popup.pinokio-download-modal .pinokio-download-cancel.swal2-cancel:hover {
2858
2858
  background: rgba(148, 163, 184, 0.18) !important;
2859
2859
  }
2860
+ .pinokio-install-inline-status .install-status-shell {
2861
+ display: flex;
2862
+ align-items: flex-start;
2863
+ gap: 12px;
2864
+ min-height: 44px;
2865
+ }
2866
+ .pinokio-install-inline-status .install-status-copy {
2867
+ min-width: 0;
2868
+ flex: 1;
2869
+ }
2870
+ .pinokio-install-inline-status .install-status-title {
2871
+ color: inherit;
2872
+ font-size: 15px;
2873
+ line-height: 1.2;
2874
+ font-weight: 700;
2875
+ }
2876
+ .pinokio-install-inline-status .install-status-detail {
2877
+ margin-top: 4px;
2878
+ color: rgba(235, 222, 197, 0.82);
2879
+ font-size: 12px;
2880
+ line-height: 1.35;
2881
+ word-break: break-word;
2882
+ }
2883
+ body.dark .pinokio-install-inline-status .install-status-detail {
2884
+ color: rgba(239, 233, 214, 0.76);
2885
+ }
2886
+ .pinokio-install-inline-status .install-status-detail > *:first-child {
2887
+ margin-top: 0;
2888
+ }
2889
+ .pinokio-install-inline-status .install-status-detail > *:last-child {
2890
+ margin-bottom: 0;
2891
+ }
2892
+ .pinokio-install-inline-status .install-status-spinner {
2893
+ width: 18px;
2894
+ height: 18px;
2895
+ flex: 0 0 18px;
2896
+ margin-top: 1px;
2897
+ position: relative;
2898
+ display: inline-flex;
2899
+ align-items: center;
2900
+ justify-content: center;
2901
+ }
2902
+ .pinokio-install-inline-status .install-status-grid-anchor,
2903
+ .pinokio-install-inline-status .install-status-grid-tile,
2904
+ .pinokio-install-inline-status .install-status-grid-chaser,
2905
+ .pinokio-install-inline-status .install-status-grid-pixel {
2906
+ position: absolute;
2907
+ top: 0;
2908
+ left: 0;
2909
+ box-sizing: border-box;
2910
+ display: none;
2911
+ transform-origin: center;
2912
+ }
2913
+ .pinokio-install-inline-status .install-status-grid-anchor,
2914
+ .pinokio-install-inline-status .install-status-grid-tile,
2915
+ .pinokio-install-inline-status .install-status-grid-chaser {
2916
+ width: 7px;
2917
+ height: 7px;
2918
+ border-radius: 2px;
2919
+ }
2920
+ .pinokio-install-inline-status .install-status-grid-anchor {
2921
+ background: currentColor;
2922
+ opacity: 0.16;
2923
+ }
2924
+ .pinokio-install-inline-status .install-status-grid-tile,
2925
+ .pinokio-install-inline-status .install-status-grid-chaser,
2926
+ .pinokio-install-inline-status .install-status-grid-pixel {
2927
+ background: currentColor;
2928
+ }
2929
+ .pinokio-install-inline-status .install-status-grid-pixel {
2930
+ width: 4px;
2931
+ height: 4px;
2932
+ border-radius: 1px;
2933
+ }
2934
+ .pinokio-install-inline-status .install-status-grid-anchor-1,
2935
+ .pinokio-install-inline-status .install-status-grid-tile-1,
2936
+ .pinokio-install-inline-status .install-status-grid-chaser {
2937
+ top: 1px;
2938
+ left: 1px;
2939
+ }
2940
+ .pinokio-install-inline-status .install-status-grid-anchor-2,
2941
+ .pinokio-install-inline-status .install-status-grid-tile-2 {
2942
+ top: 1px;
2943
+ left: 12px;
2944
+ }
2945
+ .pinokio-install-inline-status .install-status-grid-anchor-3,
2946
+ .pinokio-install-inline-status .install-status-grid-tile-3 {
2947
+ top: 12px;
2948
+ left: 12px;
2949
+ }
2950
+ .pinokio-install-inline-status .install-status-grid-anchor-4,
2951
+ .pinokio-install-inline-status .install-status-grid-tile-4 {
2952
+ top: 12px;
2953
+ left: 1px;
2954
+ }
2955
+ .pinokio-install-inline-status .install-status-grid-pixel {
2956
+ top: 2px;
2957
+ left: 2px;
2958
+ }
2959
+ [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile {
2960
+ display: block;
2961
+ }
2962
+ [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-1 {
2963
+ animation: pinokio-grid-shift-1 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2964
+ }
2965
+ [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-2 {
2966
+ animation: pinokio-grid-shift-2 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2967
+ }
2968
+ [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2969
+ animation: pinokio-grid-shift-3 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2970
+ }
2971
+ [data-install-spinner-variant="grid-shift"] .pinokio-install-inline-status .install-status-grid-tile-4 {
2972
+ animation: pinokio-grid-shift-4 1.2s cubic-bezier(0.6, 0, 0.2, 1) infinite;
2973
+ }
2974
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-anchor {
2975
+ display: block;
2976
+ }
2977
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-1,
2978
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-2,
2979
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2980
+ display: block;
2981
+ }
2982
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-1 {
2983
+ animation: pinokio-single-vacancy-1 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2984
+ }
2985
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-2 {
2986
+ animation: pinokio-single-vacancy-2 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2987
+ }
2988
+ [data-install-spinner-variant="single-vacancy"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2989
+ animation: pinokio-single-vacancy-3 1.55s cubic-bezier(0.62, 0, 0.22, 1) infinite;
2990
+ }
2991
+ [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile {
2992
+ display: block;
2993
+ }
2994
+ [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-1,
2995
+ [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-3 {
2996
+ animation: pinokio-pulse-swap-a 1.18s ease-in-out infinite;
2997
+ }
2998
+ [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-2,
2999
+ [data-install-spinner-variant="pulse-swap"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3000
+ animation: pinokio-pulse-swap-b 1.18s ease-in-out infinite;
3001
+ }
3002
+ [data-install-spinner-variant="corner-chase"] .pinokio-install-inline-status .install-status-grid-anchor {
3003
+ display: block;
3004
+ }
3005
+ [data-install-spinner-variant="corner-chase"] .pinokio-install-inline-status .install-status-grid-chaser {
3006
+ display: block;
3007
+ animation: pinokio-corner-chase 1.05s cubic-bezier(0.6, 0, 0.2, 1) infinite;
3008
+ }
3009
+ [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile {
3010
+ display: block;
3011
+ }
3012
+ [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-1 {
3013
+ animation: pinokio-grid-flip-1 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3014
+ }
3015
+ [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3016
+ animation: pinokio-grid-flip-2 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3017
+ }
3018
+ [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3019
+ animation: pinokio-grid-flip-3 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3020
+ }
3021
+ [data-install-spinner-variant="flip-2x2"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3022
+ animation: pinokio-grid-flip-4 1.06s cubic-bezier(0.68, 0, 0.24, 1) infinite;
3023
+ }
3024
+ [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile {
3025
+ display: block;
3026
+ animation: pinokio-stack-ripple 1.15s ease-in-out infinite;
3027
+ }
3028
+ [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3029
+ animation-delay: -0.16s;
3030
+ }
3031
+ [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3032
+ animation-delay: -0.32s;
3033
+ }
3034
+ [data-install-spinner-variant="stack-ripple"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3035
+ animation-delay: -0.48s;
3036
+ }
3037
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor {
3038
+ display: block;
3039
+ width: 4px;
3040
+ height: 4px;
3041
+ border-radius: 1px;
3042
+ opacity: 0.22;
3043
+ }
3044
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-1 {
3045
+ top: 2px;
3046
+ left: 2px;
3047
+ }
3048
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-2 {
3049
+ top: 2px;
3050
+ left: 14px;
3051
+ }
3052
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-3 {
3053
+ top: 14px;
3054
+ left: 14px;
3055
+ }
3056
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-anchor-4 {
3057
+ top: 14px;
3058
+ left: 2px;
3059
+ }
3060
+ [data-install-spinner-variant="pixel-orbit"] .pinokio-install-inline-status .install-status-grid-pixel {
3061
+ display: block;
3062
+ animation: pinokio-pixel-orbit 1s cubic-bezier(0.6, 0, 0.2, 1) infinite;
3063
+ }
3064
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-anchor {
3065
+ display: block;
3066
+ }
3067
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile {
3068
+ display: block;
3069
+ }
3070
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-1 {
3071
+ animation: pinokio-binary-shuffle-1 1.1s steps(1, end) infinite;
3072
+ }
3073
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-2 {
3074
+ animation: pinokio-binary-shuffle-2 1.1s steps(1, end) infinite;
3075
+ }
3076
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-3 {
3077
+ animation: pinokio-binary-shuffle-3 1.1s steps(1, end) infinite;
3078
+ }
3079
+ [data-install-spinner-variant="binary-shuffle"] .pinokio-install-inline-status .install-status-grid-tile-4 {
3080
+ animation: pinokio-binary-shuffle-4 1.1s steps(1, end) infinite;
3081
+ }
3082
+ @keyframes pinokio-grid-shift-1 {
3083
+ 0%, 100% { transform: translate(0, 0); }
3084
+ 25% { transform: translate(11px, 0); }
3085
+ 50% { transform: translate(11px, 11px); }
3086
+ 75% { transform: translate(0, 11px); }
3087
+ }
3088
+ @keyframes pinokio-grid-shift-2 {
3089
+ 0%, 100% { transform: translate(0, 0); }
3090
+ 25% { transform: translate(0, 11px); }
3091
+ 50% { transform: translate(-11px, 11px); }
3092
+ 75% { transform: translate(-11px, 0); }
3093
+ }
3094
+ @keyframes pinokio-grid-shift-3 {
3095
+ 0%, 100% { transform: translate(0, 0); }
3096
+ 25% { transform: translate(-11px, 0); }
3097
+ 50% { transform: translate(-11px, -11px); }
3098
+ 75% { transform: translate(0, -11px); }
3099
+ }
3100
+ @keyframes pinokio-grid-shift-4 {
3101
+ 0%, 100% { transform: translate(0, 0); }
3102
+ 25% { transform: translate(0, -11px); }
3103
+ 50% { transform: translate(11px, -11px); }
3104
+ 75% { transform: translate(11px, 0); }
3105
+ }
3106
+ @keyframes pinokio-single-vacancy-1 {
3107
+ 0%, 50% { transform: translate(0, 0); }
3108
+ 65%, 100% { transform: translate(11px, 0); }
3109
+ }
3110
+ @keyframes pinokio-single-vacancy-2 {
3111
+ 0%, 15% { transform: translate(0, 0); }
3112
+ 30%, 100% { transform: translate(0, 11px); }
3113
+ }
3114
+ @keyframes pinokio-single-vacancy-3 {
3115
+ 0% { transform: translate(0, 0); }
3116
+ 15%, 70% { transform: translate(-11px, 0); }
3117
+ 85%, 100% { transform: translate(-11px, -11px); }
3118
+ }
3119
+ @keyframes pinokio-pulse-swap-a {
3120
+ 0%, 45%, 100% {
3121
+ opacity: 1;
3122
+ transform: scale(1);
3123
+ }
3124
+ 50%, 95% {
3125
+ opacity: 0.34;
3126
+ transform: scale(0.82);
3127
+ }
3128
+ }
3129
+ @keyframes pinokio-pulse-swap-b {
3130
+ 0%, 45%, 100% {
3131
+ opacity: 0.34;
3132
+ transform: scale(0.82);
3133
+ }
3134
+ 50%, 95% {
3135
+ opacity: 1;
3136
+ transform: scale(1);
3137
+ }
3138
+ }
3139
+ @keyframes pinokio-corner-chase {
3140
+ 0%, 100% { transform: translate(0, 0); }
3141
+ 25% { transform: translate(11px, 0); }
3142
+ 50% { transform: translate(11px, 11px); }
3143
+ 75% { transform: translate(0, 11px); }
3144
+ }
3145
+ @keyframes pinokio-grid-flip-1 {
3146
+ 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3147
+ 50% { transform: translate(11px, 0) scale(0.86); opacity: 0.72; }
3148
+ }
3149
+ @keyframes pinokio-grid-flip-2 {
3150
+ 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3151
+ 50% { transform: translate(-11px, 0) scale(0.86); opacity: 0.72; }
3152
+ }
3153
+ @keyframes pinokio-grid-flip-3 {
3154
+ 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3155
+ 50% { transform: translate(-11px, 0) scale(0.86); opacity: 0.72; }
3156
+ }
3157
+ @keyframes pinokio-grid-flip-4 {
3158
+ 0%, 100% { transform: translate(0, 0) scale(1); opacity: 1; }
3159
+ 50% { transform: translate(11px, 0) scale(0.86); opacity: 0.72; }
3160
+ }
3161
+ @keyframes pinokio-stack-ripple {
3162
+ 0%, 100% {
3163
+ opacity: 0.38;
3164
+ transform: scale(0.76);
3165
+ }
3166
+ 30% {
3167
+ opacity: 1;
3168
+ transform: scale(1);
3169
+ }
3170
+ 55% {
3171
+ opacity: 0.62;
3172
+ transform: scale(0.9);
3173
+ }
3174
+ }
3175
+ @keyframes pinokio-pixel-orbit {
3176
+ 0%, 100% { transform: translate(0, 0); }
3177
+ 25% { transform: translate(12px, 0); }
3178
+ 50% { transform: translate(12px, 12px); }
3179
+ 75% { transform: translate(0, 12px); }
3180
+ }
3181
+ @keyframes pinokio-binary-shuffle-1 {
3182
+ 0%, 24%, 75%, 100% { opacity: 1; transform: scale(1); }
3183
+ 25%, 74% { opacity: 0; transform: scale(0.82); }
3184
+ }
3185
+ @keyframes pinokio-binary-shuffle-2 {
3186
+ 0%, 24%, 75%, 100% { opacity: 0; transform: scale(0.82); }
3187
+ 25%, 74% { opacity: 1; transform: scale(1); }
3188
+ }
3189
+ @keyframes pinokio-binary-shuffle-3 {
3190
+ 0%, 49% { opacity: 1; transform: scale(1); }
3191
+ 50%, 100% { opacity: 0; transform: scale(0.82); }
3192
+ }
3193
+ @keyframes pinokio-binary-shuffle-4 {
3194
+ 0%, 49% { opacity: 0; transform: scale(0.82); }
3195
+ 50%, 100% { opacity: 1; transform: scale(1); }
3196
+ }
2860
3197
  .pinokio-install-inline-status {
2861
3198
  padding: 14px 18px;
2862
3199
  box-sizing: border-box;