jbilcke-hf HF staff commited on
Commit
fddab62
1 Parent(s): 09a7c47

some more craziness

Browse files
package-lock.json CHANGED
@@ -11,7 +11,7 @@
11
  "@huggingface/hub": "0.12.3-oauth",
12
  "@huggingface/inference": "^2.6.7",
13
  "@jcoreio/async-throttle": "^1.6.0",
14
- "@mediapipe/tasks-vision": "^0.10.12",
15
  "@photo-sphere-viewer/core": "^5.7.2",
16
  "@photo-sphere-viewer/equirectangular-video-adapter": "^5.7.2",
17
  "@photo-sphere-viewer/gyroscope-plugin": "^5.7.2",
@@ -1492,14 +1492,14 @@
1492
  }
1493
  },
1494
  "node_modules/@mediapipe/tasks-vision": {
1495
- "version": "0.10.12",
1496
- "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.12.tgz",
1497
- "integrity": "sha512-688Vukid7hvGmx+7hzS/EQ3Q4diz4eeX4/FYDw8f/t56UjFueD8LTvA2rX5BCIwvT0oy8QHKh5uKIyct1AOFtQ=="
1498
  },
1499
  "node_modules/@next/env": {
1500
- "version": "14.1.4",
1501
- "resolved": "https://registry.npmjs.org/@next/env/-/env-14.1.4.tgz",
1502
- "integrity": "sha512-e7X7bbn3Z6DWnDi75UWn+REgAbLEqxI8Tq2pkFOFAMpWAWApz/YCUhtWMWn410h8Q2fYiYL7Yg5OlxMOCfFjJQ=="
1503
  },
1504
  "node_modules/@next/eslint-plugin-next": {
1505
  "version": "13.4.10",
@@ -1510,9 +1510,9 @@
1510
  }
1511
  },
1512
  "node_modules/@next/swc-darwin-arm64": {
1513
- "version": "14.1.4",
1514
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.4.tgz",
1515
- "integrity": "sha512-ubmUkbmW65nIAOmoxT1IROZdmmJMmdYvXIe8211send9ZYJu+SqxSnJM4TrPj9wmL6g9Atvj0S/2cFmMSS99jg==",
1516
  "cpu": [
1517
  "arm64"
1518
  ],
@@ -1525,9 +1525,9 @@
1525
  }
1526
  },
1527
  "node_modules/@next/swc-darwin-x64": {
1528
- "version": "14.1.4",
1529
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.4.tgz",
1530
- "integrity": "sha512-b0Xo1ELj3u7IkZWAKcJPJEhBop117U78l70nfoQGo4xUSvv0PJSTaV4U9xQBLvZlnjsYkc8RwQN1HoH/oQmLlQ==",
1531
  "cpu": [
1532
  "x64"
1533
  ],
@@ -1540,9 +1540,9 @@
1540
  }
1541
  },
1542
  "node_modules/@next/swc-linux-arm64-gnu": {
1543
- "version": "14.1.4",
1544
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.4.tgz",
1545
- "integrity": "sha512-457G0hcLrdYA/u1O2XkRMsDKId5VKe3uKPvrKVOyuARa6nXrdhJOOYU9hkKKyQTMru1B8qEP78IAhf/1XnVqKA==",
1546
  "cpu": [
1547
  "arm64"
1548
  ],
@@ -1555,9 +1555,9 @@
1555
  }
1556
  },
1557
  "node_modules/@next/swc-linux-arm64-musl": {
1558
- "version": "14.1.4",
1559
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.4.tgz",
1560
- "integrity": "sha512-l/kMG+z6MB+fKA9KdtyprkTQ1ihlJcBh66cf0HvqGP+rXBbOXX0dpJatjZbHeunvEHoBBS69GYQG5ry78JMy3g==",
1561
  "cpu": [
1562
  "arm64"
1563
  ],
@@ -1570,9 +1570,9 @@
1570
  }
1571
  },
1572
  "node_modules/@next/swc-linux-x64-gnu": {
1573
- "version": "14.1.4",
1574
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.4.tgz",
1575
- "integrity": "sha512-BapIFZ3ZRnvQ1uWbmqEGJuPT9cgLwvKtxhK/L2t4QYO7l+/DxXuIGjvp1x8rvfa/x1FFSsipERZK70pewbtJtw==",
1576
  "cpu": [
1577
  "x64"
1578
  ],
@@ -1585,9 +1585,9 @@
1585
  }
1586
  },
1587
  "node_modules/@next/swc-linux-x64-musl": {
1588
- "version": "14.1.4",
1589
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.4.tgz",
1590
- "integrity": "sha512-mqVxTwk4XuBl49qn2A5UmzFImoL1iLm0KQQwtdRJRKl21ylQwwGCxJtIYo2rbfkZHoSKlh/YgztY0qH3wG1xIg==",
1591
  "cpu": [
1592
  "x64"
1593
  ],
@@ -1600,9 +1600,9 @@
1600
  }
1601
  },
1602
  "node_modules/@next/swc-win32-arm64-msvc": {
1603
- "version": "14.1.4",
1604
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.4.tgz",
1605
- "integrity": "sha512-xzxF4ErcumXjO2Pvg/wVGrtr9QQJLk3IyQX1ddAC/fi6/5jZCZ9xpuL9Tzc4KPWMFq8GGWFVDMshZOdHGdkvag==",
1606
  "cpu": [
1607
  "arm64"
1608
  ],
@@ -1615,9 +1615,9 @@
1615
  }
1616
  },
1617
  "node_modules/@next/swc-win32-ia32-msvc": {
1618
- "version": "14.1.4",
1619
- "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.4.tgz",
1620
- "integrity": "sha512-WZiz8OdbkpRw6/IU/lredZWKKZopUMhcI2F+XiMAcPja0uZYdMTZQRoQ0WZcvinn9xZAidimE7tN9W5v9Yyfyw==",
1621
  "cpu": [
1622
  "ia32"
1623
  ],
@@ -1630,9 +1630,9 @@
1630
  }
1631
  },
1632
  "node_modules/@next/swc-win32-x64-msvc": {
1633
- "version": "14.1.4",
1634
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.4.tgz",
1635
- "integrity": "sha512-4Rto21sPfw555sZ/XNLqfxDUNeLhNYGO2dlPqsnuCg8N8a2a9u1ltqBOPQ4vj1Gf7eJC0W2hHG2eYUHuiXgY2w==",
1636
  "cpu": [
1637
  "x64"
1638
  ],
@@ -2859,15 +2859,21 @@
2859
  }
2860
  },
2861
  "node_modules/@rushstack/eslint-patch": {
2862
- "version": "1.10.1",
2863
- "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.1.tgz",
2864
- "integrity": "sha512-S3Kq8e7LqxkA9s7HKLqXGTGck1uwis5vAXan3FnU5yw1Ec5hsSGnq4s/UCaSqABPOnOTg7zASLyst7+ohgWexg=="
 
 
 
 
 
2865
  },
