@lampdotdev/lamp 0.0.0-stage → 0.35.0

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 (464) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +357 -2
  3. package/Resources/Devices/roku.json +410 -0
  4. package/Resources/Devices/xbox-one.json +367 -0
  5. package/Resources/GameKit/NOTICE.md +63 -0
  6. package/Resources/GameKit/apple/LampPage.swift +1646 -0
  7. package/Resources/GameKit/apple/LampPlayer.swift +46 -0
  8. package/Resources/GameKit/apple/LampWebApp.swift +63 -0
  9. package/Resources/GameKit/apple/LampWebGame.swift +87 -0
  10. package/Resources/GameKit/apple/Native.swift +12 -0
  11. package/Resources/GameKit/build.sh +55 -0
  12. package/Resources/GameKit/lamp_game.h +116 -0
  13. package/Resources/GameKit/lamp_host.h +19 -0
  14. package/Resources/GameKit/lamp_kit.cpp +61 -0
  15. package/Resources/GameKit/lamp_sound.cpp +455 -0
  16. package/Resources/GameKit/lamp_xbox.cpp +374 -0
  17. package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
  18. package/Resources/GameKit/libraries/cgltf.h +7240 -0
  19. package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
  20. package/Resources/GameKit/libraries/dr_wav.h +9209 -0
  21. package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
  22. package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
  23. package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
  24. package/Resources/GameKit/libraries/sokol_log.h +335 -0
  25. package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
  26. package/Resources/GameKit/libraries/stb_image.h +7988 -0
  27. package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
  28. package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
  29. package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
  30. package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
  31. package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
  32. package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
  33. package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
  34. package/Resources/GameKit/web/lamp-game.js +3036 -0
  35. package/Resources/GameKit/web/lamp-phaser.js +128 -0
  36. package/Resources/WebHost/App.exe +0 -0
  37. package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
  38. package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
  39. package/Resources/WebHost/lamp_controllers.h +1506 -0
  40. package/Resources/WebHost/lamp_web_host.cpp +1173 -0
  41. package/Resources/WebLibraries/earlier.txt +318 -0
  42. package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
  43. package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
  44. package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
  45. package/Resources/WebLibraries/qrcode/LICENSE +21 -0
  46. package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
  47. package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
  48. package/Resources/WebLibraries/rapier/LICENSE +201 -0
  49. package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
  50. package/Resources/WebLibraries/rapier/rapier.js +2 -0
  51. package/Resources/WebLibraries/three/LICENSE +21 -0
  52. package/Resources/WebLibraries/three/NOTICE.md +4 -0
  53. package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
  54. package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
  55. package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
  56. package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
  57. package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
  58. package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
  59. package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
  60. package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
  61. package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
  62. package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
  63. package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
  64. package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
  65. package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
  66. package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
  67. package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
  68. package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
  69. package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
  70. package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
  71. package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
  72. package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
  73. package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
  74. package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
  75. package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
  76. package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
  77. package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
  78. package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
  79. package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
  80. package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
  81. package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
  82. package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
  83. package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
  84. package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
  85. package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
  86. package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
  87. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
  88. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
  89. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
  90. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
  91. package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
  92. package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
  93. package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
  94. package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
  95. package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
  96. package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
  97. package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
  98. package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
  99. package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
  100. package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
  101. package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
  102. package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
  103. package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
  104. package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
  105. package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
  106. package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
  107. package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
  108. package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
  109. package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
  110. package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
  111. package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
  112. package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
  113. package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
  114. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
  115. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
  116. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
  117. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
  118. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
  119. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
  120. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
  121. package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
  122. package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
  123. package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
  124. package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
  125. package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
  126. package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
  127. package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
  128. package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
  129. package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
  130. package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
  131. package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
  132. package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
  133. package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
  134. package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
  135. package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
  136. package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
  137. package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
  138. package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
  139. package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
  140. package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
  141. package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
  142. package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
  143. package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
  144. package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
  145. package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
  146. package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
  147. package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
  148. package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
  149. package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
  150. package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
  151. package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
  152. package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
  153. package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
  154. package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
  155. package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
  156. package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
  157. package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
  158. package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
  159. package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
  160. package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
  161. package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
  162. package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
  163. package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
  164. package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
  165. package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
  166. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
  167. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
  168. package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
  169. package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
  170. package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
  171. package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
  172. package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
  173. package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
  174. package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
  175. package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
  176. package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
  177. package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
  178. package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
  179. package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
  180. package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
  181. package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
  182. package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
  183. package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
  184. package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
  185. package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
  186. package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
  187. package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
  188. package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
  189. package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
  190. package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
  191. package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
  192. package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
  193. package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
  194. package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
  195. package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
  196. package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
  197. package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
  198. package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
  199. package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
  200. package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
  201. package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
  202. package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
  203. package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
  204. package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
  205. package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
  206. package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
  207. package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
  208. package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
  209. package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
  210. package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
  211. package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
  212. package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
  213. package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
  214. package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
  215. package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
  216. package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
  217. package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
  218. package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
  219. package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
  220. package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
  221. package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
  222. package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
  223. package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
  224. package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
  225. package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
  226. package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
  227. package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
  228. package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
  229. package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
  230. package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
  231. package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
  232. package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
  233. package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
  234. package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
  235. package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
  236. package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
  237. package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
  238. package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
  239. package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
  240. package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
  241. package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
  242. package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
  243. package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
  244. package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
  245. package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
  246. package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
  247. package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
  248. package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
  249. package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
  250. package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
  251. package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
  252. package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
  253. package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
  254. package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
  255. package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
  256. package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
  257. package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
  258. package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
  259. package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
  260. package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
  261. package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
  262. package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
  263. package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
  264. package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
  265. package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
  266. package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
  267. package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
  268. package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
  269. package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
  270. package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
  271. package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
  272. package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
  273. package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
  274. package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
  275. package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
  276. package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
  277. package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
  278. package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
  279. package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
  280. package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
  281. package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
  282. package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
  283. package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
  284. package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
  285. package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
  286. package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
  287. package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
  288. package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
  289. package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
  290. package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
  291. package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
  292. package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
  293. package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
  294. package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
  295. package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
  296. package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
  297. package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
  298. package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
  299. package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
  300. package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
  301. package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
  302. package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
  303. package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
  304. package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
  305. package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
  306. package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
  307. package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
  308. package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
  309. package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
  310. package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
  311. package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
  312. package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
  313. package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
  314. package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
  315. package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
  316. package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
  317. package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
  318. package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
  319. package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
  320. package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
  321. package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
  322. package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
  323. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
  324. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
  325. package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
  326. package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
  327. package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
  328. package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
  329. package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
  330. package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
  331. package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
  332. package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
  333. package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
  334. package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
  335. package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
  336. package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
  337. package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
  338. package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
  339. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
  340. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
  341. package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
  342. package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
  343. package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
  344. package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
  345. package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
  346. package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
  347. package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
  348. package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
  349. package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
  350. package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
  351. package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
  352. package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
  353. package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
  354. package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
  355. package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
  356. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
  357. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
  358. package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
  359. package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
  360. package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
  361. package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
  362. package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
  363. package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
  364. package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
  365. package/Resources/WebLibraries/three/three.core.js +61162 -0
  366. package/Resources/WebLibraries/three/three.module.js +19537 -0
  367. package/Resources/WebLibraries/three/three.tsl.js +41903 -0
  368. package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
  369. package/Resources/skills/2d-game/SKILL.md +305 -0
  370. package/Resources/skills/3d-game/SKILL.md +274 -0
  371. package/Resources/skills/accounts/SKILL.md +41 -0
  372. package/Resources/skills/android-design/SKILL.md +159 -0
  373. package/Resources/skills/app-ai/SKILL.md +154 -0
  374. package/Resources/skills/app-intents/SKILL.md +31 -0
  375. package/Resources/skills/app-kinds/SKILL.md +122 -0
  376. package/Resources/skills/apple-watch/SKILL.md +43 -0
  377. package/Resources/skills/assets/SKILL.md +183 -0
  378. package/Resources/skills/building-blocks/SKILL.md +97 -0
  379. package/Resources/skills/device-control/SKILL.md +56 -0
  380. package/Resources/skills/device-integrations/SKILL.md +278 -0
  381. package/Resources/skills/finder-files/SKILL.md +19 -0
  382. package/Resources/skills/game/SKILL.md +414 -0
  383. package/Resources/skills/game-3d/SKILL.md +12 -0
  384. package/Resources/skills/game-art/SKILL.md +11 -0
  385. package/Resources/skills/game-feel/SKILL.md +13 -0
  386. package/Resources/skills/game-levels/SKILL.md +12 -0
  387. package/Resources/skills/game-live/SKILL.md +12 -0
  388. package/Resources/skills/game-physics/SKILL.md +13 -0
  389. package/Resources/skills/game-playtest/SKILL.md +26 -0
  390. package/Resources/skills/game-ui/SKILL.md +278 -0
  391. package/Resources/skills/github-projects/SKILL.md +59 -0
  392. package/Resources/skills/icloud-sync/SKILL.md +30 -0
  393. package/Resources/skills/iphone-hardware/SKILL.md +57 -0
  394. package/Resources/skills/iphone-widgets/SKILL.md +53 -0
  395. package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
  396. package/Resources/skills/mac-widgets/SKILL.md +60 -0
  397. package/Resources/skills/maps/SKILL.md +8 -0
  398. package/Resources/skills/menu-bar/SKILL.md +36 -0
  399. package/Resources/skills/more-apps/SKILL.md +53 -0
  400. package/Resources/skills/phone-controllers/SKILL.md +79 -0
  401. package/Resources/skills/phone-pages/SKILL.md +173 -0
  402. package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
  403. package/Resources/skills/scene-3d/SKILL.md +27 -0
  404. package/Resources/skills/scripting/SKILL.md +17 -0
  405. package/Resources/skills/share-extension/SKILL.md +22 -0
  406. package/Resources/skills/tv-design/SKILL.md +72 -0
  407. package/Resources/skills/web-app/SKILL.md +136 -0
  408. package/Resources/skills/web-game/SKILL.md +95 -0
  409. package/Resources/skills/web-or-native/SKILL.md +103 -0
  410. package/Resources/skills/wish-links/SKILL.md +156 -0
  411. package/THIRD_PARTY_NOTICES.md +170 -0
  412. package/cli/android.mjs +941 -0
  413. package/cli/browser.mjs +268 -0
  414. package/cli/calls.mjs +390 -0
  415. package/cli/dev.mjs +773 -0
  416. package/cli/devices.mjs +984 -0
  417. package/cli/lamp.mjs +1016 -0
  418. package/cli/lampapp.mjs +332 -0
  419. package/cli/lamps/android-host/LampPageGateway.kt +345 -0
  420. package/cli/lamps/android-host/app/build.gradle.kts +40 -0
  421. package/cli/lamps/android-host/build.gradle.kts +4 -0
  422. package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
  423. package/cli/lamps/android-host/game/MainActivity.kt +173 -0
  424. package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
  425. package/cli/lamps/android-host/gradle.properties +8 -0
  426. package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
  427. package/cli/lamps/android-host/page/MainActivity.kt +193 -0
  428. package/cli/lamps/android-host/settings.gradle.kts +30 -0
  429. package/cli/lamps/android-host/tools.json +43 -0
  430. package/cli/lamps/lamp-controllers.js +2 -0
  431. package/cli/lamps/lamp-for-games.js +6863 -0
  432. package/cli/lamps/lamp.js +7023 -0
  433. package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
  434. package/cli/lamps/mac-starter/APP.md +12 -0
  435. package/cli/lamps/mac-starter/Package.swift +8 -0
  436. package/cli/lamps/mac-starter/Sources/App.swift +11 -0
  437. package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
  438. package/cli/lamps/mac-starter/Sources/LampSupport.swift +18097 -0
  439. package/cli/lamps/mac-starter/build.sh +336 -0
  440. package/cli/lamps/mac-starter/gitignore +3 -0
  441. package/cli/lamps/mac-starter/lamp-starter.json +6 -0
  442. package/cli/lamps/web-starter/APP.md +8 -0
  443. package/cli/lamps/web-starter/app.js +1 -0
  444. package/cli/lamps/web-starter/index.html +17 -0
  445. package/cli/lamps/web-starter/lamp-starter.json +5 -0
  446. package/cli/lamps/web-starter/lamp.js +7023 -0
  447. package/cli/lamps/web-starter/style.css +25 -0
  448. package/cli/link.mjs +138 -0
  449. package/cli/mac.mjs +621 -0
  450. package/cli/mdns.mjs +205 -0
  451. package/cli/msix.mjs +413 -0
  452. package/cli/network.mjs +209 -0
  453. package/cli/outside.mjs +140 -0
  454. package/cli/page.js +165 -0
  455. package/cli/place.mjs +298 -0
  456. package/cli/png.mjs +184 -0
  457. package/cli/share.mjs +202 -0
  458. package/cli/skill/SKILL.md +255 -0
  459. package/cli/skills.mjs +71 -0
  460. package/cli/state.mjs +173 -0
  461. package/cli/update.mjs +57 -0
  462. package/package.json +20 -4
  463. package/site/lib/quota.js +59 -0
  464. package/site/lib/shared-wishes.js +996 -0
