diff --git a/animation/static_no_classes/.gitignore b/animation/static_no_classes/.gitignore new file mode 100644 index 0000000..829b1c7 --- /dev/null +++ b/animation/static_no_classes/.gitignore @@ -0,0 +1,15 @@ +# Generated files +node_modules +output +dist + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/animation/static_no_classes/package-lock.json b/animation/static_no_classes/package-lock.json new file mode 100644 index 0000000..0de87c1 --- /dev/null +++ b/animation/static_no_classes/package-lock.json @@ -0,0 +1,1041 @@ +{ + "name": "value_semantics", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "value_semantics", + "version": "0.0.0", + "dependencies": { + "@motion-canvas/2d": "^3.11.0", + "@motion-canvas/core": "^3.11.0", + "@motion-canvas/ffmpeg": "^1.1.1" + }, + "devDependencies": { + "@motion-canvas/ui": "^3.11.0", + "@motion-canvas/vite-plugin": "^3.11.0", + "typescript": "^4.9.5", + "vite": "^4.1.4" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@ffmpeg-installer/darwin-arm64": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz", + "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffmpeg-installer/darwin-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz", + "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffmpeg-installer/ffmpeg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz", + "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==", + "optionalDependencies": { + "@ffmpeg-installer/darwin-arm64": "4.1.5", + "@ffmpeg-installer/darwin-x64": "4.1.0", + "@ffmpeg-installer/linux-arm": "4.1.3", + "@ffmpeg-installer/linux-arm64": "4.1.4", + "@ffmpeg-installer/linux-ia32": "4.1.0", + "@ffmpeg-installer/linux-x64": "4.1.0", + "@ffmpeg-installer/win32-ia32": "4.1.0", + "@ffmpeg-installer/win32-x64": "4.1.0" + } + }, + "node_modules/@ffmpeg-installer/linux-arm": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz", + "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==", + "cpu": [ + "arm" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-arm64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz", + "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-ia32": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz", + "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==", + "cpu": [ + "ia32" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz", + "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/win32-ia32": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz", + "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ffmpeg-installer/win32-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz", + "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ffprobe-installer/darwin-arm64": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-arm64/-/darwin-arm64-5.0.1.tgz", + "integrity": "sha512-vwNCNjokH8hfkbl6m95zICHwkSzhEvDC3GVBcUp5HX8+4wsX10SP3B+bGur7XUzTIZ4cQpgJmEIAx6TUwRepMg==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffprobe-installer/darwin-x64": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/darwin-x64/-/darwin-x64-5.1.0.tgz", + "integrity": "sha512-J+YGscZMpQclFg31O4cfVRGmDpkVsQ2fZujoUdMAAYcP0NtqpC49Hs3SWJpBdsGB4VeqOt5TTm1vSZQzs1NkhA==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffprobe-installer/ffprobe": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/ffprobe/-/ffprobe-2.1.2.tgz", + "integrity": "sha512-ZNvwk4f2magF42Zji2Ese16SMj9BS7Fui4kRjg6gTYTxY3gWZNpg85n4MIfQyI9nimHg4x/gT6FVkp/bBDuBwg==", + "engines": { + "node": ">=14.21.2" + }, + "optionalDependencies": { + "@ffprobe-installer/darwin-arm64": "5.0.1", + "@ffprobe-installer/darwin-x64": "5.1.0", + "@ffprobe-installer/linux-arm": "5.2.0", + "@ffprobe-installer/linux-arm64": "5.2.0", + "@ffprobe-installer/linux-ia32": "5.2.0", + "@ffprobe-installer/linux-x64": "5.2.0", + "@ffprobe-installer/win32-ia32": "5.1.0", + "@ffprobe-installer/win32-x64": "5.1.0" + } + }, + "node_modules/@ffprobe-installer/linux-arm": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm/-/linux-arm-5.2.0.tgz", + "integrity": "sha512-PF5HqEhCY7WTWHtLDYbA/+rLS+rhslWvyBlAG1Fk8VzVlnRdl93o6hy7DE2kJgxWQbFaR3ZktPQGEzfkrmQHvQ==", + "cpu": [ + "arm" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffprobe-installer/linux-arm64": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-arm64/-/linux-arm64-5.2.0.tgz", + "integrity": "sha512-X1VvWtlLs6ScP73biVLuHD5ohKJKsMTa0vafCESOen4mOoNeLAYbxOVxDWAdFz9cpZgRiloFj5QD6nDj8E28yQ==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffprobe-installer/linux-ia32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-ia32/-/linux-ia32-5.2.0.tgz", + "integrity": "sha512-TFVK5sasXyXhbIG7LtPRDmtkrkOsInwKcL43iEvEw+D9vCS2rc//mn9/0Q+BR0UoJEiMK4+ApYr/3LLVUBPOCQ==", + "cpu": [ + "ia32" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffprobe-installer/linux-x64": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/linux-x64/-/linux-x64-5.2.0.tgz", + "integrity": "sha512-D3UeqTLYPNs7pBWPLUYGehPdRVqU8eACox4OZy3pZUZatxye2YKlvBwEfaLdL1v2Z4FOAlLUhms0kY8m8kqSRA==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffprobe-installer/win32-ia32": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-ia32/-/win32-ia32-5.1.0.tgz", + "integrity": "sha512-5O3vOoNRxmut0/Nu9vSazTdSHasrr+zPT2B3Hm7kjmO3QVFcIfVImS6ReQnZeSy8JPJOqXts5kX5x/3KOX54XQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ffprobe-installer/win32-x64": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@ffprobe-installer/win32-x64/-/win32-x64-5.1.0.tgz", + "integrity": "sha512-jMGYeAgkrdn4e2vvYt/qakgHRE3CPju4bn5TmdPfoAm1BlX1mY9cyMd8gf5vSzI8gH8Zq5WQAyAkmekX/8TSTg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@motion-canvas/2d": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz", + "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==", + "dependencies": { + "@motion-canvas/core": "^3.11.0", + "code-fns": "^0.8.2", + "mathjax-full": "^3.2.2", + "parse-svg-path": "^0.1.2" + } + }, + "node_modules/@motion-canvas/core": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz", + "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==", + "dependencies": { + "@types/chroma-js": "^2.1.4", + "chroma-js": "^2.4.2" + }, + "peerDependencies": { + "vite": "^4.1.4" + } + }, + "node_modules/@motion-canvas/ffmpeg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@motion-canvas/ffmpeg/-/ffmpeg-1.1.1.tgz", + "integrity": "sha512-w2d7oFfR3hYHXeYtFGoHp6goY+vVL0LoZ2h1b/veTH5KvE7jrLp2Kl/XPHsYJ5ZDRHUT0Nhl05DBLdXYqdSqgg==", + "dependencies": { + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "@ffprobe-installer/ffprobe": "^2.0.0", + "fluent-ffmpeg": "^2.1.2" + }, + "peerDependencies": { + "@motion-canvas/core": "^3.7.0", + "@motion-canvas/vite-plugin": "^3.7.0", + "vite": "4.x" + } + }, + "node_modules/@motion-canvas/ui": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz", + "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==", + "dev": true, + "dependencies": { + "@motion-canvas/core": "^3.11.0" + } + }, + "node_modules/@motion-canvas/vite-plugin": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz", + "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==", + "dependencies": { + "follow-redirects": "^1.15.2", + "mime-types": "^2.1.35" + }, + "peerDependencies": { + "vite": "4.x" + } + }, + "node_modules/@types/chroma-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.0.tgz", + "integrity": "sha512-JklMxityrwjBTjGY2anH8JaTx3yjRU3/sEHSblLH1ba5lqcSh1LnImXJZO5peJfXyqKYWjHTGy4s5Wz++hARrw==" + }, + "node_modules/@types/hast": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", + "integrity": "sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" + }, + "node_modules/@wooorm/starry-night": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@wooorm/starry-night/-/starry-night-1.7.0.tgz", + "integrity": "sha512-ktO0nkddrovIoNW2jAUT+Cdd9n1bWjy1Ir4CdcmgTaT6E94HLlQfu7Yv62falclBEwvsuVp3bSBw23wtta1fNw==", + "dependencies": { + "@types/hast": "^2.0.0", + "import-meta-resolve": "^2.0.0", + "vscode-oniguruma": "^1.0.0", + "vscode-textmate": "^9.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" + }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, + "node_modules/code-fns": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/code-fns/-/code-fns-0.8.2.tgz", + "integrity": "sha512-3VVeq3cnWxWiWKFLsVo+XWsOXBSW2gAx2uv0ViETLNmNuygEPHlCeDAv/Zy7xXqPgXtgLZyvIJZmx+ojTgOIGA==", + "dependencies": { + "@wooorm/starry-night": "^1.2.0" + } + }, + "node_modules/commander": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz", + "integrity": "sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/esbuild": { + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" + } + }, + "node_modules/esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/fluent-ffmpeg": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz", + "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==", + "dependencies": { + "async": ">=0.2.9", + "which": "^1.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/import-meta-resolve": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz", + "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/mathjax-full": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz", + "integrity": "sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w==", + "dependencies": { + "esm": "^3.2.25", + "mhchemparser": "^4.1.0", + "mj-context-menu": "^0.6.1", + "speech-rule-engine": "^4.0.6" + } + }, + "node_modules/mhchemparser": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.1.1.tgz", + "integrity": "sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA==" + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mj-context-menu": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz", + "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speech-rule-engine": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz", + "integrity": "sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g==", + "dependencies": { + "commander": "9.2.0", + "wicked-good-xpath": "1.3.0", + "xmldom-sre": "0.1.31" + }, + "bin": { + "sre": "bin/sre" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/vite": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", + "dependencies": { + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" + }, + "node_modules/vscode-textmate": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-9.0.0.tgz", + "integrity": "sha512-Cl65diFGxz7gpwbav10HqiY/eVYTO1sjQpmRmV991Bj7wAoOAjGQ97PpQcXorDE2Uc4hnGWLY17xme+5t6MlSg==" + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wicked-good-xpath": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz", + "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==" + }, + "node_modules/xmldom-sre": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom-sre/-/xmldom-sre-0.1.31.tgz", + "integrity": "sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==", + "engines": { + "node": ">=0.1" + } + } + } +} diff --git a/animation/static_no_classes/package.json b/animation/static_no_classes/package.json new file mode 100644 index 0000000..d608000 --- /dev/null +++ b/animation/static_no_classes/package.json @@ -0,0 +1,20 @@ +{ + "name": "value_semantics", + "private": true, + "version": "0.0.0", + "scripts": { + "serve": "vite", + "build": "tsc && vite build" + }, + "dependencies": { + "@motion-canvas/2d": "^3.11.0", + "@motion-canvas/core": "^3.11.0", + "@motion-canvas/ffmpeg": "^1.1.1" + }, + "devDependencies": { + "@motion-canvas/ui": "^3.11.0", + "@motion-canvas/vite-plugin": "^3.11.0", + "typescript": "^4.9.5", + "vite": "^4.1.4" + } +} diff --git a/animation/static_no_classes/src/global.css b/animation/static_no_classes/src/global.css new file mode 100644 index 0000000..84cea14 --- /dev/null +++ b/animation/static_no_classes/src/global.css @@ -0,0 +1 @@ +@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&display=swap'); diff --git a/animation/static_no_classes/src/motion-canvas.d.ts b/animation/static_no_classes/src/motion-canvas.d.ts new file mode 100644 index 0000000..067c6a4 --- /dev/null +++ b/animation/static_no_classes/src/motion-canvas.d.ts @@ -0,0 +1 @@ +/// diff --git a/animation/static_no_classes/src/project.meta b/animation/static_no_classes/src/project.meta new file mode 100644 index 0000000..7579bae --- /dev/null +++ b/animation/static_no_classes/src/project.meta @@ -0,0 +1,31 @@ +{ + "version": 0, + "shared": { + "background": "rgb(10,20,30)", + "range": [ + 0, + null + ], + "size": { + "x": 1920, + "y": 1080 + }, + "audioOffset": 0 + }, + "preview": { + "fps": 30, + "resolutionScale": 1 + }, + "rendering": { + "fps": 30, + "resolutionScale": 2, + "colorSpace": "srgb", + "exporter": { + "name": "@motion-canvas/ffmpeg", + "options": { + "fastStart": true, + "includeAudio": true + } + } + } +} \ No newline at end of file diff --git a/animation/static_no_classes/src/project.ts b/animation/static_no_classes/src/project.ts new file mode 100644 index 0000000..4d3565c --- /dev/null +++ b/animation/static_no_classes/src/project.ts @@ -0,0 +1,9 @@ +import {makeProject} from '@motion-canvas/core'; + +import static_vis from './scenes/static_vis?scene'; + +import './global.css'; // <- import the css + +export default makeProject({ + scenes: [static_vis], +}); diff --git a/animation/static_no_classes/src/scenes/static_vis.meta b/animation/static_no_classes/src/scenes/static_vis.meta new file mode 100644 index 0000000..5964ccf --- /dev/null +++ b/animation/static_no_classes/src/scenes/static_vis.meta @@ -0,0 +1,5 @@ +{ + "version": 0, + "timeEvents": [], + "seed": 2078473243 +} \ No newline at end of file diff --git a/animation/static_no_classes/src/scenes/static_vis.tsx b/animation/static_no_classes/src/scenes/static_vis.tsx new file mode 100644 index 0000000..c7c6aba --- /dev/null +++ b/animation/static_no_classes/src/scenes/static_vis.tsx @@ -0,0 +1,345 @@ +import { makeScene2D } from '@motion-canvas/2d/lib/scenes'; +import { Node, Txt, Rect, Grid, Line } from '@motion-canvas/2d/lib/components'; +import { all, waitFor } from '@motion-canvas/core/lib/flow'; +import { createRef } from '@motion-canvas/core/lib/utils'; +import { createSignal } from '@motion-canvas/core/lib/signals'; +import { + CodeBlock, + edit, + insert, + lines, + word, + remove, + CodeModification, +} from '@motion-canvas/2d/lib/components/CodeBlock'; +import { DEFAULT } from '@motion-canvas/core/lib/signals'; +import { BBox, Vector2 } from '@motion-canvas/core/lib/types'; + +const RED = '#ff6470'; +const GREEN = '#99A44A'; +const BLUE = '#68AADD'; +const WHITE = '#FFFFFF'; + +export default makeScene2D(function* (view: { add: (arg0: Node) => void; }) { + const left_half = createRef(); + const all_text_node = createRef(); + + const program_lifetime = createRef(); + const program_text = createRef(); + + const main_lifetime = createRef(); + const main_text = createRef(); + + const foo_lifetime = createRef(); + const foo_text = createRef(); + + const foo_lifetime_2 = createRef(); + const foo_text_2 = createRef(); + + const value_name = createRef(); + const value_lifetime = createRef(); + + const const_name = createRef(); + const const_lifetime = createRef(); + + const right_half = createRef(); + const code_ref = createRef(); + + const text_offset = 12 + const line_offset = 100 + const x_offset = 80 + + view.add( + <> + + + program + + + + main() + + + Foo() + + + Foo() + + + local_value + + + + + kValue + + + + + + + , + ); + + const duration = 1.5 + + const store = (...args: [TemplateStringsArray, ...any]) => args; + + function to_string([strings, ...values]: [TemplateStringsArray, ...any]): string { + return strings.reduce((acc, str, i) => { + const value = values[i] ?? ''; + return acc + str + value; + }, ' '); + } + + function append( + template_1: TemplateStringsArray, args_1: string[], + template_2: TemplateStringsArray, args_2: string[]): [TemplateStringsArray, ...string[]] { + let new_template = Array.from(template_1); + let new_args: Array = args_1; + new_template[template_1.length - 1] += template_2[0] + new_template = new_template.concat(template_2.slice(1)) + new_args = new_args.concat(args_2) + return [new_template as unknown as TemplateStringsArray, ...new_args]; + } + + const isCodeModification = (code: any): code is CodeModification => (code as CodeModification).from !== undefined; + + function simplify( + args_in: [TemplateStringsArray, ...any]): [TemplateStringsArray, ...string[]] { + const template = args_in[0] + const args = args_in.slice(1) + if (args.every((arg) => (typeof (arg) == "string") || isCodeModification(arg))) { + return args_in + } + let new_template: Array = []; + let new_args: Array = []; + let concatenate = false; + for (let i = 0; i <= args.length; i++) { + if (concatenate) { + concatenate = false; + new_template[new_template.length - 1] += template[i]; + } else { + new_template.push(template[i]); + } + if (i == args.length) { break; } + if (typeof (args[i]) == "string" || isCodeModification(args[i])) { + new_args.push(args[i]) + continue; + } + let simplified_arg = simplify(args[i]); + let simplified_template = simplified_arg[0] + let simplified_args = simplified_arg.slice(1) + const appended = append( + new_template as unknown as TemplateStringsArray, + new_args, + simplified_template, + simplified_args as string[]); + new_template = Array.from(appended[0]) + new_args = appended.slice(1) + concatenate = true; + } + return [new_template as unknown as TemplateStringsArray, ...new_args] + } + + const const_value_code = ` + namespace { + constexpr int kValue{42}; + } // namespace + ` + + const foo_func = (init_value: any = ``, static_keyword: any = ``) => store` + void Foo() { + ${static_keyword}int local_value{${init_value}}; + } + ` + + const foo_call = `\n Foo();` + const foo_call_double = `\n Foo();\n Foo();` + + const code = (func_code: any = ``, func_call: any = ``, constant_def: any = ``) => store` +${constant_def}${func_code} + int main() {${func_call} + return 0; + } + ` + + yield* code_ref().edit(duration, false)(...simplify(code(foo_func(), foo_call))); + yield* waitFor(duration / 2); + yield* all( + program_lifetime().opacity(1.0, 0), + program_lifetime().end(0.0, 0).to(1.0, duration / 2), + program_text().opacity(0.0, 0).to(1.0, duration / 2), + ); + yield* all( + main_lifetime().opacity(1.0, 0), + main_lifetime().end(0.0, 0).to(1.0, duration / 2), + main_text().opacity(0.0, 0).to(1.0, duration / 2), + ); + yield* all( + foo_lifetime().opacity(1.0, 0), + foo_lifetime().end(0.0, 0).to(1.0, duration / 2), + foo_text().opacity(0.0, 0).to(1.0, duration / 2), + ); + yield* waitFor(duration); + + yield* all( + code_ref().selection(lines(2), duration / 2), + value_lifetime().opacity(0.0, 0).to(1.0, duration / 2), + value_lifetime().scale.x(0.0, 0).to(1.0, duration / 2), + ); + yield* waitFor(duration); + + yield* code_ref().selection(DEFAULT, duration / 2); + yield* code_ref().edit(duration, false)(...simplify(code(foo_func(edit('', 'kValue')), foo_call, edit('', const_value_code)))); + yield* all( + all_text_node().y(0.0, 0).to(-120, duration / 2), + ); + yield* all( + const_lifetime().opacity(0.0, 0).to(1.0, duration / 2), + const_lifetime().scale.x(0.0, 0).to(1.0, duration / 2), + ); + yield* waitFor(duration); + yield* all( + code_ref().edit(duration, true)(...simplify(code(foo_func('kValue', edit('', 'static ')), foo_call, const_value_code))), + value_lifetime().width(380, duration / 2).to(550, duration / 2), + value_lifetime().fill(GREEN, duration), + ); + + yield* waitFor(duration); + yield* code_ref().selection(DEFAULT, 0); + yield* waitFor(duration); + + yield* all( + code_ref().edit(duration, false)(...simplify(code(foo_func('kValue', 'static '), edit(foo_call, foo_call_double), const_value_code))), + foo_lifetime().end(1.0, 0).to(0.5, duration), + foo_lifetime_2().end(0.0, 0).to(0.0, duration/2).to(0.6, duration / 2), + foo_lifetime_2().opacity(1.0), + foo_text_2().opacity(0.0, 0).to(1.0, duration / 2), + ); + yield* waitFor(duration / 2); + + yield* all( + code_ref().selection([...lines(6), ...lines(10, 11)], duration / 2), + ); + yield* waitFor(duration); + + // yield* waitFor(2.0); + // yield* a_ref().edit(1.0, false)`${insert(object_code)}`; + // yield* all( + // grid_ref().height(0, 0.0).to(250, 0.5), + // grid_ref().width(0, 0.0).to(1920, 0.5), + // grid_ref().opacity(1.0, 0.1), + // ); + // yield* all( + // data_rect_ref().opacity(0.5, 1.0), + // line_1().end(1, 1.0), + // gray_line_ref().opacity(1.0, 0.5), + // gray_code_ref().opacity(1.0, 0.5), + // ); + // yield* b_ref().edit(1.0, false)`${insert(member_object_code)}`; + // yield* waitFor(1.0); + // yield* data_rect_ref().scale(1.2, 1.0); + // yield* data_rect_ref().position.x(-20, 0.2).to(20, 0.2).to(-20, 0.2).to(20, 0.2).to(0, 0.2); + // yield* data_rect_ref().scale(1.0, 0.5); + // yield* waitFor(1.0); + // yield* line_2().end(1, 1.5); + // yield* waitFor(1.0); + // yield* all( + // data_rect_ref().opacity(0.5, 1.0), + // line_1().arrowSize(0, 0.5), + // line_1().end(0, 1.0), + // a_ref().edit(1.5, false)`Data* a${insert(' = nullptr')};`, + // ); + + yield* waitFor(3.0); + +}); diff --git a/animation/static_no_classes/tsconfig.json b/animation/static_no_classes/tsconfig.json new file mode 100644 index 0000000..789b7d1 --- /dev/null +++ b/animation/static_no_classes/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@motion-canvas/2d/tsconfig.project.json", + "compilerOptions": { + "baseUrl": "src" + }, + "include": ["src"] +} diff --git a/animation/static_no_classes/vite.config.ts b/animation/static_no_classes/vite.config.ts new file mode 100644 index 0000000..a463c29 --- /dev/null +++ b/animation/static_no_classes/vite.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite'; +import motionCanvas from '@motion-canvas/vite-plugin'; +import ffmpeg from '@motion-canvas/ffmpeg'; + +export default defineConfig({ + plugins: [ + motionCanvas(), + ffmpeg() + ], +}); diff --git a/animation/value_semantics/package-lock.json b/animation/value_semantics/package-lock.json index 9ebec27..cdefbbe 100644 --- a/animation/value_semantics/package-lock.json +++ b/animation/value_semantics/package-lock.json @@ -8,20 +8,20 @@ "name": "value_semantics", "version": "0.0.0", "dependencies": { - "@motion-canvas/2d": "^3.4.0", - "@motion-canvas/core": "^3.4.0" + "@motion-canvas/2d": "^3.11.0", + "@motion-canvas/core": "^3.11.0" }, "devDependencies": { - "@motion-canvas/ui": "^3.4.0", - "@motion-canvas/vite-plugin": "^3.4.0", + "@motion-canvas/ui": "^3.11.0", + "@motion-canvas/vite-plugin": "^3.11.0", "typescript": "^4.9.5", "vite": "^4.1.4" } }, "node_modules/@esbuild/android-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.15.tgz", - "integrity": "sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", "cpu": [ "arm" ], @@ -34,9 +34,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz", - "integrity": "sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", "cpu": [ "arm64" ], @@ -49,9 +49,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.15.tgz", - "integrity": "sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", "cpu": [ "x64" ], @@ -64,9 +64,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz", - "integrity": "sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", "cpu": [ "arm64" ], @@ -79,9 +79,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz", - "integrity": "sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", "cpu": [ "x64" ], @@ -94,9 +94,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz", - "integrity": "sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", "cpu": [ "arm64" ], @@ -109,9 +109,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz", - "integrity": "sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", "cpu": [ "x64" ], @@ -124,9 +124,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz", - "integrity": "sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", "cpu": [ "arm" ], @@ -139,9 +139,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz", - "integrity": "sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", "cpu": [ "arm64" ], @@ -154,9 +154,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz", - "integrity": "sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", "cpu": [ "ia32" ], @@ -169,9 +169,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz", - "integrity": "sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", "cpu": [ "loong64" ], @@ -184,9 +184,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz", - "integrity": "sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", "cpu": [ "mips64el" ], @@ -199,9 +199,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz", - "integrity": "sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", "cpu": [ "ppc64" ], @@ -214,9 +214,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz", - "integrity": "sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", "cpu": [ "riscv64" ], @@ -229,9 +229,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz", - "integrity": "sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", "cpu": [ "s390x" ], @@ -244,9 +244,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz", - "integrity": "sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", "cpu": [ "x64" ], @@ -259,9 +259,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz", - "integrity": "sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", "cpu": [ "x64" ], @@ -274,9 +274,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz", - "integrity": "sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", "cpu": [ "x64" ], @@ -289,9 +289,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz", - "integrity": "sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", "cpu": [ "x64" ], @@ -304,9 +304,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz", - "integrity": "sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", "cpu": [ "arm64" ], @@ -319,9 +319,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz", - "integrity": "sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", "cpu": [ "ia32" ], @@ -334,9 +334,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz", - "integrity": "sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", "cpu": [ "x64" ], @@ -349,19 +349,20 @@ } }, "node_modules/@motion-canvas/2d": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.4.0.tgz", - "integrity": "sha512-3CmB2v6eQiSo7763goTKdAreTC4qIM9Qx/N31/Ov7CVWVZ31nUFGR5pRkfyrnoHHI718cfuZNArITPlB86U+LA==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/2d/-/2d-3.11.0.tgz", + "integrity": "sha512-T/RPXGRxddO/xxbC2RcOXfrtBTp8lfcmnuW1fa6++0qy0chK5NFxm3bHJczCbX0ynKB2VAoqLNobTF9eD6ZP3w==", "dependencies": { - "@motion-canvas/core": "^3.4.0", + "@motion-canvas/core": "^3.11.0", "code-fns": "^0.8.2", - "mathjax-full": "^3.2.2" + "mathjax-full": "^3.2.2", + "parse-svg-path": "^0.1.2" } }, "node_modules/@motion-canvas/core": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.4.0.tgz", - "integrity": "sha512-qGLjnhBshnXJqTgtnx/eSJTYmXWo5PtemV4TCczkbDQhvvjNxWwVHIQDNTG4bCg7R1gzKPizFzW63L9q+bIUaw==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/core/-/core-3.11.0.tgz", + "integrity": "sha512-/WjdoSTqTPwCgrB2pP8YXq2T3KviYHrywVxXJ5fEjQ1gajkPKYD7aVlRcY1+kaTbwqXhCARMCh+pSjT2nfhTsw==", "dependencies": { "@types/chroma-js": "^2.1.4", "chroma-js": "^2.4.2" @@ -371,18 +372,18 @@ } }, "node_modules/@motion-canvas/ui": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.4.0.tgz", - "integrity": "sha512-ntgBqqlZdAiTwpySyjf9UFBYDwXgr61UQDtyAJiQzqy0HqDeO0TZKSIqSgAgkY8GCwR2ELP+ITyEW6H0Mq6ZKw==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/ui/-/ui-3.11.0.tgz", + "integrity": "sha512-sd0GxvCkejL2lzExsvgLsC1GgHzLP/0LlMw1QE2/3pMQo3rMOVA7L1Oq6br8HqdJhzMEgW3DWC0NjDJsUfkL2A==", "dev": true, "dependencies": { - "@motion-canvas/core": "^3.4.0" + "@motion-canvas/core": "^3.11.0" } }, "node_modules/@motion-canvas/vite-plugin": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.4.0.tgz", - "integrity": "sha512-tzSCw1RruDBJsF3WV6nXkMMUd5P4KMmSQ+j477qqxTIrklE+Pm4Y9Mdn3M2v3q6fr/o2b4nLa5l7QC/iZ2n9PQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@motion-canvas/vite-plugin/-/vite-plugin-3.11.0.tgz", + "integrity": "sha512-26ixfy5NhvFePj1DBdh7MFsgevpRrzzEKjzSyCK3FOvPcnUWFjab4wWErpsIEnu6a0p7yj4w9VKpa8USx6N95A==", "dev": true, "dependencies": { "follow-redirects": "^1.15.2", @@ -447,9 +448,9 @@ } }, "node_modules/esbuild": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", - "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", + "version": "0.18.20", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -458,28 +459,28 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.15", - "@esbuild/android-arm64": "0.17.15", - "@esbuild/android-x64": "0.17.15", - "@esbuild/darwin-arm64": "0.17.15", - "@esbuild/darwin-x64": "0.17.15", - "@esbuild/freebsd-arm64": "0.17.15", - "@esbuild/freebsd-x64": "0.17.15", - "@esbuild/linux-arm": "0.17.15", - "@esbuild/linux-arm64": "0.17.15", - "@esbuild/linux-ia32": "0.17.15", - "@esbuild/linux-loong64": "0.17.15", - "@esbuild/linux-mips64el": "0.17.15", - "@esbuild/linux-ppc64": "0.17.15", - "@esbuild/linux-riscv64": "0.17.15", - "@esbuild/linux-s390x": "0.17.15", - "@esbuild/linux-x64": "0.17.15", - "@esbuild/netbsd-x64": "0.17.15", - "@esbuild/openbsd-x64": "0.17.15", - "@esbuild/sunos-x64": "0.17.15", - "@esbuild/win32-arm64": "0.17.15", - "@esbuild/win32-ia32": "0.17.15", - "@esbuild/win32-x64": "0.17.15" + "@esbuild/android-arm": "0.18.20", + "@esbuild/android-arm64": "0.18.20", + "@esbuild/android-x64": "0.18.20", + "@esbuild/darwin-arm64": "0.18.20", + "@esbuild/darwin-x64": "0.18.20", + "@esbuild/freebsd-arm64": "0.18.20", + "@esbuild/freebsd-x64": "0.18.20", + "@esbuild/linux-arm": "0.18.20", + "@esbuild/linux-arm64": "0.18.20", + "@esbuild/linux-ia32": "0.18.20", + "@esbuild/linux-loong64": "0.18.20", + "@esbuild/linux-mips64el": "0.18.20", + "@esbuild/linux-ppc64": "0.18.20", + "@esbuild/linux-riscv64": "0.18.20", + "@esbuild/linux-s390x": "0.18.20", + "@esbuild/linux-x64": "0.18.20", + "@esbuild/netbsd-x64": "0.18.20", + "@esbuild/openbsd-x64": "0.18.20", + "@esbuild/sunos-x64": "0.18.20", + "@esbuild/win32-arm64": "0.18.20", + "@esbuild/win32-ia32": "0.18.20", + "@esbuild/win32-x64": "0.18.20" } }, "node_modules/esm": { @@ -511,9 +512,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, "os": [ @@ -523,22 +524,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/import-meta-resolve": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz", @@ -548,17 +533,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/mathjax-full": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.2.tgz", @@ -618,10 +592,10 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "node_modules/parse-svg-path": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz", + "integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -629,9 +603,9 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -640,10 +614,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -651,26 +629,10 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/rollup": { - "version": "3.20.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.2.tgz", - "integrity": "sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.4.tgz", + "integrity": "sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==", "bin": { "rollup": "dist/bin/rollup" }, @@ -703,17 +665,6 @@ "sre": "bin/sre" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -728,14 +679,13 @@ } }, "node_modules/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.5.0.tgz", + "integrity": "sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==", "dependencies": { - "esbuild": "^0.17.5", - "postcss": "^8.4.21", - "resolve": "^1.22.1", - "rollup": "^3.18.0" + "esbuild": "^0.18.10", + "postcss": "^8.4.27", + "rollup": "^3.27.1" }, "bin": { "vite": "bin/vite.js" @@ -743,12 +693,16 @@ "engines": { "node": "^14.18.0 || >=16.0.0" }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@types/node": ">= 14", "less": "*", + "lightningcss": "^1.21.0", "sass": "*", "stylus": "*", "sugarss": "*", @@ -761,6 +715,9 @@ "less": { "optional": true }, + "lightningcss": { + "optional": true + }, "sass": { "optional": true }, diff --git a/animation/value_semantics/package.json b/animation/value_semantics/package.json index 4c4a6cf..9c5588b 100644 --- a/animation/value_semantics/package.json +++ b/animation/value_semantics/package.json @@ -7,13 +7,13 @@ "build": "tsc && vite build" }, "dependencies": { - "@motion-canvas/core": "^3.4.0", - "@motion-canvas/2d": "^3.4.0" + "@motion-canvas/2d": "^3.11.0", + "@motion-canvas/core": "^3.11.0" }, "devDependencies": { - "@motion-canvas/ui": "^3.4.0", - "@motion-canvas/vite-plugin": "^3.4.0", + "@motion-canvas/ui": "^3.11.0", + "@motion-canvas/vite-plugin": "^3.11.0", "typescript": "^4.9.5", "vite": "^4.1.4" } -} \ No newline at end of file +} diff --git a/animation/value_semantics/src/project.meta b/animation/value_semantics/src/project.meta index 95df883..7b0759f 100644 --- a/animation/value_semantics/src/project.meta +++ b/animation/value_semantics/src/project.meta @@ -21,7 +21,7 @@ "resolutionScale": 2, "colorSpace": "srgb", "exporter": { - "name": "image sequence", + "name": "@motion-canvas/core/image-sequence", "options": { "fileType": "image/png", "quality": 100, diff --git a/lectures/code/static_no_classes/odr_violation/CMakeLists.txt b/lectures/code/static_no_classes/odr_violation/CMakeLists.txt new file mode 100644 index 0000000..ec17201 --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.16..3.24) +project( + odr_violation + VERSION 0.0.1 + DESCRIPTION "Our first project" + LANGUAGES CXX) +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "" FORCE) +endif() +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + +add_library(cxx_setup INTERFACE) +target_compile_options(cxx_setup INTERFACE -Wall -Wpedantic -Wextra) +target_compile_features(cxx_setup INTERFACE cxx_std_17) +target_include_directories(cxx_setup INTERFACE ${PROJECT_SOURCE_DIR}) + +add_library(our_cool_lib our_cool_lib.cpp) +target_link_libraries(our_cool_lib PUBLIC cxx_setup) + +add_library(other_lib other_lib.cpp) +target_link_libraries(other_lib PUBLIC cxx_setup) + +add_executable(main main.cpp) +target_link_libraries(main PRIVATE other_lib our_cool_lib) diff --git a/lectures/code/static_no_classes/odr_violation/main.cpp b/lectures/code/static_no_classes/odr_violation/main.cpp new file mode 100644 index 0000000..fb39eee --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/main.cpp @@ -0,0 +1,7 @@ +#include "our_cool_lib.hpp" +#include "other_lib.hpp" + +int main() { + SayHello(); + return 0; +} diff --git a/lectures/code/static_no_classes/odr_violation/other_lib.cpp b/lectures/code/static_no_classes/odr_violation/other_lib.cpp new file mode 100644 index 0000000..1f712fd --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/other_lib.cpp @@ -0,0 +1,5 @@ +#include "other_lib.hpp" + +#include + +void SayHello() { std::cout << "What??? 🤯" << std::endl; } diff --git a/lectures/code/static_no_classes/odr_violation/other_lib.hpp b/lectures/code/static_no_classes/odr_violation/other_lib.hpp new file mode 100644 index 0000000..8fece9e --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/other_lib.hpp @@ -0,0 +1,6 @@ +#ifndef LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_WRONG_LIB_HPP +#define LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_WRONG_LIB_HPP + +void SayHello(); // 😱 This really should be inline + +#endif /* LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_WRONG_LIB_HPP */ diff --git a/lectures/code/static_no_classes/odr_violation/our_cool_lib.cpp b/lectures/code/static_no_classes/odr_violation/our_cool_lib.cpp new file mode 100644 index 0000000..35eaccd --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/our_cool_lib.cpp @@ -0,0 +1,5 @@ +#include "our_cool_lib.hpp" + +#include + +void SayHello() { std::cout << "Hello!" << std::endl; } diff --git a/lectures/code/static_no_classes/odr_violation/our_cool_lib.hpp b/lectures/code/static_no_classes/odr_violation/our_cool_lib.hpp new file mode 100644 index 0000000..28c2ea1 --- /dev/null +++ b/lectures/code/static_no_classes/odr_violation/our_cool_lib.hpp @@ -0,0 +1,6 @@ +#ifndef LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_OUR_COOL_LIB_HPP +#define LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_OUR_COOL_LIB_HPP + +void SayHello(); // 😱 This really should be inline + +#endif /* LECTURES_CODE_STATIC_NO_CLASSES_ODR_VIOLATION_OUR_COOL_LIB_HPP */ diff --git a/lectures/helper.cpp b/lectures/helper.cpp new file mode 100644 index 0000000..dc55ffa --- /dev/null +++ b/lectures/helper.cpp @@ -0,0 +1,21 @@ +#include + +struct Helper { + Helper(int number) { + std::cout << "Create helper with number: " << number << std::endl; + } + ~Helper() { std::cout << "Destroy helper" << std::endl; } + // 😱 Implement the rest for the rule of all or nothing! +}; + +Helper& GetHelper(int number) { + // Will only be initialized when encountered for the first time + static Helper helper{number}; + return helper; +} + +int main() { + auto& helper_1 = GetHelper(42); + auto& helper_2 = GetHelper(23); + std::cout << "Is same object: " << (&helper_1 == &helper_2) << std::endl; +} diff --git a/lectures/images/program_lifetime.png b/lectures/images/program_lifetime.png new file mode 100644 index 0000000..35b2b16 Binary files /dev/null and b/lectures/images/program_lifetime.png differ diff --git a/lectures/images/static_foo_twice.png b/lectures/images/static_foo_twice.png new file mode 100644 index 0000000..f997927 Binary files /dev/null and b/lectures/images/static_foo_twice.png differ diff --git a/lectures/images/static_storage.png b/lectures/images/static_storage.png new file mode 100644 index 0000000..e41bcca Binary files /dev/null and b/lectures/images/static_storage.png differ diff --git a/lectures/images/static_storage_function.png b/lectures/images/static_storage_function.png new file mode 100644 index 0000000..8b09f5f Binary files /dev/null and b/lectures/images/static_storage_function.png differ diff --git a/lectures/namespaces_using.md b/lectures/namespaces_using.md index df8fc59..1085b99 100644 --- a/lectures/namespaces_using.md +++ b/lectures/namespaces_using.md @@ -9,7 +9,7 @@ footer: ![width:80px](images/C++ForYourselfIcon.png) - Namespaces - Using `using` -### 📺 Watch the related YouTube video! +### 📺 Watch the related YouTube video! --- # Prerequisites: @@ -54,7 +54,7 @@ Style (🎨) and software design (🎓) recommendations mostly come from [Google } // namespace bar } // namespace foo ``` -- 🎨 End with comment: `// namespace ` +- 🎨 End with comment: `// namespace ` (`clang_format` will take care of this) - 🎨 Name them like variables in `snake_case` ([source](https://google.github.io/styleguide/cppguide.html#Namespace_Names)) - 🎨 Do not indent the code inside the namespace ([source](https://google.github.io/styleguide/cppguide.html#Namespace_Formatting)) @@ -101,7 +101,7 @@ int main() { return 0; } ``` ---- +--- # Use unnamed namespaces! - ✅ Use **"unnamed" namespaces** in source files ```cpp @@ -116,7 +116,7 @@ int main() { ``` - They are sometimes also called **"anonymous" namespaces** - This generates a namespace with a unique name available only in this "translation unit" (aka source file) -- Also has "linkage" implications +- Also has "[linkage](static_outside_classes.md#linkage)" implications (stay tuned for when we talk about `static`) - Only use them in `.cpp`, `.cc` files, never in `.h`, `.hpp` etc. (stay tuned for when we talk about headers) @@ -140,8 +140,8 @@ int main() { } ``` - :x: **Don't** use from **global scope** (unless in a `cpp` file) -- :x: **Never** use `using namespace foo;` - 😱 It's too permissive and pollutes the current namespace! +- :x: **Never** use `using namespace foo;` + 😱 It's too permissive and pollutes the current namespace! --- diff --git a/lectures/static_outside_classes.md b/lectures/static_outside_classes.md new file mode 100644 index 0000000..07094d7 --- /dev/null +++ b/lectures/static_outside_classes.md @@ -0,0 +1,569 @@ +Keyword `static` outside of classes +--- + +