2866
  "node_modules/@swc/helpers": {
2867
- "version": "0.5.2",
2868
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
2869
- "integrity": "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==",
2870
  "dependencies": {
 
2871
  "tslib": "^2.4.0"
2872
  }
2873
  },
@@ -2956,9 +2962,9 @@
2956
  }
2957
  },
2958
  "node_modules/@types/qs": {
2959
- "version": "6.9.14",
2960
- "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz",
2961
- "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==",
2962
  "dev": true
2963
  },
2964
  "node_modules/@types/react": {
@@ -2989,9 +2995,9 @@
2989
  }
2990
  },
2991
  "node_modules/@types/react-virtualized": {
2992
- "version": "9.21.29",
2993
- "resolved": "https://registry.npmjs.org/@types/react-virtualized/-/react-virtualized-9.21.29.tgz",
2994
- "integrity": "sha512-+ODVQ+AyKngenj4OPpg43Hz4B9Rdjuz1Naxu9ypNc3Cjo0WVZTYhqXfF/Nm38i8PV/YXECRIl4mTAZK5hq2B+g==",
2995
  "dev": true,
2996
  "dependencies": {
2997
  "@types/prop-types": "*",
@@ -3130,9 +3136,9 @@
3130
  }
3131
  },
3132
  "node_modules/@upstash/redis": {
3133
- "version": "1.29.0",
3134
- "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.29.0.tgz",
3135
- "integrity": "sha512-kbO5fgMAeUzErnA/SOtaSbAa0dguYhhBT4MZHJ1O8gVl4iK754aC9+rIYY5hsp4nlxeCGfnIDkWpof991c9jjA==",
3136
  "dependencies": {
3137
  "crypto-js": "^4.2.0"
3138
  }
@@ -3692,9 +3698,9 @@
3692
  }
3693
  },
3694
  "node_modules/caniuse-lite": {
3695
- "version": "1.0.30001606",
3696
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001606.tgz",
3697
- "integrity": "sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg==",
3698
  "funding": [
3699
  {
3700
  "type": "opencollective",
@@ -3890,9 +3896,9 @@
3890
  }
3891
  },
3892
  "node_modules/cookies-next/node_modules/@types/node": {
3893
- "version": "16.18.94",
3894
- "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.94.tgz",
3895
- "integrity": "sha512-X8q3DoKq8t/QhA0Rk/9wJUajxtXRDiCK+cVaONKLxpsjPhu+xX6uZuEj4UKGLQ4p0obTdFxa0cP/BMvf9mOYZA=="
3896
  },
3897
  "node_modules/copy-to-clipboard": {
3898
  "version": "3.3.3",
@@ -4266,9 +4272,9 @@
4266
  "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
4267
  },
4268
  "node_modules/electron-to-chromium": {
4269
- "version": "1.4.728",
4270
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.728.tgz",
4271
- "integrity": "sha512-Ud1v7hJJYIqehlUJGqR6PF1Ek8l80zWwxA6nGxigBsGJ9f9M2fciHyrIiNMerSHSH3p+0/Ia7jIlnDkt41h5cw=="
4272
  },
4273
  "node_modules/elliptic": {
4274
  "version": "6.5.4",
@@ -5401,9 +5407,9 @@
5401
  "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
5402
  },
5403
  "node_modules/gsplat": {
5404
- "version": "1.2.3",
5405
- "resolved": "https://registry.npmjs.org/gsplat/-/gsplat-1.2.3.tgz",
5406
- "integrity": "sha512-5ZthImDFbCKpREgz7SBJUnYRd5GvA5V+0aeaBO4B0M5A/Y5fQwcoeYXioJMcmwfTVRGvHi8W1e2g7RqU1XpbxA=="
5407
  },
5408
  "node_modules/has-bigints": {
5409
  "version": "1.0.2",
@@ -6319,12 +6325,12 @@
6319
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
6320
  },
6321
  "node_modules/next": {
6322
- "version": "14.1.4",
6323
- "resolved": "https://registry.npmjs.org/next/-/next-14.1.4.tgz",
6324
- "integrity": "sha512-1WTaXeSrUwlz/XcnhGTY7+8eiaFvdet5z9u3V2jb+Ek1vFo0VhHKSAIJvDWfQpttWjnyw14kBeq28TPq7bTeEQ==",
6325
  "dependencies": {
6326
- "@next/env": "14.1.4",
6327
- "@swc/helpers": "0.5.2",
6328
  "busboy": "1.6.0",
6329
  "caniuse-lite": "^1.0.30001579",
6330
  "graceful-fs": "^4.2.11",
@@ -6338,18 +6344,19 @@
6338
  "node": ">=18.17.0"
6339
  },
6340
  "optionalDependencies": {
6341
- "@next/swc-darwin-arm64": "14.1.4",
6342
- "@next/swc-darwin-x64": "14.1.4",
6343
- "@next/swc-linux-arm64-gnu": "14.1.4",
6344
- "@next/swc-linux-arm64-musl": "14.1.4",
6345
- "@next/swc-linux-x64-gnu": "14.1.4",
6346
- "@next/swc-linux-x64-musl": "14.1.4",
6347
- "@next/swc-win32-arm64-msvc": "14.1.4",
6348
- "@next/swc-win32-ia32-msvc": "14.1.4",
6349
- "@next/swc-win32-x64-msvc": "14.1.4"
6350
  },
6351
  "peerDependencies": {
6352
  "@opentelemetry/api": "^1.1.0",
 
6353
  "react": "^18.2.0",
6354
  "react-dom": "^18.2.0",
6355
  "sass": "^1.3.0"
@@ -6358,6 +6365,9 @@
6358
  "@opentelemetry/api": {
6359
  "optional": true
6360
  },
 
 
 
6361
  "sass": {
6362
  "optional": true
6363
  }
@@ -6596,9 +6606,9 @@
6596
  }
6597
  },
6598
  "node_modules/openai": {
6599
- "version": "4.36.0",
6600
- "resolved": "https://registry.npmjs.org/openai/-/openai-4.36.0.tgz",
6601
- "integrity": "sha512-AtYrhhWY64LhB9P6f3H0nV8nTSaQJ89mWPnfNU5CnYg81zlYaV8nkyO+aTNfprdqP/9xv10woNNUgefXINT4Dg==",
6602
  "dependencies": {
6603
  "@types/node": "^18.11.18",
6604
  "@types/node-fetch": "^2.6.4",
@@ -6971,9 +6981,9 @@
6971
  }
6972
  },
6973
  "node_modules/qs": {
6974
- "version": "6.12.0",
6975
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
6976
- "integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
6977
  "dependencies": {
6978
  "side-channel": "^1.0.6"
6979
  },
@@ -7981,11 +7991,11 @@
7981
  }
7982
  },