package/cli/place.mjs ADDED
@@ -0,0 +1,298 @@
1
+ // A page on one of the person's devices: packaged for the device's own host, put there, opened, looked at, stopped
2
+ // and taken off again, each through what the device's integration says (devices.mjs). An Xbox is the first: the page
3
+ // goes in Lamp's host for the console's own Chromium (Resources/WebHost), in a Windows package lamp makes and signs
4
+ // itself (msix.mjs), installed through the console's Device Portal. It's `DeviceApps` in Lamp's app, for a page.
5
+ //
6
+ // The package is made in lamp's own folder for the app, never in the app's: what goes to a device is what lamp read
7
+ // of the page as it packaged it.
8
+
9
+ import { createHash } from "node:crypto";
10
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
11
+ import { dirname, join } from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ import { Problem, RESOURCES, stateOf } from "./state.mjs";
14
+ import { androidDeviceNamed, emulatorNamed, knowsAndroid, lookOnAndroid, putOnAndroid, removeFromAndroid, stopOnAndroid, useOnAndroid } from "./android.mjs";
15
+ import { Away, Runner, StillWorking, allKept, answersOn, devicesHome, integrationOf, isReady, kept, look, takesPages } from "./devices.mjs";
16
+ import { PUBLISHER, WEB_HOST, identityName, keptSigner, namesOf, packageOf, versionAfter } from "./msix.mjs";
17
+ import { sizeOf, tile } from "./png.mjs";
18
+ import { nameOf, pageFiles } from "./share.mjs";
19
+
20
+ const HERE = dirname(fileURLToPath(import.meta.url));
21
+ const HOST = join(RESOURCES, "WebHost");
22
+ const sleep = (ms) => new Promise((done) => setTimeout(done, ms));
23
+ // The most lamp sends a device.
24
+ const PACKAGE_LIMIT = 1 << 30;
25
+
26
+ function readJSON(file) { try { return JSON.parse(readFileSync(file, "utf8")); } catch { return null; } }
27
+
28
+ /**
29
+ * The device a word names, among those lamp set up that take a page: by its own name ("Living Room Xbox"), its kind
30
+ * ("xbox") or its id. One that's only found on the network is never taken for the person's: it's set up first.
31
+ */
32
+ export function deviceNamed(word, { command = "lamp" } = {}) {
33
+ const wanted = String(word).toLowerCase();
34
+ const mine = allKept().filter((device) => takesPages(integrationOf(device.integration)));
35
+ const setUp = `${command} devices add sets one up: run it in a terminal yourself, since it asks for what only you should type`;
36
+ if (!mine.length) throw new Problem(`lamp hasn't set up a device that takes a page yet. ${setUp}.`);
37
+ const named = mine.filter((device) => {
38
+ const integration = integrationOf(device.integration);
39
+ return device.id.toLowerCase() === wanted || device.name.toLowerCase() === wanted || integration.id.startsWith(wanted) || integration.name.toLowerCase() === wanted;
40
+ });
41
+ const found = named.length ? named : mine.filter((device) => device.name.toLowerCase().includes(wanted));
42
+ if (!found.length) throw new Problem(`lamp has no device called "${word}" set up. It has: ${mine.map((device) => device.name).join(", ")}.`);
43
+ if (found.length > 1) throw new Problem(`"${word}" could be ${found.map((device) => `"${device.name}"`).join(" or ")}: say which by its name.`);
44
+ if (!isReady(found[0], integrationOf(found[0].integration))) throw new Problem(`${found[0].name} isn't all set up yet. ${setUp}.`);
45
+ return found[0];
46
+ }
47
+
48
+ /**
49
+ * Where the word after --on says a page goes, each put on, looked at, stopped and taken off the same way: lamp's own
50
+ * Android emulator ("android", "android-tv"), a device lamp set up ("xbox", or its name), or an Android device of the
51
+ * person's that adb sees (its name, or adb's serial for it). Only an Android place can be tried (`use`): adb sends it
52
+ * taps and keys, where a console takes none.
53
+ */
54
+ export async function placeNamed(word, { command = "lamp" } = {}) {
55
+ const android = (place) => ({
56
+ name: place.name, word: place.word,
57
+ put: (layout, options = {}) => putOnAndroid(layout, place, { ...options, command }),
58
+ look: (layout) => lookOnAndroid(layout, place, { command }),
59
+ use: (layout, moves) => useOnAndroid(layout, place, moves, { command }),
60
+ stop: (layout) => stopOnAndroid(layout, place),
61
+ remove: (layout) => removeFromAndroid(layout, place, { command }),
62
+ });
63
+ const emulator = emulatorNamed(word);
64
+ if (emulator) {
65
+ if (!knowsAndroid()) throw new Problem(process.platform === "darwin" ? "Lamp's Android app for a page isn't beside this copy of lamp: scripts/cli-files.sh writes it" : "lamp builds for Android on a Mac, so far");
66
+ return android(emulator);
67
+ }
68
+ let device, missing;
69
+ try { device = deviceNamed(word, { command }); } catch (error) { if (!(error instanceof Problem)) throw error; missing = error; }
70
+ if (device) {
71
+ return {
72
+ name: device.name, word,
73
+ put: async (layout, options = {}) => {
74
+ const put = await putOn(layout, device, options);
75
+ return { ...put, line: `${put.name} is open on ${device.name}${put.game ? ", installed as a game" : ""}: ${put.files} files, version ${put.identity.version}.` };
76
+ },
77
+ look: (layout) => lookOn(layout, device),
78
+ stop: (layout) => stopOn(layout, device),
79
+ remove: (layout) => removeFrom(layout, device),
80
+ };
81
+ }
82
+ const own = await androidDeviceNamed(word);
83
+ if (own) return android(own);
84
+ throw new Problem(`${missing.message}${knowsAndroid() ? ` lamp's Android emulator is --on android, and an Android device of the person's goes by its name once it's plugged in with USB debugging on (${command} devices lists them).` : ""}`);
85
+ }
86
+
87
+ /**
88
+ * Makes sure the device answers where lamp last found it, before anything is made for it. One that doesn't may have
89
+ * been given another address since: lamp looks for it once, and goes on at the address it answers from now.
90
+ */
91
+ async function reached(runner) {
92
+ const device = runner.device, port = runner.integration.bridge?.install?.find((action) => action.http)?.http.port;
93
+ if (!port || (await answersOn(device.address, port, { reach: runner.reach }))) return;
94
+ await look().catch(() => []);
95
+ const now = kept(device.id);
96
+ if (now?.address && now.address !== device.address && (await answersOn(now.address, port, { reach: runner.reach }))) { device.address = now.address; return; }
97
+ throw new Problem(`${device.name} isn't answering (last at ${device.address}). Make sure it's on and in Developer Mode, then try again.`);
98
+ }
99
+
100
+ /** Where lamp keeps what it made of an app for one device: the package, its names, and which copy the device has. */
101
+ const buildFolder = (layout, device) => join(stateOf(layout.folder), "device", createHash("sha256").update(device.id).digest("hex").slice(0, 8));
102
+
103
+ /** The app's name to lamp, which its package is named for: its folder's own, so two apps never share a package. */
104
+ const appID = (layout) => stateOf(layout.folder).split(/[\\/]/).pop();
105
+
106
+ /**
107
+ * The package's name on the Xbox: the folder's name, cut so its hash always fits after it (`identityName` keeps 40
108
+ * characters), so two folders with the same long name are two apps there.
109
+ */
110
+ const xboxName = (layout) => {
111
+ const id = appID(layout), hash = id.slice(id.lastIndexOf("-") + 1);
112
+ const name = [...id.slice(0, id.lastIndexOf("-"))].filter((c) => /[A-Za-z0-9-]/.test(c)).join("");
113
+ return identityName(`${name.slice(0, 40 - hash.length - 1)}-${hash}`);
114
+ };
115
+
116
+ /** What a game's page is told about the device it's on (`GamePage.descriptor`): its controller and what its keys are called. */
117
+ export function deviceFile(integration) {
118
+ const input = integration.input ?? {}, facts = {};
119
+ if (input.controller) facts.controller = input.controller;
120
+ facts.keys = Object.fromEntries(Object.entries(input.keys ?? {}).sort(([a], [b]) => (a < b ? -1 : 1)));
121
+ if (input.layout) facts.layout = input.layout;
122
+ return `// Written by Lamp for the device this copy of the game is on (${integration.id}); don't edit.\nexport default ${JSON.stringify(facts)};\n`;
123
+ }
124
+
125
+ /** Whether the app is installed as a game: a device may give a game more than an app (an Xbox, about five times the memory and its whole GPU). */
126
+ const isGame = (layout) => layout.game || readJSON(join(layout.folder, "capabilities.json"))?.game === true;
127
+
128
+ /** The app's icon, where it has one lamp can draw from: Lamp's own for the app, or a page's. */
129
+ function iconOf(layout) {
130
+ const candidates = [join(layout.folder, ".lamp", "AppIcon-square.png"), ...["apple-touch-icon.png", "icon.png", "favicon.png"].map((name) => join(layout.root, name))];
131
+ for (const file of candidates) {
132
+ try { const bytes = readFileSync(file); if (sizeOf(bytes)) return bytes; } catch {}
133
+ }
134
+ return null;
135
+ }
136
+
137
+ /**
138
+ * Makes the package of the page for a device, in lamp's folder: the page's files as they are now, with what a game is
139
+ * told of the device, in the device's host. Each one is a newer version than the last, so it replaces it.
140
+ */
141
+ export function packageFor(layout, device, integration = integrationOf(device.integration)) {
142
+ if (!takesPages(integration)) throw new Problem(`lamp doesn't put a page on a ${integration?.name ?? "device like that"} yet`);
143
+ let host, library;
144
+ try { host = readFileSync(join(HOST, WEB_HOST.program)); library = readFileSync(join(HOST, WEB_HOST.library)); }
145
+ catch { throw new Problem(`Lamp's web host for the ${integration.name} isn't beside this copy of lamp`); }
146
+ const files = pageFiles(layout, { device: deviceFile(integration) });
147
+ if (files.reduce((sum, [, bytes]) => sum + bytes.length, 0) > PACKAGE_LIMIT) throw new Problem(`the page is bigger than lamp sends to a device (${PACKAGE_LIMIT >> 30} GB)`);
148
+ const payload = [[WEB_HOST.program, host], [WEB_HOST.library, library], ...files.map(([path, bytes]) => [`${WEB_HOST.folder}/${path}`, bytes])];
149
+ const folder = buildFolder(layout, device);
150
+ mkdirSync(folder, { recursive: true });
151
+ const identity = { name: xboxName(layout), publisher: PUBLISHER, version: versionAfter(readJSON(join(folder, "identity.json"))?.version), architecture: "x64" };
152
+ const signer = keptSigner(join(devicesHome(), "msix")), icon = iconOf(layout);
153
+ const made = packageOf({ payload, displayName: nameOf(layout), identity, entry: "webHost", logo: (width, height) => tile(icon, width, height), signer });
154
+ writeFileSync(join(folder, "package.msix"), made);
155
+ writeFileSync(join(folder, "certificate.cer"), signer.certificate);
156
+ writeFileSync(join(folder, "identity.json"), JSON.stringify(identity));
157
+ return { folder, identity, files: files.length, bytes: made.length, game: isGame(layout) };
158
+ }
159
+
160
+ /** lamp's values for the bridge: the app's id, whether it's a game, and the names Windows gives its package. */
161
+ function valuesOf(layout, identity) {
162
+ const values = { appID: appID(layout), isGame: isGame(layout) ? "true" : "false" };
163
+ if (identity) { const names = namesOf(identity); values.packageFullName = names.fullName; values.appUserModelID = names.appUserModelID; }
164
+ return values;
165
+ }
166
+
167
+ /** The copy lamp last put on the device, by the record its install left; null when lamp never put one there. */
168
+ const installed = (layout, device) => readJSON(join(buildFolder(layout, device), "installed.json"));
169
+
170
+ // A device busy closing the app it's replacing can drop a connection, the upload's or the launch's just after it.
171
+ const dropped = (error) => error instanceof Away && ["ECONNRESET", "EPIPE", "ECONNABORTED"].includes(error.code);
172
+
173
+ /**
174
+ * Packages the page and puts it on the device: the copy there is ended, the new one installed and, unless `opens` is
175
+ * false, opened. `said` is told each stage as it starts.
176
+ */
177
+ export async function putOn(layout, device, { opens = true, said = () => {}, runner } = {}) {
178
+ runner ??= new Runner({ integration: integrationOf(device.integration), device });
179
+ const integration = runner.integration, bridge = integration.bridge ?? {};
180
+ if (!bridge.install) throw new Problem(`${device.name}'s integration doesn't say how an app goes on it`);
181
+ await reached(runner);
182
+ said(`Packaging ${nameOf(layout)} for ${device.name}…`);
183
+ const made = packageFor(layout, device, integration), folder = made.folder;
184
+ let waited = false;
185
+ runner.onWaiting = () => { if (!waited) said(`Waiting for ${device.name} to finish with it…`); waited = true; };
186
+ const values = valuesOf(layout, made.identity), files = { package: join(folder, "package.msix"), certificate: join(folder, "certificate.cer") };
187
+ // The copy on the device now is ended first: a device can fail to open a package installed over its running copy.
188
+ const before = installed(layout, device);
189
+ if (opens && bridge.stop && before) await runner.run(bridge.stop, { extra: valuesOf(layout, before) }).catch(() => {});
190
+ // A setting the install changes for itself (an Xbox's "treat apps as games") stays changed until the app has been
191
+ // opened: the console settles the package's type then.
192
+ const changed = [];
193
+ const stillInstalling = `The ${integration.name} is still finishing installing ${nameOf(layout)}. Try again in a moment.`;
194
+ said(`Installing it on ${device.name} (${(made.bytes / 1_000_000).toFixed(1)} MB)…`);
195
+ for (let tries = 0; ; tries++) {
196
+ try {
197
+ // Noted as on its way before the upload, and as the installed one only once the device took it: an install cut
198
+ // short may still land on the device, and a removal then names both.
199
+ writeFileSync(join(folder, "pending.json"), JSON.stringify(made.identity));
200
+ await runner.run(bridge.install, { extra: values, files, changed });
201
+ writeFileSync(join(folder, "installed.json"), JSON.stringify(made.identity));
202
+ rmSync(join(folder, "pending.json"), { force: true });
203
+ if (opens && bridge.launch?.length) {
204
+ said(`Opening it…`);
205
+ waited = false;
206
+ const opened = await runner.open(bridge.launch, bridge.running, { extra: values, changed });
207
+ if (!opened.opened) {
208
+ throw new Problem(opened.launched
209
+ ? `The ${integration.name} is still finishing installing ${nameOf(layout)}, or it closed as it opened. Try again in a moment.`
210
+ : stillInstalling + (opened.refused ? `\n${opened.refused}` : ""));
211
+ }
212
+ }
213
+ break;
214
+ } catch (error) {
215
+ if (dropped(error) && tries < 2) { await sleep(3000); continue; }
216
+ await runner.putBack(changed);
217
+ if (error instanceof StillWorking) throw new Problem(stillInstalling);
218
+ throw error;
219
+ }
220
+ }
221
+ await runner.putBack(changed);
222
+ return { ...made, opened: opens && !!bridge.launch?.length, name: nameOf(layout) };
223
+ }
224
+
225
+ /**
226
+ * The device's screen now, kept as a picture in lamp's folder, with whether the app is the one open there and what
227
+ * it last logged: the only word from the device of how the page runs on it.
228
+ */
229
+ export async function lookOn(layout, device, { runner } = {}) {
230
+ runner ??= new Runner({ integration: integrationOf(device.integration), device });
231
+ const bridge = runner.integration.bridge ?? {};
232
+ await reached(runner);
233
+ const mine = installed(layout, device), values = valuesOf(layout, mine);
234
+ const seen = { device: device.name, installed: !!mine, running: null, picture: null, log: null };
235
+ if (mine && bridge.running) seen.running = await openNow(runner, values);
236
+ if (bridge.look) {
237
+ const picture = (await runner.run(bridge.look, { extra: values })).picture;
238
+ if (picture?.length) {
239
+ const kind = picture.subarray(0, 3).equals(Buffer.from([0xff, 0xd8, 0xff])) ? "jpg" : "png";
240
+ seen.picture = join(buildFolder(layout, device), `look.${kind}`);
241
+ mkdirSync(dirname(seen.picture), { recursive: true });
242
+ writeFileSync(seen.picture, picture);
243
+ seen.size = kind === "png" ? sizeOf(picture) : null;
244
+ }
245
+ }
246
+ if (mine && bridge.log) seen.log = await runner.run(bridge.log, { extra: values }).then((outcome) => outcome.log ?? "", (error) => { if (error instanceof Problem) return null; throw error; });
247
+ return seen;
248
+ }
249
+
250
+ /** Whether the app is open on the device now, asked once: not whether it opens in a while. */
251
+ function openNow(runner, values) {
252
+ const once = runner.integration.bridge.running.map((action) => (action.http ? { http: { ...action.http, until: undefined } } : action));
253
+ return runner.run(once, { extra: values }).then(() => true, (error) => { if (error instanceof Problem && !(error instanceof Away)) return false; throw error; });
254
+ }
255
+
256
+ /** Ends the app on the device; false when lamp never put it there. */
257
+ export async function stopOn(layout, device, { runner } = {}) {
258
+ runner ??= new Runner({ integration: integrationOf(device.integration), device });
259
+ const bridge = runner.integration.bridge ?? {}, mine = installed(layout, device);
260
+ if (!mine || !bridge.stop) return false;
261
+ await reached(runner);
262
+ const values = valuesOf(layout, mine);
263
+ try {
264
+ await runner.run(bridge.stop, { extra: values });
265
+ } catch (error) {
266
+ // A device refuses to end an app that isn't open (an Xbox answers that it failed to): that's stopped already.
267
+ if (!(error instanceof Problem) || error instanceof Away || !bridge.running || (await openNow(runner, values))) throw error;
268
+ return true;
269
+ }
270
+ // A device goes on listing an app for a while after it's told to end it (an Xbox, about fifteen seconds): waited
271
+ // for, so a look right after says what's so.
272
+ for (let tries = 0; bridge.running && tries < 25 && (await openNow(runner, values)); tries++) await runner.pause(1000);
273
+ return true;
274
+ }
275
+
276
+ /** Takes the app off the device: the copy it took, and one that was on its way and may have landed. False when lamp never put it there. */
277
+ export async function removeFrom(layout, device, { runner } = {}) {
278
+ runner ??= new Runner({ integration: integrationOf(device.integration), device });
279
+ const bridge = runner.integration.bridge ?? {}, folder = buildFolder(layout, device);
280
+ if (!bridge.remove) throw new Problem(`${device.name}'s integration doesn't say how an app comes off it`);
281
+ if (!readJSON(join(folder, "installed.json")) && !readJSON(join(folder, "pending.json"))) return false;
282
+ await reached(runner);
283
+ const asked = new Set();
284
+ let removed = false;
285
+ for (const record of ["installed.json", "pending.json"]) {
286
+ const identity = readJSON(join(folder, record));
287
+ if (!identity || asked.has(namesOf(identity).fullName)) continue;
288
+ asked.add(namesOf(identity).fullName);
289
+ const values = valuesOf(layout, identity);
290
+ if (bridge.stop) await runner.run(bridge.stop, { extra: values }).catch(() => {});
291
+ // The copy that was only on its way may never have landed: the device saying so is no failure.
292
+ if (record === "installed.json") await runner.run(bridge.remove, { extra: values });
293
+ else await runner.run(bridge.remove, { extra: values }).catch(() => {});
294
+ removed = true;
295
+ rmSync(join(folder, record), { force: true });
296
+ }
297
+ return removed;
298
+ }
package/cli/png.mjs ADDED
@@ -0,0 +1,184 @@
1
+ // Just enough PNG for the pictures lamp makes itself: an app's icon on the tile a device shows it on, at the sizes the
2
+ // device's package names (`DeviceSupport.iconPNG` in Lamp's app, which draws the same tile with AppKit).
3
+
4
+ import { deflateSync, inflateSync } from "node:zlib";
5
+
6
+ const SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
7
+ const CRC = Array.from({ length: 256 }, (_, n) => { let c = n; for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1; return c >>> 0; });
8
+ function crc32(bytes) {
9
+ let c = 0xffffffff;
10
+ for (let i = 0; i < bytes.length; i++) c = CRC[(c ^ bytes[i]) & 0xff] ^ (c >>> 8);
11
+ return (c ^ 0xffffffff) >>> 0;
12
+ }
13
+
14
+ function chunk(type, data) {
15
+ const head = Buffer.alloc(8), sum = Buffer.alloc(4);
16
+ head.writeUInt32BE(data.length, 0);
17
+ head.write(type, 4, "latin1");
18
+ sum.writeUInt32BE(crc32(Buffer.concat([head.subarray(4), data])), 0);
19
+ return Buffer.concat([head, data, sum]);
20
+ }
21
+
22
+ /** A PNG of these pixels (four bytes each: red, green, blue, alpha). */
23
+ export function encode(width, height, rgba) {
24
+ const header = Buffer.alloc(13);
25
+ header.writeUInt32BE(width, 0);
26
+ header.writeUInt32BE(height, 4);
27
+ header[8] = 8; // eight bits a channel
28
+ header[9] = 6; // color with alpha
29
+ const rows = Buffer.alloc((width * 4 + 1) * height);
30
+ for (let y = 0; y < height; y++) rgba.copy(rows, y * (width * 4 + 1) + 1, y * width * 4, (y + 1) * width * 4);
31
+ return Buffer.concat([SIGNATURE, chunk("IHDR", header), chunk("IDAT", deflateSync(rows)), chunk("IEND", Buffer.alloc(0))]);
32
+ }
33
+
34
+ /**
35
+ * A PNG's pixels (four bytes each), or null for one this doesn't read: only what an icon is saved as, eight bits a
36
+ * channel and not interlaced.
37
+ */
38
+ export function decode(bytes) {
39
+ try {
40
+ if (bytes.length < 33 || !bytes.subarray(0, 8).equals(SIGNATURE)) return null;
41
+ let width = 0, height = 0, kind = 0, palette = null, clear = null;
42
+ const packed = [];
43
+ for (let at = 8; at + 12 <= bytes.length;) {
44
+ const length = bytes.readUInt32BE(at), type = bytes.toString("latin1", at + 4, at + 8), data = bytes.subarray(at + 8, at + 8 + length);
45
+ if (type === "IHDR") {
46
+ width = data.readUInt32BE(0); height = data.readUInt32BE(4); kind = data[9];
47
+ if (data[8] !== 8 || data[12] !== 0 || ![0, 2, 3, 4, 6].includes(kind)) return null;
48
+ } else if (type === "PLTE") palette = data;
49
+ else if (type === "tRNS") clear = data;
50
+ else if (type === "IDAT") packed.push(data);
51
+ else if (type === "IEND") break;
52
+ at += 12 + length;
53
+ }
54
+ if (!width || !height || width > 8192 || height > 8192) return null;
55
+ const channels = { 0: 1, 2: 3, 3: 1, 4: 2, 6: 4 }[kind], stride = width * channels;
56
+ const raw = inflateSync(Buffer.concat(packed));
57
+ if (raw.length < (stride + 1) * height) return null;
58
+ const lines = Buffer.alloc(stride * height);
59
+ for (let y = 0; y < height; y++) {
60
+ const filter = raw[y * (stride + 1)], from = y * (stride + 1) + 1, to = y * stride;
61
+ for (let x = 0; x < stride; x++) {
62
+ const left = x >= channels ? lines[to + x - channels] : 0, up = y ? lines[to + x - stride] : 0;
63
+ const corner = x >= channels && y ? lines[to + x - stride - channels] : 0;
64
+ let guess = 0;
65
+ if (filter === 1) guess = left;
66
+ else if (filter === 2) guess = up;
67
+ else if (filter === 3) guess = (left + up) >> 1;
68
+ else if (filter === 4) {
69
+ const p = left + up - corner, a = Math.abs(p - left), b = Math.abs(p - up), c = Math.abs(p - corner);
70
+ guess = a <= b && a <= c ? left : b <= c ? up : corner;
71
+ }
72
+ lines[to + x] = (raw[from + x] + guess) & 0xff;
73
+ }
74
+ }
75
+ const rgba = Buffer.alloc(width * height * 4);
76
+ for (let i = 0; i < width * height; i++) {
77
+ const at = i * channels;
78
+ let r, g, b, a = 255;
79
+ if (kind === 0) r = g = b = lines[at];
80
+ else if (kind === 4) { r = g = b = lines[at]; a = lines[at + 1]; }
81
+ else if (kind === 2) { r = lines[at]; g = lines[at + 1]; b = lines[at + 2]; }
82
+ else if (kind === 6) { r = lines[at]; g = lines[at + 1]; b = lines[at + 2]; a = lines[at + 3]; }
83
+ else {
84
+ if (!palette) return null;
85
+ const index = lines[at];
86
+ r = palette[index * 3]; g = palette[index * 3 + 1]; b = palette[index * 3 + 2];
87
+ a = clear && index < clear.length ? clear[index] : 255;
88
+ }
89
+ rgba[i * 4] = r; rgba[i * 4 + 1] = g; rgba[i * 4 + 2] = b; rgba[i * 4 + 3] = a;
90
+ }
91
+ return { width, height, rgba };
92
+ } catch { return null; }
93
+ }
94
+
95
+ /** A PNG's size in pixels, read from its header; null when it isn't one. */
96
+ export function sizeOf(bytes) {
97
+ if (bytes.length < 24 || !bytes.subarray(0, 8).equals(SIGNATURE)) return null;
98
+ return { width: bytes.readUInt32BE(16), height: bytes.readUInt32BE(20) };
99
+ }
100
+
101
+ /**
102
+ * The app's icon as a square of that many pixels, clear where the icon is: what a phone's home screen shows. Null for
103
+ * no icon, or one this can't read.
104
+ */
105
+ export function scaled(icon, side) {
106
+ const picture = icon && decode(icon);
107
+ if (!picture) return null;
108
+ const out = Buffer.alloc(side * side * 4), across = picture.width / side, down = picture.height / side;
109
+ for (let y = 0; y < side; y++) {
110
+ for (let x = 0; x < side; x++) {
111
+ const x0 = Math.floor(x * across), x1 = Math.max(x0 + 1, Math.min(picture.width, Math.ceil((x + 1) * across)));
112
+ const y0 = Math.floor(y * down), y1 = Math.max(y0 + 1, Math.min(picture.height, Math.ceil((y + 1) * down)));
113
+ let r = 0, g = 0, b = 0, a = 0;
114
+ for (let sy = y0; sy < y1; sy++) {
115
+ for (let sx = x0; sx < x1; sx++) {
116
+ const at = (Math.min(sy, picture.height - 1) * picture.width + Math.min(sx, picture.width - 1)) * 4, alpha = picture.rgba[at + 3];
117
+ r += picture.rgba[at] * alpha; g += picture.rgba[at + 1] * alpha; b += picture.rgba[at + 2] * alpha; a += alpha;
118
+ }
119
+ }
120
+ if (!a) continue;
121
+ const at = (y * side + x) * 4;
122
+ out[at] = Math.round(r / a); out[at + 1] = Math.round(g / a); out[at + 2] = Math.round(b / a);
123
+ out[at + 3] = Math.round(a / ((x1 - x0) * (y1 - y0)));
124
+ }
125
+ }
126
+ return encode(side, side, out);
127
+ }
128
+
129
+ /** A PNG made `width` pixels wide, its height in proportion; null for one this can't read. */
130
+ export function resized(bytes, width) {
131
+ const picture = decode(bytes);
132
+ if (!picture) return null;
133
+ width = Math.max(1, Math.round(width));
134
+ const height = Math.max(1, Math.round((picture.height * width) / picture.width)), out = Buffer.alloc(width * height * 4);
135
+ const across = picture.width / width, down = picture.height / height;
136
+ for (let y = 0; y < height; y++) {
137
+ for (let x = 0; x < width; x++) {
138
+ const x0 = Math.floor(x * across), x1 = Math.max(x0 + 1, Math.min(picture.width, Math.ceil((x + 1) * across)));
139
+ const y0 = Math.floor(y * down), y1 = Math.max(y0 + 1, Math.min(picture.height, Math.ceil((y + 1) * down)));
140
+ const sum = [0, 0, 0, 0];
141
+ for (let sy = y0; sy < y1; sy++) for (let sx = x0; sx < x1; sx++) { const at = (sy * picture.width + sx) * 4; for (let c = 0; c < 4; c++) sum[c] += picture.rgba[at + c]; }
142
+ const count = (x1 - x0) * (y1 - y0), at = (y * width + x) * 4;
143
+ for (let c = 0; c < 4; c++) out[at + c] = Math.round(sum[c] / count);
144
+ }
145
+ }
146
+ return encode(width, height, out);
147
+ }
148
+
149
+ // The tile's color: Lamp's dark blue, the same one the package's manifest names for the tile behind it.
150
+ const TILE = [27, 27, 58];
151
+
152
+ /**
153
+ * The app's icon centered on its tile's color at a logo's size, or the color alone when the app has no icon (or one
154
+ * this can't read): a device's package names these files, and shows nothing in their place without them.
155
+ */
156
+ export function tile(icon, width, height) {
157
+ const out = Buffer.alloc(width * height * 4);
158
+ for (let i = 0; i < width * height; i++) { out[i * 4] = TILE[0]; out[i * 4 + 1] = TILE[1]; out[i * 4 + 2] = TILE[2]; out[i * 4 + 3] = 255; }
159
+ const picture = icon && decode(icon);
160
+ if (picture) {
161
+ const side = Math.round(Math.min(width, height) * 0.8), left = Math.round((width - side) / 2), top = Math.round((height - side) / 2);
162
+ const across = picture.width / side, down = picture.height / side;
163
+ for (let y = 0; y < side; y++) {
164
+ for (let x = 0; x < side; x++) {
165
+ // Each pixel is the average of the part of the icon it covers, so a large icon made small stays smooth.
166
+ const x0 = Math.floor(x * across), x1 = Math.max(x0 + 1, Math.min(picture.width, Math.ceil((x + 1) * across)));
167
+ const y0 = Math.floor(y * down), y1 = Math.max(y0 + 1, Math.min(picture.height, Math.ceil((y + 1) * down)));
168
+ let r = 0, g = 0, b = 0, a = 0;
169
+ for (let sy = y0; sy < y1; sy++) {
170
+ for (let sx = x0; sx < x1; sx++) {
171
+ const at = (Math.min(sy, picture.height - 1) * picture.width + Math.min(sx, picture.width - 1)) * 4, alpha = picture.rgba[at + 3];
172
+ r += picture.rgba[at] * alpha; g += picture.rgba[at + 1] * alpha; b += picture.rgba[at + 2] * alpha; a += alpha;
173
+ }
174
+ }
175
+ if (!a) continue;
176
+ const cover = a / ((x1 - x0) * (y1 - y0)) / 255, at = ((top + y) * width + left + x) * 4;
177
+ out[at] = Math.round((r / a) * cover + TILE[0] * (1 - cover));
178
+ out[at + 1] = Math.round((g / a) * cover + TILE[1] * (1 - cover));
179
+ out[at + 2] = Math.round((b / a) * cover + TILE[2] * (1 - cover));
180
+ }
181
+ }
182
+ }
183
+ return encode(width, height, out);
184
+ }