+ Video +

+ + +- [Keyword `static` outside of classes](#keyword-static-outside-of-classes) +- [Storage duration](#storage-duration) + - [Automatic storage duration an local namespace scope](#automatic-storage-duration-an-local-namespace-scope) + - [Static storage duration at namespace scope](#static-storage-duration-at-namespace-scope) + - [Static storage duration at function scope](#static-storage-duration-at-function-scope) + - [Very rare use of `static` to create mutable variables with static storage duration from a function](#very-rare-use-of-static-to-create-mutable-variables-with-static-storage-duration-from-a-function) + - [Summary of controlling storage duration with `static`](#summary-of-controlling-storage-duration-with-static) +- [Linkage](#linkage) + - [What is linkage](#what-is-linkage) + - [Levels of linkage](#levels-of-linkage) + - [How to understand what linkage a name has](#how-to-understand-what-linkage-a-name-has) + - [Why we care about linkage](#why-we-care-about-linkage) + - [Example with broken linkage](#example-with-broken-linkage) + - [What went wrong?](#what-went-wrong) + - [How to fix the ODR violation?](#how-to-fix-the-odr-violation) + - [Prefer `inline` to `static`](#prefer-inline-to-static) +- [Conclusion and a rule of thumb](#conclusion-and-a-rule-of-thumb) +- [Final words](#final-words) + + +The keyword [`static`](https://en.cppreference.com/w/cpp/keyword/static) is a very important keyword in C++ and is used a lot. Honestly, because of a very general name, it is probably a bit _overused_. Largely speaking, it can be used outside of classes and inside classes and these two cases are slightly different. Today we focus on the former - using `static` outside of classes. If you are interested in how and when to use `static` _inside_ of classes, I will link that lecture here when it's out. + +Anyway, as for using `static` _outside_ of classes, I have good news for you. If you follow my advices about best practices from before then the rule-of-thumb for using `static` outside of classes in modern C++ (that is at least C++17) is very simple - don't! **Don't use `static` at all!** + +Technically, that's all you need to know. But if you want to learn _why_ you shouldn't use `static` outside of classes then keep watching this video and see how deep this rabbit hole goes :wink: + + + +In order to explain why we mostly don't want to use `static` for anything outside of classes we will need to talk about why we _might_ want to use `static` in the first place. The keyword `static` really controls just two things: +- The storage duration +- The linkage + +These terms feel a bit technical and I can already feel the confused faces on the other side of the screen from me :wink: So... what do these words mean? + +## Storage duration +We'll start with "storage duration". Every object declared in C++ has a certain lifetime, or, in other words, a _storage duration_. There is a number of storage durations that any variable can have. At this point, we care about these two: +- Automatic storage duration +- Static storage duration + +To explain the difference between the two we start with a simple `main` function that calls another function `Foo` that has a single local variable in it: + + + +```cpp +void Foo() { + int local_value{}; + // Use local_value +} + +int main() { + Foo(); + return 0; +} +``` +We can then draw the execution time of the program, `main` and `Foo` functions as lines that indicate that most of the time that the program runs is spends in `main`, while most of the time in `main` is spent executing the `Foo` function. + +### Automatic storage duration an local namespace scope + +If we focus now on the lifetime of the `local_value` variable, shown as a blue box in the image, it lives as long as is needed for the execution of the `Foo` function. It's memory is allocated at the start of the function and is freed at the end of the scope. + +We say that a variable `local_value` and any other variable that lives in some local scope, has **automatic storage duration**. + +### Static storage duration at namespace scope +Let's further extend our example by adding some value `kValue`, that is defined at **namespace scope**, and use it to initialize our `local_value`. We will introduce it in an unnamed namespace following the best practices, but it could live in any namespace including the global one. + + + + + +```cpp +namespace { +constexpr int kValue{42}; +} // namespace + +void Foo() { + int local_value{kValue}; + // Use local_value +} + +int main() { + Foo(); + return 0; +} +``` +The `kValue` here has what is called the **static storage duration** and lives for the whole duration of the program. Its data gets allocated at the start of the program and freed at the end of the program. + +:bulb: While we _can_ use `static` for an object definition at namespace scope to indicate that it has the static storage duration **we don't have to**, as any such object has **static storage duration** by default. So all of these definitions are equivalent in terms of storage duration: + +```cpp +constexpr auto answer_1 = 42; +const auto answer_2 = 42; +auto answer_3 = 42; // 😱 please don't create non-const globals... + +// 😱 please don't use static like this ... +static constexpr auto answer_4 = 42; +static const auto answer_5 = 42; +static auto answer_6 = 42; // 😱 please don't create non-const globals... +``` + +### Static storage duration at function scope +Finally, use of `static` can extend the storage duration of a local variable within some function scope to have the static storage duration. + +If we add `static` in front of our `local_value` definition, it will have **static storage duration** again even though it is defined in a local scope. Now `local_value` will get allocated when the function `Foo` is called for the first time and will get de-allocated at the end of the program. + + + +```cpp +namespace { +constexpr int kValue{42}; +} // namespace + +void Foo() { + static int local_value{kValue}; + // Use local_value +} + +int main() { + Foo(); + return 0; +} +``` + +Such a `static` variable will be initialized when first encountered during the program flow and destroyed when the program exits. + +One interesting peculiarity of using `static` to extend the storage duration of a local variable is that if the flow of our program encounters the line that defines the `static` variable multiple times, this line will **only be executed once**. The reason being is that the variable already exists when the program flow reaches the variable definition for the second time, so the definition is skipped and the existing `static` variable is simply used further. + + + +```cpp +namespace { +constexpr int kValue{42}; +} // namespace + +void Foo() { + static int local_value{kValue}; + // Use local_value +} + +int main() { + Foo(); + Foo(); + return 0; +} +``` + +You can easily see (*C++) this for yourself if you replace the creation of a `static` `int` object by the creation of a `static` object of your custom type that prints something on construction and destruction and calling the function `Foo` a couple of times from `main`, like we just discussed. Your object will only print once from its constructor and destructor. Really, give this a try, it should take you no more than a couple of minutes by now :wink: + +### Very rare use of `static` to create mutable variables with static storage duration from a function +Now this is where I lied to you a bit about _never_ needing to use `static`. There _are_ situations when you might want to create a static object within a function. In our `Foo` function we could have returned a non-const reference and essentially model a global mutable variable that will live for the rest of the program lifetime. +```cpp +int& Foo() { + static int local_value{}; + return local_value; +} + +int main() { + // Reference to our static variable. + auto& ref_to_static = Foo(); + return 0; +} +``` + +This is also very similar to the **singleton** design pattern and we will talk about what it is and why you probably don't want to use it later in the course. Anyway, if you remember what we talked about before, you will know that using non-`const` global variables tends to wreak havoc and we probably don't want to do this. + +> For completeness, one use for such an improvised singleton is to deal with the **"static initialization order fiasco"**. It should not hit you as long as you only create variables that rely *exclusively* on values within the same translation unit and not across translation unit boundaries. +> +> ```cpp +> constexpr int kAnswer = 42; // ✅ this is ok. +> constexpr int kValue = kValueFromOtherCppFile; // ❌ not ok! +> ``` +> +> I won't go into details here, but tell me in the comments if you are interested to learn more about it! + +### Summary of controlling storage duration with `static` +It's time we sum up where `static` can be used and what it gives us in terms of changing the storage duration of variables. Generally speaking, when used outside of classes, `static` can be used in two places: +- at namespace scope which adds nothing as any such variable already has the static storage duration +- inside of functions to extend the local variable's automatic storage duration to static storage duration, which we mostly don't want to do + +:bulb: So, all in all, there is really **no good reason** to use `static` to change storage duration of our variables! + +## Linkage +Now it's time to talk about the second thing that `static` controls - linkage. + + + +### What is linkage +First, let me try to explain what linkage is by describing what it is used for. When we write programs we name things like our variables, classes, functions etc. We can think of linkage as of a property of any given name. This property basically controls if a name of any symbol can correspond (in other words - be linked) to its declaration in a different scope. We distinguish linkage of several levels that control which boundaries such links can cross: +- No linkage +- Internal linkage +- External linkage + +Let's dive into these. + +### Levels of linkage +Intuitively speaking, if we want some name to be available only in the current scope, it should have **no linkage**. As an example, any variable defined in any local scope usually has no linkage. + +```cpp +void Foo() { + int bar; // bar has no linkage +} +``` + +If a name should be available beyond local scopes but still **only** from within the same translation unit (think, within one `.cpp` file) - it should have **internal linkage**. The typical examples of these are constants defined at namespace scope, any data and functions put into an unnamed namespaces within a `.cpp` file. Oh, and also any `static` data and functions, but more on that in a minute. + +```cpp +// Constants have internal linkage by default +constexpr int kGlobalConst{}; // 😱 should be inline +const std::string kGlobalWord{}; // 😱 should be inline + + +// In some cpp file +namespace { +// Everything within unnamed namespaces has internal linkage +constexpr int kNumber{}; +const std::string kWord{}; +void Foo() {} +} // namespace + +// Any static variable or function has internal linkage +static int kStaticVariable{}; // 😱 don't use static like this +static void StaticFoo(){} // 😱 don't use static like this +``` + +Finally, **external linkage** is needed for symbols that need to be available globally throughout the program. These are usually classes, enums, non-`static` (usually `inline`) functions and `inline` constants declared at namespace scope in some header files. + +```cpp +// In some header file +// All of the below have external linkage +inline void GlobalFoo() {} +inline constexpr int kGlobalNumber{}; +inline const std::string kGlobalString{}; + +void OtherGlobalFoo() {} // 😱 should be inline +``` + +### How to understand what linkage a name has +In the end it is up to us which linkage our entities have. We can pick linkage of anything that we declare at declaration time by choosing **where** we put our declarations (local scope, namespace scope, unnamed namespace etc.) and by using keywords `const`, `constexpr`, `static` and `inline` all of which have their influence on linkage. + +As you might start to suspect, the complete rules of how linkage is selected are slightly convoluted. If you want to figure out these rules in all details you can always read the cppreference pages for [linkage](https://en.cppreference.com/w/cpp/language/storage_duration) and [inline](https://en.cppreference.com/w/cpp/language/inline). The good news is that when _we_ write the code the rules to follow the best practices are pretty simple and I will summarize them at the end of this lecture. + +However, in order to read the code written by others we have to dive a bit deeper into these convoluted rules. So, to save you the trouble of figuring out all of the intricate details, I came up with a flow chart. If we follow it, we can find out the linkage of any symbol we are looking at. This is helpful to debug code that we did not write and see issues in the code _before_ they happen as well as to know how to make sure the symbol we want to write has the linkage we want. + +```mermaid +graph TB; + Local -->|yes| No[No linkage] + Local{{Is in local scope?}} -->|no| Unnamed + Unnamed{{Is in unnamed namespace?}} -->|yes| Internal + Unnamed -->|no| Static + Static{{static?}} -->|yes| Internal[Internal linkage] + Static -->|no| Inline{{inline?}} + Inline -->|no| Const{{const? constexpr?}} + Inline -->|yes| External[External linkage] + Const -->|yes| Func{{Is function?}} + Func -->|no| Internal + Func -->|yes| External + + style No fill:#226666,color:white; + style Internal fill:#763289,color:white; + style External fill:#3355AA,color:white; +``` + +Here is how to read it. This chart should work with any function or data declaration you might encounter. First, if you are looking at a function, ignore the return type along with any const qualifiers it might have. Then, follow the chart by answering the questions. + +Let's see a couple of examples that follow best practices: + +```cpp +// In some hpp file +inline constexpr int kNumber{}; // external linkage +inline const std::string kWord{}; // external linkage +inline void Func(); // external linkage + +// Lives in some cpp file +namespace { +constexpr int kOtherNumber{}; // internal linkage + +void OtherFunc() { // internal linkage + int local_variable{}; // no linkage +} +} // namespace +``` + + + +### Why we care about linkage +#### Example with broken linkage +Now I think is a good time to dive into an [example](code/static_no_classes/odr_violation/) that should show us why linkage is so important and what can go wrong if we don't follow best practices. + + +Say we have a somewhat large project and in it we write a library that has a declaration of a function `SayHello` in a header file `our_cool_lib.hpp`: + +`our_cool_lib.hpp` + +```cpp +void SayHello(); // 😱 This really should be inline +``` + +We further write a definition of our function, which prints "Hello!" to the terminal when we call it, in a corresponding source file `our_cool_lib.cpp`: + +```cpp +#include "our_cool_lib.hpp" + +#include + +void SayHello() { std::cout << "Hello!" << std::endl; } +``` + +And we also add another file `main.cpp` that includes our header and calls the `SayHello` function in the `main` function: + +```cpp +#include "our_cool_lib.hpp" + +int main() { + SayHello(); + return 0; +} +``` + +Now, we just need to instruct the compiler and the linker on how to build and link this code and we do that using CMake. Let's further assume that we implement this as part of some large project so we also link to some `other_lib` that might itself be linked against other libraries too. We will see why this matters in a second. + +```cmake +# Omitting CMake boilerplate and creation of other_lib + +add_library(our_cool_lib our_cool_lib.cpp) +target_link_libraries(our_cool_lib PUBLIC cxx_setup) + +add_executable(main main.cpp) +target_link_libraries(main PRIVATE other_lib our_cool_lib) +``` + +So far so good. Now, we build it and run it and should get our "Hello!" printed to the terminal: +```cmd +λ › cmake -S . -B build +λ › cmake --build build -j 12 +λ › ./build/main +What??? 🤯 +``` + +#### What went wrong? +Wait... What? Why did it not print "Hello!" as we expected? + +Well, I hid something from you before. But only because this can happen in real projects! You might have guessed that the `other_lib` is somehow involved. Somehow, somebody had a header `other_lib.hpp` that had exactly the same declaration of the `SayHello` function as we did! + +```cpp +void SayHello(); // 😱 This really should be inline +``` + +However, in the corresponding source file `other_lib.cpp` they had a different printout! + +```cpp +#include "other_lib.hpp" + +#include + +void SayHello() { std::cout << "What??? 🤯" << std::endl; } +``` + +Ok, so we start getting the feeling that something _might_ go wrong here, but why does it? + +The reason for this is that the linkage of the `SayHello` function is **external** as it is a function in the namespace scope and every function at namespace scope has external linkage by default. And there are now two definitions of the `SayHello` function in two different libraries. And these definitions are different. This means that we get into trouble because of the [One Definition Rule (ODR)](https://en.cppreference.com/w/cpp/language/definition) violation. That rule states roughly this: that any symbol must have exactly one definition in the entire program, i.e., across all of its translation units. Only `inline` symbols can have more than one definition which are then all assumed to be exactly the same. + +So, here is a slightly simplified explanation of what happens when we compile our code. First, the compiler sees the declaration of the function in our `our_cool_lib.hpp` file, understands that the linkage of the `SayHello` symbol is external and calmly continues, knowing that the linker will take care of finding where the implementation of `SayHello` lives. Which the linker does. The issue arises because the linked sees the `SayHello` symbol from the `other_lib` first. As that symbol also has external linkage and expecting that we know about ODR, it happily links these symbols together and stops. So we end up calling a wrong function! + +:bulb: Note that _which_ function is called in such a situation is pure luck as the way the linker will search for the proper symbol is implementation defined. It is implicitly assumed that we follow the ODR and nobody double checks it. Which is to say, that we are firmly in the "Undefined behavior land" 🌈🦄 + +This is why it is so important to have the right muscle memory when writing C++ code to never end up in such a situation! + +#### How to fix the ODR violation? +Now that we understand _what_ went wrong, how can we fix this? + +And this is, I believe, where `static` historically has been used. Remember how I mentioned that `static` functions have **internal** linkage? We can make use of this. + +First, let's consider what would happen if we added `static` before the declaration and the definition of _our_ `SayHello` function? + +`our_cool_lib.hpp` + +```cpp +static void SayHello(); // 😱 This really should be inline +``` + +`our_cool_lib.cpp`: + +```cpp +#include "our_cool_lib.hpp" + +#include + +static void SayHello() { std::cout << "Hello!" << std::endl; } +``` + +If we try to compile this, we get a couple of warnings and an error (note that I'm using clang so if you are using gcc your error might be different): +```cmd +λ › cmake --build build -j 12 +Consolidate compiler generated dependencies of target our_cool_lib +[ 50%] Building CXX object CMakeFiles/our_cool_lib.dir/our_cool_lib.cpp.o +/static_no_classes/odr_violation/our_cool_lib.cpp:5:13: warning: unused function 'SayHello' [-Wunused-function] +static void SayHello() { std::cout << "Hello!" << std::endl; } + ^ +1 warning generated. +... +[100%] Linking CXX executable main +ld: Undefined symbols: + SayHello(), referenced from: + _main in main.cpp.o +clang: error: linker command failed with exit code 1 (use -v to see invocation) +make[2]: *** [main] Error 1 +``` + +Overall, the important things to note here are that our `main` executable sees that there is a function `SayHello` declared as `static`. Which is to say that its linkage is **internal**. So the linker tries to find the definition of this function **within the same translation unit**, aka `main.cpp`. But our definition lives in a **different** translation unit `our_cool_lib.cpp`. So in that translation unit our function is unused, thus the warning, while there is no implementation for the `static void SayHello()` function within the `main.cpp` file which makes the linker fail. + +To solve this we can move the implementation of the function into the header file `our_cool_lib.hpp` while marking the function `static`: + +```cpp +#include +// 😱 Should really be inline instead +static void SayHello() { std::cout << "Hello!" << std::endl; } +``` + +If we do that, we don't need the `our_cool_lib` target in CMake anymore and just include this file into `main.cpp` directly. + +Now our code builds without issues and when we run it, we get the correct output. + +Seems like we've solved everything, right? Well, technically yes, but there is a minor issue with using `static` like this which might or might not be important to us depending on the application. + +#### Prefer `inline` to `static` +The issue with `static` is that it **enforces** internal linkage. This means that in our example, if we include our `our_cool_lib.hpp` file into multiple translation units, we will have a **copy** of the compiled binary code of the `SayHello` function in every single translation unit. This takes space which might become problematic on constrained hardware. + +

+ Video +

+ +This is where `inline` comes to the rescue! It implies **external** linkage but, as stated in the ODR formulation, multiple definitions _are_ allowed for `inline` functions and data (🔼 C++17). So in our case, if we replace `static` with `inline` for our `SayHello` function, we will only ever have one instance of the compiled binary code for this function that the linker will happily link everywhere. + +`our_cool_lib.hpp`: + +```cpp +#include +inline void SayHello() { std::cout << "Hello!" << std::endl; } +``` + +I also urge you to watch [this video](https://www.youtube.com/watch?v=QVHwOOrSh3w) by Jason Turner on his C++ Weekly chanel about this to learn the intuitive differences between `static` and `inline` in this context. + + +:bulb: Overall, using `inline` is the best way to declare functions and data that should be visible globally in modern C++. So, you see, there is no reason to mark functions or data as `static` anymore due to linkage reasons. We should mark them `inline` instead. + +## Conclusion and a rule of thumb +And I guess this pretty much sums up everything I wanted to talk about with regard to using `static` outside of classes. This has led us down a couple of rabbit holes, linkage being a pretty deep one. + +But I hope that by now you see that **there is no need to use `static` outside of classes at all in modern C++**. Here is a guideline to follow along with this: + +- When defining variables at namespace scope always mark them as `inline const` or, even better `inline constexpr`. Do **not** mark them `static`! +- When defining variables at local scope, do **not** mark them `static` unless you are explicitly implementing a singleton-like design pattern (which you probably shouldn't do anyway, stay tuned...) +- When declaring functions at namespace scope, declare (and define) them as `inline`. Do **not** use `static` for this! +- When declaring data or functions in an unnamed namespace, do not mark them as `static` or `inline`. Data should still be `const` or `constexpr` + +## Final words +Understanding the key role that linkage and ODR play here is crucial to understanding what `inline` and, previously, `static` were designed to solve. Initially `static` was introduced into the C programming language and then was inherited by C++. It was in the times when C did not have `inline` and in C++ it meant something different and could not be used as it can be now. Thankfully, we live in better times now, which makes `static` close to obsolete when used outside of classes. Now if you want to know how to use `static` *in classes* you can see a video about that once it's ready and maybe also go back and refresh how `inline` plays a huge role in creating [libraries](headers_and_libraries.md) in C++. + + diff --git a/readme.md b/readme.md index 2714d66..86cbfa9 100644 --- a/readme.md +++ b/readme.md @@ -436,6 +436,21 @@ Headers with classes ---------------------------------------------------------- +
+Keyword static outside of classes + +---------------------------------------------------------- +[![Video thumbnail](https://img.youtube.com/vi/m8kN3MIUEpg/maxresdefault.jpg)](https://youtu.be/m8kN3MIUEpg) + +[Lecture script](lectures/static_outside_classes.md) +- Why we should not use `static` outside of classes +- Relation to storage duration +- Relation to linkage +- Why we should use `inline` instead + +---------------------------------------------------------- +
+ --- ## PS