7983
  "node_modules/tailwind-merge": {
7984
- "version": "2.2.2",
7985
- "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.2.2.tgz",
7986
- "integrity": "sha512-tWANXsnmJzgw6mQ07nE3aCDkCK4QdT3ThPMCzawoYA2Pws7vSTCvz3Vrjg61jVUGfFZPJzxEP+NimbcW+EdaDw==",
7987
  "dependencies": {
7988
- "@babel/runtime": "^7.24.0"
7989
  },
7990
  "funding": {
7991
  "type": "github",
 
11
  "@huggingface/hub": "0.12.3-oauth",
12
  "@huggingface/inference": "^2.6.7",
13
  "@jcoreio/async-throttle": "^1.6.0",
14
+ "@mediapipe/tasks-vision": "^0.10.13-rc.20240419",
15
  "@photo-sphere-viewer/core": "^5.7.2",
16
  "@photo-sphere-viewer/equirectangular-video-adapter": "^5.7.2",
17
  "@photo-sphere-viewer/gyroscope-plugin": "^5.7.2",
 
1492
  }
1493
  },
1494
  "node_modules/@mediapipe/tasks-vision": {
1495
+ "version": "0.10.13-rc.20240419",
1496
+ "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.13-rc.20240419.tgz",
1497
+ "integrity": "sha512-IfIFVSkektnlo9FjqhDYe5LzbOJTdx9kjs65lXmerqPQSOA3akYwp5zt2Rtm1G4JrG1Isv1A15yfiSlqm5pGdQ=="
1498
  },
1499
  "node_modules/@next/env": {
1500
+ "version": "14.2.2",
1501
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.2.tgz",
1502
+ "integrity": "sha512-sk72qRfM1Q90XZWYRoJKu/UWlTgihrASiYw/scb15u+tyzcze3bOuJ/UV6TBOQEeUaxOkRqGeuGUdiiuxc5oqw=="
1503
  },
1504
  "node_modules/@next/eslint-plugin-next": {
1505
  "version": "13.4.10",
 
1510
  }
1511
  },
1512
  "node_modules/@next/swc-darwin-arm64": {
1513
+ "version": "14.2.2",
1514
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.2.tgz",
1515
+ "integrity": "sha512-3iPgMhzbalizGwHNFUcGnDhFPSgVBHQ8aqSTAMxB5BvJG0oYrDf1WOJZlbXBgunOEj/8KMVbejEur/FpvFsgFQ==",
1516
  "cpu": [
1517
  "arm64"
1518
  ],
 
1525
  }
1526
  },
1527
  "node_modules/@next/swc-darwin-x64": {
1528
+ "version": "14.2.2",
1529
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.2.tgz",
1530
+ "integrity": "sha512-x7Afi/jt0ZBRUZHTi49yyej4o8znfIMHO4RvThuoc0P+uli8Jd99y5GKjxoYunPKsXL09xBXEM1+OQy2xEL0Ag==",
1531
  "cpu": [
1532
  "x64"
1533
  ],
 
1540
  }
1541
  },
1542
  "node_modules/@next/swc-linux-arm64-gnu": {
1543
+ "version": "14.2.2",
1544
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.2.tgz",
1545
+ "integrity": "sha512-zbfPtkk7L41ODMJwSp5VbmPozPmMMQrzAc0HAUomVeVIIwlDGs/UCqLJvLNDt4jpWgc21SjjyIn762lNGrMaUA==",
1546
  "cpu": [
1547
  "arm64"
1548
  ],
 
1555
  }
1556
  },
1557
  "node_modules/@next/swc-linux-arm64-musl": {
1558
+ "version": "14.2.2",
1559
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.2.tgz",
1560
+ "integrity": "sha512-wPbS3pI/JU16rm3XdLvvTmlsmm1nd+sBa2ohXgBZcShX4TgOjD4R+RqHKlI1cjo/jDZKXt6OxmcU0Iys0OC/yg==",
1561
  "cpu": [
1562
  "arm64"
1563
  ],
 
1570
  }
1571
  },
1572
  "node_modules/@next/swc-linux-x64-gnu": {
1573
+ "version": "14.2.2",
1574
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.2.tgz",
1575
+ "integrity": "sha512-NqWOHqqq8iC9tuHvZxjQ2tX+jWy2X9y8NX2mcB4sj2bIccuCxbIZrU/ThFPZZPauygajZuVQ6zediejQHwZHwQ==",
1576
  "cpu": [
1577
  "x64"
1578
  ],
 
1585
  }
1586
  },
1587
  "node_modules/@next/swc-linux-x64-musl": {
1588
+ "version": "14.2.2",
1589
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.2.tgz",
1590
+ "integrity": "sha512-lGepHhwb9sGhCcU7999+iK1ZZT+6rrIoVg40MP7DZski9GIZP80wORSbt5kJzh9v2x2ev2lxC6VgwMQT0PcgTA==",
1591
  "cpu": [
1592
  "x64"
1593
  ],
 
1600
  }
1601
  },
1602
  "node_modules/@next/swc-win32-arm64-msvc": {
1603
+ "version": "14.2.2",
1604
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.2.tgz",
1605
+ "integrity": "sha512-TZSh/48SfcLEQ4rD25VVn2kdIgUWmMflRX3OiyPwGNXn3NiyPqhqei/BaqCYXViIQ+6QsG9R0C8LftMqy8JPMA==",
1606
  "cpu": [
1607
  "arm64"
1608
  ],
 
1615
  }
1616
  },
1617
  "node_modules/@next/swc-win32-ia32-msvc": {
1618
+ "version": "14.2.2",
1619
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.2.tgz",
1620
+ "integrity": "sha512-M0tBVNMEBJN2ZNQWlcekMn6pvLria7Sa2Fai5znm7CCJz4pP3lrvlSxhKdkCerk0D9E0bqx5yAo3o2Q7RrD4gA==",
1621
  "cpu": [
1622
  "ia32"
1623
  ],
 
1630
  }
1631
  },
1632
  "node_modules/@next/swc-win32-x64-msvc": {
1633
+ "version": "14.2.2",
1634
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.2.tgz",
1635
+ "integrity": "sha512-a/20E/wtTJZ3Ykv3f/8F0l7TtgQa2LWHU2oNB9bsu0VjqGuGGHmm/q6waoUNQYTVPYrrlxxaHjJcDV6aiSTt/w==",
1636
  "cpu": [
1637
  "x64"
1638
  ],
 
2859
  }
2860
  },
2861
  "node_modules/@rushstack/eslint-patch": {
2862
+ "version": "1.10.2",
2863
+ "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.2.tgz",
2864
+ "integrity": "sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw=="
2865
+ },
2866
+ "node_modules/@swc/counter": {
2867
+ "version": "0.1.3",
2868
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
2869
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
2870
  },
2871
  "node_modules/@swc/helpers": {
2872
+ "version": "0.5.5",
2873
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz",
2874
+ "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==",
2875
  "dependencies": {
2876
+ "@swc/counter": "^0.1.3",
2877
  "tslib": "^2.4.0"
2878
  }
2879
  },
 
2962
  }
2963
  },
2964
  "node_modules/@types/qs": {
2965
+ "version": "6.9.15",
2966
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz",
2967
+ "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==",
2968
  "dev": true
2969
  },
2970
  "node_modules/@types/react": {
 
2995
  }
2996
  },
