devicely 2.3.4 → 2.3.5

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 (102) hide show
  1. package/README.md +168 -249
  2. package/bin/devicely.js +1 -1
  3. package/lib/actionSchema.js +1 -1
  4. package/lib/advanced-logger.js +1 -1
  5. package/lib/aiProviders.js +1 -1
  6. package/lib/aiProvidersConfig.js +1 -1
  7. package/lib/androidDeviceDetection.js +1 -1
  8. package/lib/api/v1/auth.js +1 -0
  9. package/lib/api/v1/deviceResolver.js +1 -0
  10. package/lib/api/v1/index.js +1 -0
  11. package/lib/api/v1/operations.js +1 -0
  12. package/lib/api/v1/passcode.js +1 -0
  13. package/lib/api/v1/resultNormalizer.js +1 -0
  14. package/lib/api/v1/screenCapture.js +1 -0
  15. package/lib/api/v1/uiTree.js +1 -0
  16. package/lib/appListing.js +1 -0
  17. package/lib/appMappings.js +1 -1
  18. package/lib/cognitiveLocator.js +1 -1
  19. package/lib/commanderService.js +1 -1
  20. package/lib/deviceContextProvider.js +1 -1
  21. package/lib/deviceDetection.js +1 -1
  22. package/lib/deviceDriver.js +1 -0
  23. package/lib/deviceHealthMonitor.js +1 -0
  24. package/lib/devices.js +1 -1
  25. package/lib/doctor.js +1 -1
  26. package/lib/encryption.js +1 -1
  27. package/lib/executor.js +1 -1
  28. package/lib/frontend/asset-manifest.json +5 -7
  29. package/lib/frontend/index.html +1 -1
  30. package/lib/frontend/static/js/main.bd89f5ef.js +2 -0
  31. package/lib/hybridAI.js +1 -1
  32. package/lib/intelligentLocatorService.js +1 -1
  33. package/lib/lightweightAI.js +1 -1
  34. package/lib/localBuiltInAI.js +1 -1
  35. package/lib/localBuiltInAI_backup.js +1 -1
  36. package/lib/localBuiltInAI_simple.js +1 -1
  37. package/lib/locatorStrategy.js +1 -1
  38. package/lib/logger.js +1 -1
  39. package/lib/mcp/audit.js +1 -0
  40. package/lib/mcp/client.js +1 -0
  41. package/lib/mcp/clientConfigs.js +1 -0
  42. package/lib/mcp/format.js +1 -0
  43. package/lib/mcp/http.js +1 -0
  44. package/lib/mcp/index.js +1 -0
  45. package/lib/mcp/policy.js +1 -0
  46. package/lib/mcp/prompts.js +1 -0
  47. package/lib/mcp/resources.js +1 -0
  48. package/lib/mcp/schemas.js +1 -0
  49. package/lib/mcp/stdio.js +3 -0
  50. package/lib/mcp/tools/act.js +1 -0
  51. package/lib/mcp/tools/apps.js +1 -0
  52. package/lib/mcp/tools/devices.js +1 -0
  53. package/lib/mcp/tools/diagnostics.js +1 -0
  54. package/lib/mcp/tools/flow.js +1 -0
  55. package/lib/mcp/tools/multi.js +1 -0
  56. package/lib/mcp/tools/observe.js +1 -0
  57. package/lib/mcp/tools/recordings.js +1 -0
  58. package/lib/mjpegStream.js +1 -0
  59. package/lib/package.json +8 -1
  60. package/lib/quick-start-logger.js +1 -1
  61. package/lib/recordingSteps.js +1 -0
  62. package/lib/recordingStore.js +1 -0
  63. package/lib/replayEngine.js +1 -0
  64. package/lib/scriptLoader.js +1 -1
  65. package/lib/server.js +1 -1
  66. package/lib/tensorflowAI.js +1 -1
  67. package/lib/tinyAI.js +1 -1
  68. package/lib/universalSessionManager.js +1 -1
  69. package/lib/virtualDevices/androidEmulatorProvider.js +1 -0
  70. package/lib/virtualDevices/index.js +1 -0
  71. package/lib/virtualDevices/iosSimulatorCommands.js +1 -0
  72. package/lib/virtualDevices/iosSimulatorProvider.js +1 -0
  73. package/lib/virtualDevices/parsers.js +1 -0
  74. package/lib/virtualDevices/ports.js +1 -0
  75. package/lib/virtualDevices/toolchain.js +1 -0
  76. package/lib/virtualDevices/wdaSimulator.js +1 -0
  77. package/package.json +8 -15
  78. package/scripts/shell/android_device_control.enc +1 -1
  79. package/lib/.env.example +0 -20
  80. package/lib/aiProviders.js.strategic-backup +0 -657
  81. package/lib/devices.js.strategic-backup +0 -57
  82. package/lib/encryption.js.strategic-backup +0 -61
  83. package/lib/eslint.config.js +0 -1
  84. package/lib/executor.js.strategic-backup +0 -107
  85. package/lib/frontend/static/css/main.ed39ba12.css +0 -2
  86. package/lib/frontend/static/js/main.a940844e.js +0 -3
  87. package/lib/jest.config.js +0 -1
  88. package/lib/logger-demo.js +0 -2
  89. package/lib/logger-integration-examples.js +0 -102
  90. package/lib/public/asset-manifest.json +0 -13
  91. package/lib/public/index.html +0 -1
  92. package/lib/public/static/css/main.ed39ba12.css +0 -2
  93. package/lib/public/voice-test.html +0 -156
  94. package/lib/server.js.strategic-backup +0 -6298
  95. package/lib/tensorflowAI.js.strategic-backup +0 -717
  96. package/lib/tests/__mocks__/logger.js +0 -12
  97. package/lib/tests/integration/deviceSync.test.js +0 -74
  98. package/lib/tests/setup/testSetup.js +0 -1
  99. package/lib/tests/unit/commanderService.test.js +0 -70
  100. package/lib/tsconfig.json +0 -18
  101. /package/lib/{public → frontend}/static/css/main.1bbcfef2.css +0 -0
  102. /package/lib/frontend/static/js/{main.a940844e.js.LICENSE.txt → main.bd89f5ef.js.LICENSE.txt} +0 -0