2997
  "node_modules/@types/react-virtualized": {
2998
+ "version": "9.21.30",
2999
+ "resolved": "https://registry.npmjs.org/@types/react-virtualized/-/react-virtualized-9.21.30.tgz",
3000
+ "integrity": "sha512-4l2TFLQ8BCjNDQlvH85tU6gctuZoEdgYzENQyZHpgTHU7hoLzYgPSOALMAeA58LOWua8AzC6wBivPj1lfl6JgQ==",
3001
  "dev": true,
3002
  "dependencies": {
3003
  "@types/prop-types": "*",
 
3136
  }
3137
  },
3138
  "node_modules/@upstash/redis": {
3139
+ "version": "1.30.0",
3140
+ "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.30.0.tgz",
3141
+ "integrity": "sha512-bkxl2n7qls27hONXNyItM6ccRT0NBJ8c6zl83wx+TlODpYXehgeiUJTkcTaXLp7hk+zy6Mqpzpeo3GX+wZSvBw==",
3142
  "dependencies": {
3143
  "crypto-js": "^4.2.0"
3144
  }
 
3698
  }
3699
  },
3700
  "node_modules/caniuse-lite": {
3701
+ "version": "1.0.30001611",
3702
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001611.tgz",
3703
+ "integrity": "sha512-19NuN1/3PjA3QI8Eki55N8my4LzfkMCRLgCVfrl/slbSAchQfV0+GwjPrK3rq37As4UCLlM/DHajbKkAqbv92Q==",
3704
  "funding": [
3705
  {
3706
  "type": "opencollective",
 
3896
  }
3897
  },
3898
  "node_modules/cookies-next/node_modules/@types/node": {
3899
+ "version": "16.18.96",
3900
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.96.tgz",
3901
+ "integrity": "sha512-84iSqGXoO+Ha16j8pRZ/L90vDMKX04QTYMTfYeE1WrjWaZXuchBehGUZEpNgx7JnmlrIHdnABmpjrQjhCnNldQ=="
3902
  },
3903
  "node_modules/copy-to-clipboard": {
3904
  "version": "3.3.3",
 
4272
  "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
4273
  },
4274
  "node_modules/electron-to-chromium": {
4275
+ "version": "1.4.744",
4276
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.744.tgz",
4277
+ "integrity": "sha512-nAGcF0yeKKfrP13LMFr5U1eghfFSvFLg302VUFzWlcjPOnUYd52yU5x6PBYrujhNbc4jYmZFrGZFK+xasaEzVA=="
4278
  },
4279
  "node_modules/elliptic": {
4280
  "version": "6.5.4",
 
5407
  "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
5408
  },
5409
  "node_modules/gsplat": {
5410
+ "version": "1.2.4",
5411
+ "resolved": "https://registry.npmjs.org/gsplat/-/gsplat-1.2.4.tgz",
5412
+ "integrity": "sha512-YW/qc1KxmkI8VGfVY0avZ6wpcjOijHdXvNkLSy8KniY3R326bYYbePMBlI1VrGQ60dkj4dWnW2k779jKTWNXyQ=="
5413
  },
5414
  "node_modules/has-bigints": {
5415
  "version": "1.0.2",
 
6325
  "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
6326
  },
6327
  "node_modules/next": {
6328
+ "version": "14.2.2",
6329
+ "resolved": "https://registry.npmjs.org/next/-/next-14.2.2.tgz",
6330
+ "integrity": "sha512-oGwUaa2bCs47FbuxWMpOoXtBMPYpvTPgdZr3UAo+pu7Ns00z9otmYpoeV1HEiYL06AlRQQIA/ypK526KjJfaxg==",
6331
  "dependencies": {
6332
+ "@next/env": "14.2.2",
6333
+ "@swc/helpers": "0.5.5",
6334
  "busboy": "1.6.0",
6335
  "caniuse-lite": "^1.0.30001579",
6336
  "graceful-fs": "^4.2.11",
 
6344
  "node": ">=18.17.0"
6345
  },
6346
  "optionalDependencies": {
6347
+ "@next/swc-darwin-arm64": "14.2.2",
6348
+ "@next/swc-darwin-x64": "14.2.2",
6349
+ "@next/swc-linux-arm64-gnu": "14.2.2",
6350
+ "@next/swc-linux-arm64-musl": "14.2.2",
6351
+ "@next/swc-linux-x64-gnu": "14.2.2",
6352
+ "@next/swc-linux-x64-musl": "14.2.2",
6353
+ "@next/swc-win32-arm64-msvc": "14.2.2",
6354
+ "@next/swc-win32-ia32-msvc": "14.2.2",
6355
+ "@next/swc-win32-x64-msvc": "14.2.2"
6356
  },
6357
  "peerDependencies": {
6358
  "@opentelemetry/api": "^1.1.0",
6359
+ "@playwright/test": "^1.41.2",
6360
  "react": "^18.2.0",
6361
  "react-dom": "^18.2.0",
6362
  "sass": "^1.3.0"
 
6365
  "@opentelemetry/api": {
6366
  "optional": true
6367
  },
6368
+ "@playwright/test": {
6369
+ "optional": true
6370
+ },
6371
  "sass": {
6372
  "optional": true
6373
  }
 
6606
  }
6607
  },
6608
  "node_modules/openai": {
6609
+ "version": "4.38.1",
6610
+ "resolved": "https://registry.npmjs.org/openai/-/openai-4.38.1.tgz",
6611
+ "integrity": "sha512-nmSKE9O2piuoh9+AgDqwGHojIFSxToQ2jJqwaxjbzz2ebdD5LYY9s+bMe25b18t4QEgvtgW70JfK8BU3xf5dRw==",
6612
  "dependencies": {
6613
  "@types/node": "^18.11.18",
6614
  "@types/node-fetch": "^2.6.4",
 
6981
  }
6982
  },
6983
  "node_modules/qs": {
6984
+ "version": "6.12.1",
6985
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
6986
+ "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
6987
  "dependencies": {
6988
  "side-channel": "^1.0.6"
6989
  },
 
7991
  }
7992
  },
7993
  "node_modules/tailwind-merge": {
7994
+ "version": "2.3.0",
7995
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz",
7996
+ "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==",
7997
  "dependencies": {
7998
+ "@babel/runtime": "^7.24.1"
7999
  },
8000
  "funding": {
8001
  "type": "github",
package.json CHANGED
@@ -12,7 +12,7 @@
12
  "@huggingface/hub": "0.12.3-oauth",
13
  "@huggingface/inference": "^2.6.7",
14
  "@jcoreio/async-throttle": "^1.6.0",
15
- "@mediapipe/tasks-vision": "^0.10.12",
16
  "@photo-sphere-viewer/core": "^5.7.2",
17
  "@photo-sphere-viewer/equirectangular-video-adapter": "^5.7.2",
18
  "@photo-sphere-viewer/gyroscope-plugin": "^5.7.2",
 
12
  "@huggingface/hub": "0.12.3-oauth",
13
  "@huggingface/inference": "^2.6.7",
14
  "@jcoreio/async-throttle": "^1.6.0",
15
+ "@mediapipe/tasks-vision": "^0.10.13-rc.20240419",
16
  "@photo-sphere-viewer/core": "^5.7.2",
17
  "@photo-sphere-viewer/equirectangular-video-adapter": "^5.7.2",
18
  "@photo-sphere-viewer/gyroscope-plugin": "^5.7.2",
src/app/api/resolvers/image/route.ts CHANGED
@@ -4,7 +4,6 @@ import queryString from "query-string"
4
  import { newRender, getRender } from "../../providers/videochain/renderWithVideoChain"
5
  import { generateSeed } from "@/lib/utils/generateSeed"
6
  import { sleep } from "@/lib/utils/sleep"
7
- import { getContentType } from "@/lib/data/getContentType"
8
 
9
  export async function GET(req: NextRequest) {
10
 
@@ -22,8 +21,8 @@ let prompt = ""
22
  // console.log("calling await newRender")
23
 
24
  let render = await newRender({
25
- prompt,
26
- negativePrompt: "blurry, cropped, bad quality",
27
  nbFrames: 1,
28
  nbSteps: 8,
29
  width: 1024,
 
4
  import { newRender, getRender } from "../../providers/videochain/renderWithVideoChain"
5
  import { generateSeed } from "@/lib/utils/generateSeed"
6
  import { sleep } from "@/lib/utils/sleep"
 
7
 
8
  export async function GET(req: NextRequest) {
9
 
 
21
  // console.log("calling await newRender")
22
 
23
  let render = await newRender({
24
+ prompt: `${prompt}, cinematic, photo, sublime, pro quality, sharp, crisp, beautiful, impressive, amazing, high quality, 4K`,
25
+ negativePrompt: "logo, text, ui, hud, interface, buttons, ad, signature, copyright, blurry, cropped, bad quality",
26
  nbFrames: 1,
27
  nbSteps: 8,
28
  width: 1024,
src/app/api/resolvers/video/route.ts CHANGED
@@ -22,10 +22,10 @@ let prompt = ""
22
  // console.log("calling await newRender")
23
 
24
  let render = await newRender({
25
- prompt,
26
- negativePrompt: "blurry, cropped, bad quality",
27
  nbFrames: 1,
28
- nbSteps: 4,
29
  width: 1024,
30
  height: 576,
31
  turbo: true,
 
22
  // console.log("calling await newRender")
23
 
24
  let render = await newRender({
25
+ prompt: `${prompt}, cinematic, photo, sublime, pro quality, sharp, crisp, beautiful, impressive, amazing, high quality, 4K`,
26
+ negativePrompt: "logo, text, ui, hud, interface, buttons, ad, signature, copyright, blurry, cropped, bad quality",
27
  nbFrames: 1,
28
+ nbSteps: 8,
29
  width: 1024,
30
  height: 576,
31
  turbo: true,
src/components/interface/latent-engine/core/drawSegmentation.ts CHANGED
@@ -1,36 +1,61 @@
1
- import { MPMask } from "@mediapipe/tasks-vision"
 
 
 
 
 
 
 
2
 
3
  /**
4
- * Draw segmentation result
5
  */
6
- export function drawSegmentation(mask?: MPMask, canvas?: HTMLCanvasElement) {
7
-
8
- if (!mask) { throw new Error("drawSegmentation failed: empty mask") }
 
 
 
 
9
 
10
- if (!canvas) { throw new Error("drawSegmentation failed: cannot access the canvas") }
 
 
11
 
12
- const width = mask.width;
13
- const height = mask.height;
14
- const maskData = mask.getAsFloat32Array();
15
 
16
- canvas.width = width;
17
- canvas.height = height;
18
 
19
  console.log("drawSegmentation: drawing..")
20
 
21
  const ctx = canvas.getContext("2d")
 
 
 
22
 
23
- if (!ctx) { throw new Error("drawSegmentation failed: cannot access the 2D context") }
24
-
25
- ctx.fillStyle = "#00000000";
26
  ctx.fillRect(0, 0, width, height);
27
- ctx.fillStyle = "rgba(18, 181, 203, 0.7)";
28
-
29
- maskData.forEach((category: number, index: number, array: Float32Array) => {
30
- if (Math.round(category * 255.0) === 0) {
31
- const x = (index + 1) % width;
32
- const y = (index + 1 - x) / width;
33
- ctx.fillRect(x, y, 1, 1);
34
- }
35
- })
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
 
1
+ import { MPMask } from "@mediapipe/tasks-vision";
2
+
3
+ interface DrawSegmentationOptions {
4
+ mask?: MPMask;
5
+ canvas?: HTMLCanvasElement;
6
+ backgroundImage?: HTMLImageElement;
7
+ fillStyle?: string;
8
+ }
9
 
10
  /**
11
+ * Draw segmentation result with enhancements.
12
  */
13
+ export function drawSegmentation(options: DrawSegmentationOptions): HTMLCanvasElement {
14
+ const {
15
+ mask,
16
+ canvas,
17
+ backgroundImage,
18
+ fillStyle = "rgba(255, 255, 255, 1.0)"
19
+ } = options;
20
 
21
+ if (!canvas) {
22
+ throw new Error("drawSegmentation failed: cannot access the canvas");
23
+ }
24
 
25
+ const width = mask?.width || 0;
26
+ const height = mask?.height || 0;
 
27
 
28
+ canvas.width = width || canvas.width;
29
+ canvas.height = height || canvas.height;
30
 
31
  console.log("drawSegmentation: drawing..")
32
 
33
  const ctx = canvas.getContext("2d")
34
+ if (!ctx) {
35
+ throw new Error("drawSegmentation failed: cannot access the 2D context")
36
+ }
37
 
38
+ ctx.fillStyle = "#00000000"; // Maintain transparent background if no image provided
 
 
39
  ctx.fillRect(0, 0, width, height);
40
+
41
+ // Draw the background image if provided, otherwise default to transparent background.
42
+ if (backgroundImage) {
43
+ ctx.drawImage(backgroundImage, 0, 0, width, height);
44
+ }
45
+
46
+ if (mask) {
47
+
48
+ ctx.fillStyle = fillStyle;
49
+ const maskData = mask.getAsFloat32Array();
50
+
51
+ maskData.forEach((category: number, index: number) => {
52
+ if (Math.round(category * 255.0) === 0) {
53
+ const x = index % width;
54
+ const y = Math.floor(index / width);
55
+ ctx.fillRect(x, y, 1, 1);
56
+ }
57
+ });
58
+ }
59
+
60
+ return canvas;
61
  }
src/components/interface/latent-engine/core/engine.tsx CHANGED
@@ -11,9 +11,6 @@ import { ContentLayer } from "../components/content-layer"
11
  import { MediaInfo } from "@/types/general"
12
  import { getMockClap } from "@/lib/clap/getMockClap"
13
  import { serializeClap } from "@/lib/clap/serializeClap"
14
- import { blobToDataUri } from "@/app/api/utils/blobToDataUri"
15
- import { InteractiveSegmentationCanvas } from "@/lib/on-device-ai/getInteractiveSegmentationCanvas"
16
- import { InteractiveSegmenterResult } from "@mediapipe/tasks-vision"
17
 
18
  function LatentEngine({
19
  media,
 
11
  import { MediaInfo } from "@/types/general"
12
  import { getMockClap } from "@/lib/clap/getMockClap"
13
  import { serializeClap } from "@/lib/clap/serializeClap"
 
 
 
14
 
15
  function LatentEngine({
16
  media,
src/components/interface/latent-engine/resolvers/{index.tsx → deprecated.txt} RENAMED
File without changes
src/components/interface/latent-engine/resolvers/resolveSegment.ts CHANGED
@@ -13,10 +13,8 @@ export async function resolveSegment(segment: ClapSegment, clap: ClapProject): P
13
  if (segment.category === "interface") {
14
  latentComponentResolver = interfaceResolver
15
  } else if (segment.category === "video") {
16
-
17
- // for backend performance reason (generative video is slow)
18
- // we do not support "true" video for now
19
- // latentComponentResolver = videoResolver
20
  latentComponentResolver = imageResolver
21
  }
22
 
 
13
  if (segment.category === "interface") {
14
  latentComponentResolver = interfaceResolver
15
  } else if (segment.category === "video") {
16
+ latentComponentResolver = videoResolver
17
+ } else if (segment.category === "storyboard") {
 
 
18
  latentComponentResolver = imageResolver
19
  }
20
 
src/components/interface/latent-engine/store/useLatentEngine.ts CHANGED
@@ -14,6 +14,7 @@ import { parseClap } from "@/lib/clap/parseClap"
14
  import { InteractiveSegmenterResult, MPMask } from "@mediapipe/tasks-vision"
15
  import { segmentFrame } from "@/lib/on-device-ai/segmentFrameOnClick"
16
  import { drawSegmentation } from "../core/drawSegmentation"
 
17
 
18
  export const useLatentEngine = create<LatentEngineStore>((set, get) => ({
19
  width: 1024,
@@ -144,7 +145,19 @@ export const useLatentEngine = create<LatentEngineStore>((set, get) => ({
144
  if (debug) {
145
  console.log(`processClickOnSegment: callling drawSegmentation`)
146
  }
147
- drawSegmentation(result.categoryMask, segmentationElement)
 
 
 
 
 
 
 
 
 
 
 
 
148
 
149
  if (debug) {
150
  console.log("processClickOnSegment: TODO call data.close() to free the memory!")
@@ -278,13 +291,24 @@ export const useLatentEngine = create<LatentEngineStore>((set, get) => ({
278
  if (get().isPlaying) {
279
  // console.log(`runSimulationLoop: rendering video content layer..`)
280
  // we only grab the first one
 
281
  const videoLayer = (await resolveSegments(clap, "video", 1)).at(0)
282
 
283
  if (get().isPlaying) {
 
284
  set({
285
  videoLayer
286
  })
287
 
 
 
 
 
 
 
 
 
 
288
  console.log(`runSimulationLoop: rendered video content layer`)
289
  }
290
  }
 
14
  import { InteractiveSegmenterResult, MPMask } from "@mediapipe/tasks-vision"
15
  import { segmentFrame } from "@/lib/on-device-ai/segmentFrameOnClick"
16
  import { drawSegmentation } from "../core/drawSegmentation"
17
+ import { filterImage } from "@/lib/on-device-ai/filterImage"
18
 
19
  export const useLatentEngine = create<LatentEngineStore>((set, get) => ({
20
  width: 1024,
 
145
  if (debug) {
146
  console.log(`processClickOnSegment: callling drawSegmentation`)
147
  }
148
+
149
+ const canvasMask: HTMLCanvasElement = drawSegmentation({
150
+ mask: result.categoryMask,
151
+ canvas: segmentationElement,
152
+ backgroundImage: imageElement,
153
+ fillStyle: "rgba(255, 255, 255, 1.0)"
154
+ })
155
+ // TODO: read the canvas te determine on what the user clicked
156
+
157
+ if (debug) {
158
+ console.log(`processClickOnSegment: filtering the original image`)
159
+ }
160
+ // filterImage(imageElement, canvasMask)
161
 
162
  if (debug) {
163
  console.log("processClickOnSegment: TODO call data.close() to free the memory!")
 
291
  if (get().isPlaying) {
292
  // console.log(`runSimulationLoop: rendering video content layer..`)
293
  // we only grab the first one
294
+
295
  const videoLayer = (await resolveSegments(clap, "video", 1)).at(0)
296
 
297
  if (get().isPlaying) {
298
+
299
  set({
300
  videoLayer
301
  })
302
 
303
+ const { videoElement, imageElement, segmentationElement } = get()
304
+
305
+ const canvas = drawSegmentation({
306
+ // no mask means this will effectively clear the canvas
307
+ canvas: segmentationElement,
308
+ backgroundImage: imageElement,
309
+ })
310
+
311
+
312
  console.log(`runSimulationLoop: rendered video content layer`)
313
  }
314
  }
src/components/interface/stream-tag/index.tsx CHANGED
@@ -15,12 +15,14 @@ export function StreamTag({
15
  const isInteractive = streamType === "interactive"
16
  const isLive = streamType === "live"
17
  const isStatic = !isInteractive && !isLive
 
18
  console.log("debug:", {
19
  streamType,
20
  isInteractive,
21
  isLive,
22
  isStatic
23
  })
 
24
 
25
  return (
26
  <div className={cn(`
 
15
  const isInteractive = streamType === "interactive"
16
  const isLive = streamType === "live"
17
  const isStatic = !isInteractive && !isLive
18
+ /*
19
  console.log("debug:", {
20
  streamType,
21
  isInteractive,
22
  isLive,
23
  isStatic
24
  })
25
+ */
26
 
27
  return (
28
  <div className={cn(`
src/lib/clap/getMockClap.ts CHANGED
@@ -6,10 +6,11 @@ let defaultSegmentDurationInMs = 2000
6
 
7
  // const demoPrompt = "closeup of Queen angelfish, bokeh"
8
  // const demoPrompt = "portrait of a man tv news anchor, pierre-jean-hyves, serious, bokeh"
9
- const demoPrompt = "dogs and cats, playing in garden, balls, trees"
 
10
 
11
  export function getMockClap({
12
- prompt =demoPrompt,
13
  showDisclaimer = true,
14
  }: {
15
  prompt?: string
 
6
 
7
  // const demoPrompt = "closeup of Queen angelfish, bokeh"
8
  // const demoPrompt = "portrait of a man tv news anchor, pierre-jean-hyves, serious, bokeh"
9
+ // const demoPrompt = "screenshot from Call of Duty, FPS game, nextgen, videogame screenshot, unreal engine, raytracing"
10
+ const demoPrompt = "screenshot from a flight simulator, nextgen, videogame screenshot, unreal engine, raytracing"
11
 
12
  export function getMockClap({
13
+ prompt = demoPrompt,
14
  showDisclaimer = true,
15
  }: {
16
  prompt?: string
src/lib/on-device-ai/classifyFrame.ts ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { FilesetResolver, ImageClassifier, ImageClassifierResult } from "@mediapipe/tasks-vision"
2
+
3
+ export type InteractiveImageClassifier = (videoFrame: TexImageSource, x: number, y: number) => Promise<ImageClassifierResult>
4
+
5
+ const getInteractiveImageClassifier = async (): Promise<InteractiveImageClassifier> => {
6
+ const vision = await FilesetResolver.forVisionTasks(
7
+ "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@latest/wasm"
8
+ );
9
+
10
+ const imageClassifier = await ImageClassifier.createFromOptions(vision, {
11
+ baseOptions: {
12
+ modelAssetPath: `https://storage.googleapis.com/mediapipe-models/image_classifier/efficientnet_lite0/float32/1/efficientnet_lite0.tflite`
13
+ },
14
+ runningMode: "VIDEO",
15
+ });
16
+
17
+ const segmenter: InteractiveImageClassifier = (
18
+ videoFrame: TexImageSource,
19
+ x: number,
20
+ y: number
21
+ ): Promise<ImageClassifierResult> => {
22
+ return new Promise((resolve, reject) => {
23
+ imageClassifier.classify(
24
+ videoFrame
25
+ // TODO: there is a "region of interest field" we could use
26
+ )
27
+ })
28
+ }
29
+
30
+ return segmenter
31
+ }
32
+
33
+
34
+ const globalState: { classifier?: InteractiveImageClassifier } = {};
35
+
36
+ (async () => {
37
+ globalState.classifier = globalState.classifier || (await getInteractiveImageClassifier())
38
+ })();
39
+
40
+ export async function classifyFrame(frame: TexImageSource, x: number, y: number): Promise<ImageClassifierResult> {
41
+ console.log("classifyFrame: loading classifier..")
42
+ globalState.classifier = globalState.classifier || (await getInteractiveImageClassifier())
43
+
44
+ console.log("classifyFrame: segmenting..")
45
+ return globalState.classifier(frame, x, y)
46
+ }
47
+
48
+ // to run:
49
+
50
+ // see doc:
51
+ // https://developers.google.com/mediapipe/solutions/vision/image_segmenter/web_js#video
52
+ // imageSegmenter.segmentForVideo(video, startTimeMs, callbackForVideo);
src/lib/on-device-ai/filterImage.ts ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Applies a mask to an image using canvas blending modes to avoid explicit pixel iteration.
3
+ *
4
+ * @param image The source image as an HTMLImageElement.
5
+ * @param maskCanvas The canvas element containing a mask.
6
+ * @returns A new Promise resolving to a headless canvas element containing the masked image.
7
+ */
8
+ export async function filterImage(
9
+ image?: HTMLImageElement,
10
+ maskCanvas?: HTMLCanvasElement
11
+ ): Promise<HTMLCanvasElement> {
12
+ return new Promise((resolve, reject) => {
13
+
14
+ // Create a new canvas to construct the final image
15
+ const resultCanvas = document.createElement("canvas");
16
+
17
+ if (!image) {
18
+ // reject(`missing image (must be a HTMLImageElement)`)
19
+ resolve(resultCanvas)
20
+ return
21
+ }
22
+
23
+ resultCanvas.width = image.width;
24
+ resultCanvas.height = image.height;
25
+
26
+ if (!maskCanvas) {
27
+ // reject(`missing image (must be a HTMLImageElement)`)
28
+ resolve(resultCanvas)
29
+ return
30
+ }
31
+
32
+ const ctx = resultCanvas.getContext("2d");
33
+ if (!ctx) {
34
+ reject(new Error("Failed to get 2D context"));
35
+ return;
36
+ }
37
+
38
+ // Draw the original image
39
+ ctx.drawImage(image, 0, 0, image.width, image.height);
40
+
41
+ // Set blending mode to 'destination-in' to keep only the content that overlaps the mask
42
+ ctx.globalCompositeOperation = "destination-in";
43
+ ctx.drawImage(maskCanvas, 0, 0, image.width, image.height);
44
+
45
+ // Reset composite operation to default
46
+ ctx.globalCompositeOperation = "source-over";
47
+
48
+ // Draw white rectangle where the mask is opaque
49
+ ctx.globalCompositeOperation = "destination-over";
50
+ ctx.fillStyle = "white";
51
+ ctx.fillRect(0, 0, image.width, image.height);
52
+
53
+ resolve(resultCanvas);
54
+ });
55
+ }
src/lib/on-device-ai/getInteractiveSegmentationCanvas.tsx DELETED
@@ -1,37 +0,0 @@
1
- import { useRef } from "react"
2
- import { segmentFrame } from "./segmentFrameOnClick"
3
- import { ImageSource, InteractiveSegmenterResult } from "@mediapipe/tasks-vision"
4
-
5
-
6
- export function InteractiveSegmentationCanvas({
7
- src,
8
- onClick,
9
- }: {
10
- src?: ImageSource
11
- onClick?: (results: InteractiveSegmenterResult ) => void
12
- }) {
13
- const segmentationClickRef = useRef<HTMLDivElement>(null)
14
- return (
15
- <div
16
- ref={segmentationClickRef}
17
- onClick={(event) => {
18
- if (!segmentationClickRef.current || !src || !onClick) { return }
19
-
20
- const box = segmentationClickRef.current.getBoundingClientRect()
21
-
22
- const px = event.clientX
23
- const py = event.clientY
24
-
25
- const x = px / box.width
26
- const y = py / box.height
27
-
28
- const fn = async () => {
29
- const results: InteractiveSegmenterResult = await segmentFrame(src, x, y);
30
- onClick(results)
31
- }
32
- fn()
33
-
34
- }}>
35
- </div>
36
- )
37
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/lib/on-device-ai/getSegmentationCanvas.tsx CHANGED
@@ -1,6 +1,6 @@
1
 
2
  import React from "react"
3
- import { ImageSegmenterResult, ImageSource } from "@mediapipe/tasks-vision"
4
 
5
  import { segmentFrame } from "./segmentFrame"
6
 
@@ -10,7 +10,7 @@ export async function getSegmentationCanvas({
10
  width,
11
  height
12
  }: {
13
- frame: ImageSource;
14
  timestamp: number;
15
  width: number;
16
  height: number;
 
1
 
2
  import React from "react"
3
+ import { ImageSegmenterResult } from "@mediapipe/tasks-vision"
4
 
5
  import { segmentFrame } from "./segmentFrame"
6
 
 
10
  width,
11
  height
12
  }: {
13
+ frame: TexImageSource;
14
  timestamp: number;
15
  width: number;
16
  height: number;
src/lib/on-device-ai/identifyFrame.ts CHANGED
@@ -1,11 +1,10 @@
1
  import {
2
  FilesetResolver,
3
  ObjectDetector,
4
- ObjectDetectorResult,
5
- ImageSource
6
  } from "@mediapipe/tasks-vision"
7
 
8
- export type VideoObjectDetector = (videoFrame: ImageSource, timestamp: number) => Promise<ObjectDetectorResult>
9
 
10
  const getObjectDetector = async (): Promise<VideoObjectDetector> => {
11
  const vision = await FilesetResolver.forVisionTasks(
@@ -20,7 +19,7 @@ const getObjectDetector = async (): Promise<VideoObjectDetector> => {
20
  runningMode: "VIDEO"
21
  });
22
 
23
- const detector: VideoObjectDetector = async (videoFrame: ImageSource, timestamp: number): Promise<ObjectDetectorResult> => {
24
  const result = objectDetector.detectForVideo(videoFrame, timestamp)
25
  return result
26
  }
@@ -35,7 +34,7 @@ const globalState: { detector?: VideoObjectDetector } = {};
35
  globalState.detector = globalState.detector || (await getObjectDetector())
36
  })();
37
 
38
- export async function identifyFrame(frame: ImageSource, timestamp: number): Promise<ObjectDetectorResult> {
39
  console.log("identifyFrame: loading segmenter..")
40
  globalState.detector = globalState.detector || (await getObjectDetector())
41
 
 
1
  import {
2
  FilesetResolver,
3
  ObjectDetector,
4
+ ObjectDetectorResult
 
5
  } from "@mediapipe/tasks-vision"
6
 
7
+ export type VideoObjectDetector = (videoFrame: TexImageSource, timestamp: number) => Promise<ObjectDetectorResult>
8
 
9
  const getObjectDetector = async (): Promise<VideoObjectDetector> => {
10
  const vision = await FilesetResolver.forVisionTasks(
 
19
  runningMode: "VIDEO"
20
  });
21
 
22
+ const detector: VideoObjectDetector = async (videoFrame: TexImageSource, timestamp: number): Promise<ObjectDetectorResult> => {
23
  const result = objectDetector.detectForVideo(videoFrame, timestamp)
24
  return result
25
  }
 
34
  globalState.detector = globalState.detector || (await getObjectDetector())
35
  })();
36
 
37
+ export async function identifyFrame(frame: TexImageSource, timestamp: number): Promise<ObjectDetectorResult> {
38
  console.log("identifyFrame: loading segmenter..")
39
  globalState.detector = globalState.detector || (await getObjectDetector())
40
 
src/lib/on-device-ai/segmentFrame.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { FilesetResolver, ImageSegmenter, ImageSegmenterResult, ImageSource } from "@mediapipe/tasks-vision"
2
 
3
- export type VideoSegmenter = (videoFrame: ImageSource, timestamp: number) => Promise<ImageSegmenterResult>
4
 
5
  const getSegmenter = async (): Promise<VideoSegmenter> => {
6
  const vision = await FilesetResolver.forVisionTasks(
@@ -24,7 +24,7 @@ const getSegmenter = async (): Promise<VideoSegmenter> => {
24
  runningMode: "VIDEO"
25
  });
26
 
27
- const segmenter: VideoSegmenter = (videoFrame: ImageSource, timestamp: number): Promise<ImageSegmenterResult> => {
28
  return new Promise((resolve, reject) => {
29
  imageSegmenter.segmentForVideo(videoFrame, timestamp, (results) => {
30
  resolve(results)
@@ -42,7 +42,7 @@ const globalState: { segmenter?: VideoSegmenter } = {};
42
  globalState.segmenter = globalState.segmenter || (await getSegmenter())
43
  })();
44
 
45
- export async function segmentFrame(frame: ImageSource, timestamp: number): Promise<ImageSegmenterResult> {
46
  console.log("segmentFrame: loading segmenter..")
47
  globalState.segmenter = globalState.segmenter || (await getSegmenter())
48
 
 
1
+ import { FilesetResolver, ImageSegmenter, ImageSegmenterResult } from "@mediapipe/tasks-vision"
2
 
3
+ export type VideoSegmenter = (videoFrame: TexImageSource, timestamp: number) => Promise<ImageSegmenterResult>
4
 
5
  const getSegmenter = async (): Promise<VideoSegmenter> => {
6
  const vision = await FilesetResolver.forVisionTasks(
 
24
  runningMode: "VIDEO"
25
  });
26
 
27
+ const segmenter: VideoSegmenter = (videoFrame: TexImageSource, timestamp: number): Promise<ImageSegmenterResult> => {
28
  return new Promise((resolve, reject) => {
29
  imageSegmenter.segmentForVideo(videoFrame, timestamp, (results) => {
30
  resolve(results)
 
42
  globalState.segmenter = globalState.segmenter || (await getSegmenter())
43
  })();
44
 
45
+ export async function segmentFrame(frame: TexImageSource, timestamp: number): Promise<ImageSegmenterResult> {
46
  console.log("segmentFrame: loading segmenter..")
47
  globalState.segmenter = globalState.segmenter || (await getSegmenter())
48
 
src/lib/on-device-ai/segmentFrameOnClick.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { FilesetResolver, InteractiveSegmenter, InteractiveSegmenterResult, ImageSource } from "@mediapipe/tasks-vision"
2
 
3
- export type InteractiveVideoSegmenter = (videoFrame: ImageSource, x: number, y: number) => Promise<InteractiveSegmenterResult>
4
 
5
  const getInteractiveSegmenter = async (): Promise<InteractiveVideoSegmenter> => {
6
  const vision = await FilesetResolver.forVisionTasks(
@@ -17,7 +17,7 @@ const getInteractiveSegmenter = async (): Promise<InteractiveVideoSegmenter> =>
17
  });
18
 
19
  const segmenter: InteractiveVideoSegmenter = (
20
- videoFrame: ImageSource,
21
  x: number,
22
  y: number
23
  ): Promise<InteractiveSegmenterResult> => {
@@ -43,7 +43,7 @@ const globalState: { segmenter?: InteractiveVideoSegmenter } = {};
43
  globalState.segmenter = globalState.segmenter || (await getInteractiveSegmenter())
44
  })();
45
 
46
- export async function segmentFrame(frame: ImageSource, x: number, y: number): Promise<InteractiveSegmenterResult> {
47
  console.log("segmentFrame: loading segmenter..")
48
  globalState.segmenter = globalState.segmenter || (await getInteractiveSegmenter())
49
 
 
1
+ import { FilesetResolver, InteractiveSegmenter, InteractiveSegmenterResult } from "@mediapipe/tasks-vision"
2
 
3
+ export type InteractiveVideoSegmenter = (videoFrame: TexImageSource, x: number, y: number) => Promise<InteractiveSegmenterResult>
4
 
5
  const getInteractiveSegmenter = async (): Promise<InteractiveVideoSegmenter> => {
6
  const vision = await FilesetResolver.forVisionTasks(
 
17
  });
18
 
19
  const segmenter: InteractiveVideoSegmenter = (
20
+ videoFrame: TexImageSource,
21
  x: number,
22
  y: number
23
  ): Promise<InteractiveSegmenterResult> => {
 
43
  globalState.segmenter = globalState.segmenter || (await getInteractiveSegmenter())
44
  })();
45
 
46
+ export async function segmentFrame(frame: TexImageSource, x: number, y: number): Promise<InteractiveSegmenterResult> {
47
  console.log("segmentFrame: loading segmenter..")
48
  globalState.segmenter = globalState.segmenter || (await getInteractiveSegmenter())
49