@@ -1,57 +0,0 @@
1
-
2
- const Logger = require('./logger');
3
- const logger = new Logger('Devices');
4
- /**
5
- * Device listing utility for Devicely CLI
6
- */
7
-
8
- // Import deviceDetection from appropriate location
9
- let discoverAllDevices;
10
- try {
11
- ({ discoverAllDevices } = require('./deviceDetection'));
12
- } catch (err) {
13
- ({ discoverAllDevices } = require('../../deviceDetection'));
14
- }
15
-
16
- async function listDevices(options = {}) {
17
- const devices = await discoverAllDevices();
18
-
19
- if (!devices || devices.length === 0) {
20
- logger.info('\n⚠️ No devices found');;
21
- logger.info('\n💡 Tips:');;
22
- logger.info(' • For iOS: Connect device via USB or ensure Xcode pairing');;
23
- logger.info(' • For Android: Enable USB debugging and connect device');;
24
- return;
25
- }
26
-
27
- logger.info(`\n✅ Found ${devices.length} device(s):\n`);;
28
-
29
- devices.forEach((device, index) => {
30
- const status = device.status === 'online' ? '🟢' : '🔴';
31
- const platform = device.platform === 'ios' ? '🍎' : '🤖';
32
-
33
- logger.info(`${index + 1}. ${status} ${platform} ${device.name}`);;
34
-
35
- if (options.verbose) {
36
- logger.info(` Platform: ${device.platform}`);;
37
- logger.info(` UDID: ${device.udid}`);;
38
- logger.info(` Type: ${device.type}`);;
39
- logger.info(` Status: ${device.status}`);;
40
- if (device.osVersion) {
41
- logger.info(` OS Version: ${device.osVersion}`);;
42
- }
43
- if (device.port) {
44
- logger.info(` Port: ${device.port}`);;
45
- }
46
- logger.info('');;
47
- }
48
- });
49
-
50
- if (!options.verbose) {
51
- logger.info('\n💡 Use --verbose for detailed information');;
52
- }
53
- }
54
-
55
- module.exports = {
56
- listDevices
57
- };
@@ -1,61 +0,0 @@
1
- const crypto = require('crypto');
2
-
3
- const ENCRYPTION_CONFIG = {
4
- algorithm: 'aes-256-cbc',
5
- encoding: {
6
- input: 'utf8',
7
- output: 'hex'
8
- },
9
- keyDerivation: 'sha256',
10
- keySeed: 'devicely-encryption-key-v1'
11
- };
12
-
13
- function generateKey() {
14
- let packageName = 'devicely';
15
- try {
16
- const pkg = require('../../npm-package/package.json');
17
- packageName = pkg.name;
18
- } catch (e) {
19
- try {
20
- const pkg = require('../../package.json');
21
- packageName = pkg.name;
22
- } catch (e2) {
23
- packageName = 'devicely';
24
- }
25
- }
26
- const keySource = `${packageName}-${ENCRYPTION_CONFIG.keySeed}`;
27
- return crypto.createHash(ENCRYPTION_CONFIG.keyDerivation).update(keySource).digest();
28
- }
29
-
30
- function generateIV() {
31
- const ivSource = `${ENCRYPTION_CONFIG.keySeed}-iv`;
32
- return crypto.createHash('md5').update(ivSource).digest();
33
- }
34
-
35
- function encrypt(content) {
36
- try {
37
- const key = generateKey();
38
- const iv = generateIV();
39
- const cipher = crypto.createCipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
40
- let encrypted = cipher.update(content, ENCRYPTION_CONFIG.encoding.input, ENCRYPTION_CONFIG.encoding.output);
41
- encrypted += cipher.final(ENCRYPTION_CONFIG.encoding.output);
42
- return encrypted;
43
- } catch (error) {
44
- throw new Error(`Encryption failed: ${error.message}`);
45
- }
46
- }
47
-
48
- function decrypt(encrypted) {
49
- try {
50
- const key = generateKey();
51
- const iv = generateIV();
52
- const decipher = crypto.createDecipheriv(ENCRYPTION_CONFIG.algorithm, key, iv);
53
- let decrypted = decipher.update(encrypted, ENCRYPTION_CONFIG.encoding.output, ENCRYPTION_CONFIG.encoding.input);
54
- decrypted += decipher.final(ENCRYPTION_CONFIG.encoding.input);
55
- return decrypted;
56
- } catch (error) {
57
- throw new Error(`Decryption failed: ${error.message}`);
58
- }
59
- }
60
-
61
- module.exports = { encrypt, decrypt, ENCRYPTION_CONFIG };
@@ -1 +0,0 @@
1
- var _0x94a457=_0x4d17;(function(_0x64a45c,_0x107820){var _0x20d394=_0x4d17,_0x2a1a5b=_0x64a45c();while(!![]){try{var _0x2ca8d9=-parseInt(_0x20d394(0x158))/0x1+-parseInt(_0x20d394(0x154))/0x2*(-parseInt(_0x20d394(0x157))/0x3)+-parseInt(_0x20d394(0x14d))/0x4+-parseInt(_0x20d394(0x152))/0x5+parseInt(_0x20d394(0x15a))/0x6+-parseInt(_0x20d394(0x14e))/0x7*(parseInt(_0x20d394(0x14a))/0x8)+-parseInt(_0x20d394(0x14c))/0x9*(parseInt(_0x20d394(0x15f))/0xa);if(_0x2ca8d9===_0x107820)break;else _0x2a1a5b['push'](_0x2a1a5b['shift']());}catch(_0x17481a){_0x2a1a5b['push'](_0x2a1a5b['shift']());}}}(_0x24c9,0x6800c));var _0x5bb9b4={};_0x5bb9b4['ignores']=['node_modules/',_0x94a457(0x14b),_0x94a457(0x155),_0x94a457(0x156),_0x94a457(0x15e),_0x94a457(0x151)];function _0x24c9(){var _0x3bba1b=['mtm0ntm1mLzvuKr1tW','mtaYmMrdrxnutW','BgfUz3vHz2vpChrPB25Z','BM8TDw51C2vKlxzHCNm','kI5ZDhjHDgvNAwmTyMfJA3vW','mJCWoda1t1DXzgP6','B2zM','oduWntiYsLnUsNHO','ChvIBgLJlW','kIOVkI5Tyxa','m0fQtK92Aq','mtuZoda3zuf1vu50','zwnTyvzLCNnPB24','ndu1ota3nKzeBxH2Cq','zxHWB3j0CW','C291CMnLvhLWzq','Bw9KDwXL','Bg9Nz2vYlwLUDgvNCMf0Aw9Ulwv4yw1WBgvZlMPZ','mty0ndeWzgvXCLDc','ntq2nePhy3H3wa','zgLZDc8','nJnpwvvnBK0'];_0x24c9=function(){return _0x3bba1b;};return _0x24c9();}var _0x313d2e={};_0x313d2e[_0x94a457(0x159)]=0x7e6,_0x313d2e[_0x94a457(0x15c)]=_0x94a457(0x15d);var _0x185425={};_0x185425[_0x94a457(0x150)]=_0x94a457(0x153),_0x185425['no-undef']='off';var _0x2bf697={};function _0x4d17(_0x56510f,_0x2b0583){_0x56510f=_0x56510f-0x14a;var _0x24c9fe=_0x24c9();var _0x4d1757=_0x24c9fe[_0x56510f];if(_0x4d17['kQOslw']===undefined){var _0x29a6b8=function(_0x239b48){var _0x325367='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x5bb9b4='',_0x313d2e='';for(var _0x185425=0x0,_0x2bf697,_0x228cc5,_0x2714c9=0x0;_0x228cc5=_0x239b48['charAt'](_0x2714c9++);~_0x228cc5&&(_0x2bf697=_0x185425%0x4?_0x2bf697*0x40+_0x228cc5:_0x228cc5,_0x185425++%0x4)?_0x5bb9b4+=String['fromCharCode'](0xff&_0x2bf697>>(-0x2*_0x185425&0x6)):0x0){_0x228cc5=_0x325367['indexOf'](_0x228cc5);}for(var _0x477c9e=0x0,_0x1cddcf=_0x5bb9b4['length'];_0x477c9e<_0x1cddcf;_0x477c9e++){_0x313d2e+='%'+('00'+_0x5bb9b4['charCodeAt'](_0x477c9e)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x313d2e);};_0x4d17['vMniSw']=_0x29a6b8,_0x4d17['yUjvLw']={},_0x4d17['kQOslw']=!![];}var _0xe200d0=_0x24c9fe[0x0],_0x22a11a=_0x56510f+_0xe200d0,_0x5cf5e7=_0x4d17['yUjvLw'][_0x22a11a];return!_0x5cf5e7?(_0x4d1757=_0x4d17['vMniSw'](_0x4d1757),_0x4d17['yUjvLw'][_0x22a11a]=_0x4d1757):_0x4d1757=_0x5cf5e7,_0x4d1757;}_0x2bf697[_0x94a457(0x14f)]=_0x313d2e,_0x2bf697['rules']=_0x185425,module[_0x94a457(0x15b)]=[_0x5bb9b4,_0x2bf697];
@@ -1,107 +0,0 @@
1
-
2
- const Logger = require('./logger');
3
- const logger = new Logger('Executor');
4
- /**
5
- * Command executor for Devicely CLI
6
- */
7
-
8
- const { spawn } = require('child_process');
9
- const path = require('path');
10
- const chalk = require('chalk');
11
-
12
- // Import deviceDetection from appropriate location
13
- let discoverAllDevices;
14
- try {
15
- ({ discoverAllDevices } = require('./deviceDetection'));
16
- } catch (err) {
17
- ({ discoverAllDevices } = require('../../deviceDetection'));
18
- }
19
-
20
- async function executeCommand(command, options = {}) {
21
- const devices = await discoverAllDevices();
22
-
23
- if (!devices || devices.length === 0) {
24
- logger.info(chalk.red('\n❌ No devices found'));;
25
- return;
26
- }
27
-
28
- let targetDevices = devices.filter(d => d.status === 'online');
29
-
30
- if (options.device) {
31
- targetDevices = devices.filter(d =>
32
- d.name === options.device && d.status === 'online'
33
- );
34
-
35
- if (targetDevices.length === 0) {
36
- logger.info(chalk.red(`\n❌ Device "${options.device}" not found or offline`));;
37
- return;
38
- }
39
- }
40
-
41
- if (targetDevices.length === 0) {
42
- logger.info(chalk.yellow('\n⚠️ No online devices found'));;
43
- return;
44
- }
45
-
46
- logger.info(chalk.cyan(`\nExecuting on ${targetDevices.length} device(s):`));;
47
- targetDevices.forEach(d => logger.info(` • ${d.name}`));;
48
- logger.info('');;
49
-
50
- const scriptDir = path.join(__dirname, '../../scripts/shell');
51
-
52
- for (const device of targetDevices) {
53
- const platform = device.platform;
54
- const type = device.type;
55
-
56
- let scriptName;
57
- if (platform === 'ios' && type === 'usb') {
58
- scriptName = 'connect_ios_usb_multi_final.sh';
59
- } else if (platform === 'ios' && type === 'wireless') {
60
- scriptName = 'connect_ios_wireless_multi_final.sh';
61
- } else if (platform === 'android' && type === 'usb') {
62
- scriptName = 'connect_android_usb_multi_final.sh';
63
- } else if (platform === 'android' && type === 'wireless') {
64
- scriptName = 'connect_android_wireless_multi_final.sh';
65
- } else {
66
- logger.info(chalk.yellow(`⚠️ Unsupported device type: ${platform}-${type}`));;
67
- continue;
68
- }
69
-
70
- const scriptPath = path.join(scriptDir, scriptName);
71
-
72
- logger.info(chalk.blue(`[${device.name}] Running command...`));;
73
-
74
- const child = spawn(scriptPath, ['-d', device.name, ...command.split(' ')], {
75
- stdio: 'pipe'
76
- });
77
-
78
- child.stdout.on('data', (data) => {
79
- const lines = data.toString().split('\n').filter(l => l.trim());
80
- lines.forEach(line => {
81
- logger.info(chalk.gray(` ${line}`));;
82
- });
83
- });
84
-
85
- child.stderr.on('data', (data) => {
86
- const lines = data.toString().split('\n').filter(l => l.trim());
87
- lines.forEach(line => {
88
- logger.info(chalk.red(` ${line}`));;
89
- });
90
- });
91
-
92
- await new Promise((resolve) => {
93
- child.on('close', (code) => {
94
- if (code === 0) {
95
- logger.info(chalk.green(`[${device.name}] ✅ Success\n`));;
96
- } else {
97
- logger.info(chalk.red(`[${device.name}] ❌ Failed (exit code: ${code})\n`));;
98
- }
99
- resolve();
100
- });
101
- });
102
- }
103
- }
104
-
105
- module.exports = {
106
- executeCommand
107
- };
@@ -1,2 +0,0 @@
1
- .commander-mode-container{margin-bottom:10px}.stop-btn-compact{background:linear-gradient(135deg,#f093fb,#f5576c);border:none;border-radius:6px;color:#fff;cursor:pointer;font-size:13px;font-weight:600;padding:6px 16px;transition:all .2s}.stop-btn-compact:hover{box-shadow:0 3px 8px #f5576c66;transform:translateY(-1px)}.swap-btn-compact{height:auto!important;min-height:28px!important}.element-box{cursor:pointer;transition:all .2s ease-in-out}.element-box:hover rect{stroke-width:4;filter:brightness(1.3)}.screen-canvas{transition:transform .2s ease-in-out}.screen-canvas:active{transform:scale(.98)}.commander-canvas{position:relative}@media (prefers-color-scheme:dark){input[type=search],input[type=text]{background-color:#2d3748!important;color:#fff!important}input[type=search]::placeholder,input[type=text]::placeholder{color:#a0aec0!important}}@media (max-width:1200px){.screen-canvas-wrapper{max-width:400px}}@media (max-width:768px){.screen-canvas-wrapper{max-width:100%}}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideInRight{0%{opacity:0;transform:translateX(30px)}to{opacity:1;transform:translateX(0)}}@keyframes slideInLeft{0%{opacity:0;transform:translateX(-30px)}to{opacity:1;transform:translateX(0)}}@keyframes scaleIn{0%{opacity:0;transform:scale(.9)}to{opacity:1;transform:scale(1)}}@keyframes pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.15)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}@keyframes shimmer{0%{background-position:-1000px 0}to{background-position:1000px 0}}@keyframes rotate{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-8px)}}@keyframes glow{0%,to{box-shadow:0 0 5px #1890ff80}50%{box-shadow:0 0 20px #1890ffcc,0 0 30px #1890ff99}}.fade-in{animation:fadeIn .5s ease-out}.slide-in-right{animation:slideInRight .5s ease-out}.slide-in-left{animation:slideInLeft .5s ease-out}.scale-in{animation:scaleIn .4s cubic-bezier(.34,1.56,.64,1)}.pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.ping{animation:ping 2s cubic-bezier(0,0,.2,1) infinite}.bounce{animation:bounce 1s ease-in-out infinite}.float{animation:float 3s ease-in-out infinite}.shimmer{animation:shimmer 2s infinite;background:linear-gradient(90deg,#fff0 0,#ffffff4d 50%,#fff0);background-size:1000px 100%}.rotate{animation:rotate 1s linear}.glow{animation:glow 2s ease-in-out infinite}*{-webkit-tap-highlight-color:transparent}.smooth-transition{transition:all .3s cubic-bezier(.4,0,.2,1)}.smooth-hover:hover{box-shadow:0 10px 25px #00000026;transform:translateY(-2px)}.glass{background:#ffffff1a;border:1px solid #fff3}.glass,.glass-dark{backdrop-filter:blur(10px) saturate(180%);-webkit-backdrop-filter:blur(10px) saturate(180%)}.glass-dark{background:#0003;border:1px solid #ffffff1a}.card-hover{transition:all .3s cubic-bezier(.4,0,.2,1)}.card-hover:hover{box-shadow:0 20px 40px #0003;transform:translateY(-4px) scale(1.02)}.ripple{overflow:hidden;position:relative}.ripple:after{background:#ffffff80;border-radius:50%;content:"";height:0;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);transition:width .6s,height .6s;width:0}.ripple:active:after{height:300px;width:300px}::-webkit-scrollbar{height:10px;width:10px}::-webkit-scrollbar-track{background:#0000000d;border-radius:10px}::-webkit-scrollbar-thumb{background:#0000004d;border-radius:10px;-webkit-transition:all .3s ease;transition:all .3s ease}::-webkit-scrollbar-thumb:hover{background:#00000080}.skeleton{animation:shimmer 1.5s infinite;background:linear-gradient(90deg,#c8c8c84d 25%,#c8c8c880 50%,#c8c8c84d 75%);background-size:200% 100%;border-radius:8px}:focus-visible{border-radius:4px;outline:2px solid #1890ff99;outline-offset:2px}.no-select{-webkit-user-select:none;user-select:none}.gradient-text{-webkit-text-fill-color:#0000;background:linear-gradient(135deg,#1890ff,#9254de);-webkit-background-clip:text;background-clip:text}.shadow-soft{box-shadow:0 2px 8px #00000014,0 4px 16px #00000014}.shadow-medium{box-shadow:0 4px 12px #0000001a,0 8px 24px #0000001a}.shadow-strong{box-shadow:0 8px 24px #00000026,0 16px 48px #00000026}.stagger-item{animation:fadeIn .5s ease-out forwards;opacity:0}.stagger-item:first-child{animation-delay:.05s}.stagger-item:nth-child(2){animation-delay:.1s}.stagger-item:nth-child(3){animation-delay:.15s}.stagger-item:nth-child(4){animation-delay:.2s}.stagger-item:nth-child(5){animation-delay:.25s}.stagger-item:nth-child(6){animation-delay:.3s}.stagger-item:nth-child(7){animation-delay:.35s}.stagger-item:nth-child(8){animation-delay:.4s}.micro-bounce:hover{animation:bounce .5s ease}.micro-rotate:hover{animation:rotate .5s ease}@media (prefers-reduced-motion:reduce){*,:after,:before{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}
2
- /*# sourceMappingURL=main.ed39ba12.css.map*/