diff --git a/.gitignore b/.gitignore index 13e00578..5b7252b8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,9 @@ newman config.json uploads/ -.docker/mitmproxy-data \ No newline at end of file +.docker/mitmproxy-data +.DS_Store + +# auto generated files +apps/juxtaposition-ui/src/webfiles/ctr/css/sprites.css +apps/juxtaposition-ui/src/webfiles/ctr/images/sprites.png \ No newline at end of file diff --git a/apps/juxtaposition-ui/nodemon.json b/apps/juxtaposition-ui/nodemon.json index cabe691d..5b610579 100644 --- a/apps/juxtaposition-ui/nodemon.json +++ b/apps/juxtaposition-ui/nodemon.json @@ -3,6 +3,10 @@ "src/" ], "ext": "js,ts,ejs,tsx,jsx,json,css", + "ignore": [ + "src/webfiles/ctr/css/sprites.css", + "src/webfiles/ctr/images/sprites.png" + ], "env": { "NODE_ENV": "development" } diff --git a/apps/juxtaposition-ui/package.json b/apps/juxtaposition-ui/package.json index a47b0723..87ff34b9 100644 --- a/apps/juxtaposition-ui/package.json +++ b/apps/juxtaposition-ui/package.json @@ -13,7 +13,8 @@ "lint": "eslint .", "lint:fix": "eslint . --fix", "build": "tsup && tsc --noEmit", - "start": "node --enable-source-maps dist/server.js" + "start": "node --enable-source-maps dist/server.js", + "build:sprites": "node scripts/sprites.ts" }, "dependencies": { "@aws-sdk/client-s3": "^3.958.0", @@ -63,6 +64,8 @@ "@types/node": "^22.19.1", "@types/react": "^19.1.13", "@types/react-dom": "^19.2.3", + "@repo/esbuild-plugin-oxipng": "^0.0.0", + "@repo/esbuild-plugin-spritesmith": "^0.0.0", "browserslist": "^4.28.0", "browserslist-to-esbuild": "^2.1.1", "ejs-lint": "^2.0.1", diff --git a/apps/juxtaposition-ui/src/services/juxt-web/views/ctr/newPostView.tsx b/apps/juxtaposition-ui/src/services/juxt-web/views/ctr/newPostView.tsx index d0791958..9261cd03 100644 --- a/apps/juxtaposition-ui/src/services/juxt-web/views/ctr/newPostView.tsx +++ b/apps/juxtaposition-ui/src/services/juxt-web/views/ctr/newPostView.tsx @@ -7,38 +7,38 @@ const empathies = [ value: 0, miiFaceFile: 'normal_face.png', sound: 'SE_WAVE_MII_FACE_00', - className: 'feeling-button-normal', + className: 'sprite sp-feeling-normal', isDefault: true }, { value: 1, miiFaceFile: 'smile_open_mouth.png', sound: 'SE_WAVE_MII_FACE_01', - className: 'feeling-button-happy' + className: 'sprite sp-feeling-happy' }, { value: 2, miiFaceFile: 'wink_left.png', sound: 'SE_WAVE_MII_FACE_02', - className: 'feeling-button-like' + className: 'sprite sp-feeling-like' }, { value: 3, miiFaceFile: 'surprise_open_mouth.png', sound: 'SE_WAVE_MII_FACE_03', - className: 'feeling-button-surprised' + className: 'sprite sp-feeling-surprise' }, { value: 4, miiFaceFile: 'frustrated.png', sound: 'SE_WAVE_MII_FACE_04', - className: 'feeling-button-frustrated' + className: 'sprite sp-feeling-frustrated' }, { value: 5, miiFaceFile: 'sorrow.png', sound: 'SE_WAVE_MII_FACE_05', - className: 'feeling-button-puzzled' + className: 'sprite sp-feeling-puzzled' } ]; @@ -83,14 +83,14 @@ export function CtrNewPostView(props: NewPostViewProps): ReactNode { data-sound="SE_WAVE_BALLOON_OPEN" evt-click="window.alert('Screenshots are not ready yet. Check back soon!')" > - +
  • - +
  • - + - + {post.topic_tag} @@ -92,14 +92,18 @@ export function CtrPostView(props: PostViewProps): ReactNode { })} data-post={post.id} > - + - {post.empathy_count} + + {post.empathy_count} {' '} {!props.isReply ? ( - {post.reply_count} + <> + + {post.reply_count} + ) : null} diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/community.ejs b/apps/juxtaposition-ui/src/webfiles/ctr/community.ejs index 7f110bea..eb9156d8 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/community.ejs +++ b/apps/juxtaposition-ui/src/webfiles/ctr/community.ejs @@ -20,11 +20,11 @@ - - <%= bundle.numPosts %> + + <%= bundle.numPosts %> | - + <%= community.followers %> @@ -45,7 +45,7 @@ <%}%> <%if(community.permissions.open){%> <%}%> diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/css/juxt.css b/apps/juxtaposition-ui/src/webfiles/ctr/css/juxt.css index 3f58f6d1..164f5359 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/css/juxt.css +++ b/apps/juxtaposition-ui/src/webfiles/ctr/css/juxt.css @@ -1,3 +1,5 @@ +@import 'sprites.css'; + body { margin: 0; font-family: Arial, serif; @@ -12,7 +14,7 @@ body { } #body { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAABlBMVEXr6+vz8/MrOb4oAAABaklEQVR42u3dwQ3AMAgDQGf/pftI2xWMxLEA4RSF/JwzoVKp23rt+C9BNs+fTABItQBk9/zfUwgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTuAhC9LXy9SnBbtw9Qt29fwQEAq5fwSXsNAfATBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYncBiN4Wvv4DtAjOhHoA98yAYU5WRYgAAAAASUVORK5CYII=); + background-image: url(@/webfiles/ctr/images/background.png); background-size: 100px; background-repeat: repeat; padding-bottom: 30px @@ -54,7 +56,7 @@ ul { display: block; width: 400px; height: 220px; - background: url(data:image/png;base64,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); + background: url(@/webfiles/ctr/images/header.png); background-size: 400px; position: relative; margin-bottom: 10px @@ -127,13 +129,13 @@ menu.tab-header { .headline { line-height: 2; color: #fff; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAA4CAMAAAASENtRAAAAVFBMVEUAAABJL5JKL5JKL5NKMJNLMJRLMZRMMZRMMZVMMpVNMpVNMpZNM5ZOM5ZOM5dONJdPNJhPNZhQNZhQNZlQNplRNppRN5pSN5tSOJtTOJxTOZxUOZ0LlP23AAAAAXRSTlMAQObYZgAAAZ9JREFUeNrt3WFSgzAUReFEAxpFq9YqNvvfp5RpFREqXqahSc/ZwCv98hh+gTFf2dN1de3+rthVNulzfNPdfbdqsIfHfit96Hqg106bsfSRH8Ntt2Gf+ZU9aQBHBu4bWwtwbsBdYgtwjsAhmi/AywCHWL4ALwQcAL4AYAtwvsABYIABThvYApwzcAAYYIABBhhggAEGGGCAAQYYYIABBhhggAEGGGCAAQY4UWCnTnSJA+sXPgNYPlZeBvbqyCpx4HLOAqvAK/FYubUMrK5wUacOrO1wu786sLbDg/s7FXjjhQt11ZjvgsD/+f3lkW5uD/mRpKNRtsD9ngZ6/tlLq+ml07gDfjv0frx6V5eyrqZe6NkBN3/3DGD1VM0BVu/tM4DrYvKYMwR2OrD8eFbqwPKjkteBK5sysNWB9Zk6sH6QdWAHcALAVge2AAMMMMAAAwwwwAADDDDAAAMMMMAAAwwwwAADDDDAsYANwDkDG4ABBjhtYANwvsAG4AsANgDnChzvhdEALwEc8ZXvAC8AHPWrDQDHBo794RWAYwJ/s34C68TCMJTo+UUAAAAASUVORK5CYII=) 0 0 no-repeat; + background: url(@/webfiles/ctr/images/headline.png) 0 0 no-repeat; margin: 6px 10px; background-size: 100% !important } .headline.headline-green { - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAA4CAMAAAASENtRAAAASFBMVEUAAAAAoosAo4wApIwApI0ApY0ApY4Apo4Apo8Ap48Ap5AAqI8AqJAAqZAAqZEAqpIAq5EAq5MArJIArJMArZMArZQArpQAr5WsfiPZAAAAAXRSTlMAQObYZgAAAZlJREFUeNrt3eFagjAYhuHNQZOsTCN3/mcaWBkRKL1cDjef5wQ+8d7HxS8w5pS9XquVu1zRVjbpc3zTurrc41O/jT50O9Brp91Y+sj34Q6H8JX5k71qAEcG7htbC3BuwF1iC3COwCGaL8DLAIdYvgAvBBwAvgNgC3C+wAFggAFOG9gCnDNwABhggAEGGGCAAQYYYIABBhhggAEGGGCAAQYYYIABBjhRYKdOdIkD6xc+A1g+Vl4G9urIKnHgcs4Cq8Ab8Vi5rQysrnBRpw6s7fBxf3VgbYcH93cq8M4LF+qqMd8Fgf/z+8szPZzyI0lHozwC93sZ6Pl3n5peOo0t8P67t/PVbV3Kupp6oTcH3PzdM4DVUzUHWL23zwCui8ljbhDY6cDy41mpA8uPSl4HrmzKwFYH1mfqwPpB1oEdwAkAWx3YAgwwwAADDDDAAAMMMMAAAwwwwAADDDDAAAMMMMAAxwI2AOcMbAAGGOC0gQ3A+QIbgO8A2ACcK3C8F0YDvARwxFe+A7wAcNSvNgAcGzj2h1cAjgn8w/oBNdhJzC/qUbIAAAAASUVORK5CYII=) 0 0 no-repeat; + background: url(@/webfiles/ctr/images/headline-green.png) 0 0 no-repeat; border-color: #59c9a5 } @@ -208,40 +210,14 @@ menu.tab-header { width: 400px } -.sprite { - display: inline-block; - width: 16px; - height: 16px; - background-size: 100px -} - -.feeling-selector .buttons input, -.sprite { - content: ""; - background-image: url(data:image/png;base64,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) -} - -.sprite.posts { - background-position: 0 0 -} - -.sprite.followers { - background-position: -17px 0; - width: 19px -} - -.sprite.tag { - background-position: -27px 0; - width: 11px; - background-size: 75px; - height: 14px -} - .text { font-size: 16px; position: absolute; right: 10px; - top: 2px + top: 2px; +} +.text > span > span { + vertical-align: middle; } menu.tab-header { @@ -258,7 +234,7 @@ menu.tab-header { menu.tab-header li { display: inline-block; width: 144px; - background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAA0CAIAAADEwMXAAAAAQ0lEQVQI17XOMQGAQBDAsLbvDR0YRBUCGBBwDGCBIXvYt6PrPhPTqpWu0GoVhqssNTClwYTUZgj+JxNjSNh3fg/vnQd22QnBxJgqHwAAAABJRU5ErkJggg==) + background: url(@/webfiles/ctr/images/tab.png); } menu.tab-header li:first-child { @@ -479,17 +455,9 @@ header svg { background: -webkit-gradient(linear, left top, left bottom, from(#fff), color-stop(.5, #fff), color-stop(.8, #f6f6f6), color-stop(.96, #f5f5f5), to(#bbb)) 0 0 } -.sprite.yeah { - width: 20px; - height: 19px; - background-position: -55px 0; - background-size: 110px; +.inline-sprite { + display: inline-block; border: 0; - margin: 0 -} - -.yeah-button.selected .sprite.yeah { - background-position: -74px 0 } .feeling-selector .buttons { @@ -500,7 +468,8 @@ header svg { background-color: #846abd; margin-top: 5px; margin-right: 5px; - padding: 0 3px + padding: 0 3px; + font-size: 0; /* Collapse out whitespace */ } .feeling-selector .buttons li { @@ -517,15 +486,9 @@ header svg { height: 28px; border: 0; text-indent: -3000px; - background-size: 172px; - background-position: 0 -29px; margin: -1px -2px -2px } -.feeling-selector .buttons input:checked { - background-position-y: -58px !important -} - .feeling-selector .icon { float: left; border: 1px solid gray; @@ -547,30 +510,6 @@ header svg { height: 208px } -.feeling-button-normal { - background-position-x: 0 !important -} - -.feeling-button-happy { - background-position-x: -28px !important -} - -.feeling-button-like { - background-position-x: -56px !important -} - -.feeling-button-surprised { - background-position-x: -84px !important -} - -.feeling-button-frustrated { - background-position-x: -113px !important -} - -.feeling-button-puzzled { - background-position-x: 31px !important -} - #body .image-selector .dropdown-toggle, button.load-more { text-align: center; @@ -581,24 +520,24 @@ button.load-more { #body .image-selector .dropdown-toggle { display: inline-block; - height: 34px; + width: 65px; + height: 36px; margin: 5px 0; font-size: 24px; background: -webkit-gradient(linear, left top, left bottom, from(#fff), color-stop(.5, #fff), color-stop(.8, #f6f6f6), color-stop(.96, #f5f5f5), to(#bbb)) 0 0; border-radius: 4px; padding: 0 2px; user-select: none; - border: 1px solid #323232 + border: 1px solid #323232; + position: relative; } -#body .image-selector .preview-image { - vertical-align: bottom; - width: 35px; - height: 25px; +#body .image-selector .sprite.sp-screenshot { + position: absolute; + left: 50%; + top: 50%; + -webkit-transform: translate(-50%, -50%); border: 0; - background-position-x: 1px; - background-position-y: -125px; - background-size: 150px } .dropdown-toggle > input { @@ -612,30 +551,21 @@ button.load-more { z-index: 20 } -.sprite.feeling, -.sprite.reply { - padding-left: 20px; - background-size: 150px; - padding-bottom: 5px; +.yeah-count, +.reply-count { + padding-left: 5px; color: #646464; - margin-top: 6px; - width: auto -} - -.sprite.reply { - background-position-x: -127px; - background-position-y: 75px } -.sprite.feeling { - background-position-x: -128px; - background-position-y: 55px +.to-permalink-button span { + vertical-align: middle; } .to-permalink-button { float: right; margin-right: 10px; - margin-top: 2px + margin-top: 2px; + padding-top: 10px; } div.button-wrapper.center { @@ -680,7 +610,7 @@ menu.tab-header.no-margin { .textarea-menu { height: 123px; - margin-top: 10px; + margin-top: 8px; position: relative; margin-left: 2px; } @@ -764,33 +694,18 @@ menu.tab-header.no-margin { display: inline-block } -.textarea-menu .sprite { +.textarea-menu .sprite.sp-text-input { position: absolute; - left: 9px; - width: 26px; - height: 17px; - background-size: 170px; - pointer-events: none -} - -.sprite.text-input { + pointer-events: none; top: 24px; - background-position: -61px -86px -} - -.sprite.text-input.selected { - background-position: -86px -86px + left: 9px; } -.sprite.memo { +.textarea-menu .sprite.sp-memo-input { + position: absolute; + pointer-events: none; top: 85px; - background-position: -65px -105px; - width: 17px; - left: 14px -} - -.sprite.memo.selected { - background-position: -85px -105px; + left: 13px } .checkbox-container span { diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/header.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/header.png new file mode 100644 index 00000000..bf3bfd46 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/header.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/icons.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/icons.png deleted file mode 100644 index e4794cc3..00000000 Binary files a/apps/juxtaposition-ui/src/webfiles/ctr/images/icons.png and /dev/null differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated.png new file mode 100644 index 00000000..9d394ec3 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated_checked.png new file mode 100644 index 00000000..be2f0ee1 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-frustrated_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy.png new file mode 100644 index 00000000..a17b1467 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy_checked.png new file mode 100644 index 00000000..b385fe2a Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-happy_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like.png new file mode 100644 index 00000000..1f3a61b1 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like_checked.png new file mode 100644 index 00000000..d745b12b Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-like_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal.png new file mode 100644 index 00000000..38986f87 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal_checked.png new file mode 100644 index 00000000..82ecdb2f Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-normal_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled.png new file mode 100644 index 00000000..97986abd Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled_checked.png new file mode 100644 index 00000000..9f16b735 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-puzzled_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise.png new file mode 100644 index 00000000..fb8f6887 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise_checked.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise_checked.png new file mode 100644 index 00000000..df9316e9 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/feeling-surprise_checked.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/follower-count.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/follower-count.png new file mode 100644 index 00000000..20b77d6d Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/follower-count.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.png new file mode 100644 index 00000000..dc82bbe1 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.selected.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.selected.png new file mode 100644 index 00000000..3a2fee0e Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/memo-input.selected.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/post-count.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/post-count.png new file mode 100644 index 00000000..3adff2e2 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/post-count.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/reply.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/reply.png new file mode 100644 index 00000000..c070e429 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/reply.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/screenshot.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/screenshot.png new file mode 100644 index 00000000..ebf3184d Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/screenshot.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/tag.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/tag.png new file mode 100644 index 00000000..4edc2dfc Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/tag.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.png new file mode 100644 index 00000000..43b8c5f2 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.selected.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.selected.png new file mode 100644 index 00000000..73e800ad Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/text-input.selected.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah-small.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah-small.png new file mode 100644 index 00000000..9ab11872 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah-small.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.png new file mode 100644 index 00000000..4781c638 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.selected.png b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.selected.png new file mode 100644 index 00000000..7e430e81 Binary files /dev/null and b/apps/juxtaposition-ui/src/webfiles/ctr/images/sprites/yeah.selected.png differ diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/js/juxt.js b/apps/juxtaposition-ui/src/webfiles/ctr/js/juxt.js index 2bbca947..0cf110b5 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/js/juxt.js +++ b/apps/juxtaposition-ui/src/webfiles/ctr/js/juxt.js @@ -129,6 +129,7 @@ function initYeah() { } function yeah(e) { var el = e.currentTarget; + var sprite = el.querySelector('.sprite.sp-yeah'); var id = el.getAttribute('data-post'); var parent = document.getElementById(id); var count = document.getElementById('count-' + id); @@ -136,6 +137,7 @@ function initYeah() { var params = 'postID=' + id; if (classList.contains(el, 'selected')) { classList.remove(el, 'selected'); + classList.remove(sprite, 'selected'); classList.remove(parent, 'yeah'); if (count) { count.innerText -= 1; @@ -143,6 +145,7 @@ function initYeah() { cave.snd_playSe('SE_OLV_CANCEL'); } else { classList.add(el, 'selected'); + classList.add(sprite, 'selected'); classList.add(parent, 'yeah'); if (count) { count.innerText = ++count.innerText; diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/partials/new_post.ejs b/apps/juxtaposition-ui/src/webfiles/ctr/partials/new_post.ejs index 2d93cc4f..260af361 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/partials/new_post.ejs +++ b/apps/juxtaposition-ui/src/webfiles/ctr/partials/new_post.ejs @@ -9,55 +9,55 @@
      -
    • + data-sound="SE_WAVE_MII_FACE_00"/>
    • - + data-sound="SE_WAVE_MII_FACE_01"/>
    • - + data-sound="SE_WAVE_MII_FACE_02"/>
    • - + data-sound="SE_WAVE_MII_FACE_03"/>
    • - + data-sound="SE_WAVE_MII_FACE_04"/>
    • - + data-sound="SE_WAVE_MII_FACE_05"/>
  • - +
  • - +
    diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/partials/post_template.ejs b/apps/juxtaposition-ui/src/webfiles/ctr/partials/post_template.ejs index 8d328974..b2482128 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/partials/post_template.ejs +++ b/apps/juxtaposition-ui/src/webfiles/ctr/partials/post_template.ejs @@ -10,7 +10,7 @@ <%if(post.topic_tag) {%> - + <%=post.topic_tag%> @@ -48,13 +48,15 @@
    href="/posts/<%= post.id %>"<%}%> class="to-permalink-button" data-pjax="#body"> <%if(!locals.yeah) {%> - <%=post.empathy_count %> + + <%=post.empathy_count %> <%if(!reply) {%> - <%=post.reply_count %> + + <%=post.reply_count %> <%}%> <%}%> diff --git a/apps/juxtaposition-ui/src/webfiles/ctr/user_page.ejs b/apps/juxtaposition-ui/src/webfiles/ctr/user_page.ejs index b425b344..4ff3c408 100644 --- a/apps/juxtaposition-ui/src/webfiles/ctr/user_page.ejs +++ b/apps/juxtaposition-ui/src/webfiles/ctr/user_page.ejs @@ -21,11 +21,11 @@ <%if(!pnid.deleted && !banned) {%> - - <%=numPosts%> + + <%=numPosts%> | - + <%= userContent.following_users.length - 1 %> @@ -38,7 +38,7 @@ <%}%> <%if(pnid.pid !== pid && !pnid.deleted && !banned) {%> <%}%> diff --git a/apps/juxtaposition-ui/tsup.config.ts b/apps/juxtaposition-ui/tsup.config.ts index e771cba2..2871a76e 100644 --- a/apps/juxtaposition-ui/tsup.config.ts +++ b/apps/juxtaposition-ui/tsup.config.ts @@ -2,6 +2,8 @@ import { defineConfig } from 'tsup'; import { copy } from 'esbuild-plugin-copy'; import { raw } from 'esbuild-raw-plugin'; import { fixImportsPlugin } from 'esbuild-fix-imports-plugin'; +import { oxipng } from '@repo/esbuild-plugin-oxipng'; +import { spritesmith } from '@repo/esbuild-plugin-spritesmith'; import browserslist from 'browserslist-to-esbuild'; export default defineConfig([ @@ -53,9 +55,16 @@ export default defineConfig([ format: 'iife', esbuildOptions(options): void { - options.external = ['/images/*', '/fonts/*']; + options.external = ['/fonts/*']; }, esbuildPlugins: [ + oxipng({ loader: 'dataurl' }), + spritesmith({ + input_folder: './src/webfiles/ctr/images/sprites/', + output_css: './src/webfiles/ctr/css/sprites.css', + output_image: './src/webfiles/ctr/images/sprites.png', + output_image_url: '@/webfiles/ctr/images/sprites.png' + }), copy({ resolveFrom: 'cwd', assets: [ diff --git a/package-lock.json b/package-lock.json index 4319fbba..f15a9a08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -56,6 +56,8 @@ }, "devDependencies": { "@pretendonetwork/eslint-config": "^0.1.3", + "@repo/esbuild-plugin-oxipng": "^0.0.0", + "@repo/esbuild-plugin-spritesmith": "^0.0.0", "@types/cookie-parser": "^1.4.10", "@types/express-session": "^1.18.2", "@types/hashmap": "^2.3.4", @@ -2060,6 +2062,15 @@ "url": "https://opencollective.com/js-sdsl" } }, + "node_modules/@jsquash/oxipng": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@jsquash/oxipng/-/oxipng-2.3.0.tgz", + "integrity": "sha512-aQ8wiEp6ztlTMXc+RMt/CG8crU3mEHDU+h+JYkIi6ctMhlh8+Ltj5XwQFfBuyzKYrp8NxaFW80Dp824bqjr+zA==", + "license": "Apache-2.0", + "dependencies": { + "wasm-feature-detect": "^1.2.11" + } + }, "node_modules/@mongodb-js/saslprep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.2.tgz", @@ -2431,6 +2442,14 @@ "@redis/client": "^5.10.0" } }, + "node_modules/@repo/esbuild-plugin-oxipng": { + "resolved": "packages/esbuild-plugin-oxipng", + "link": true + }, + "node_modules/@repo/esbuild-plugin-spritesmith": { + "resolved": "packages/esbuild-plugin-spritesmith", + "link": true + }, "node_modules/@repo/grpc-client": { "resolved": "packages/grpc-client", "link": true @@ -3551,6 +3570,13 @@ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true }, + "node_modules/@types/expect": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz", + "integrity": "sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/express": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", @@ -3738,6 +3764,16 @@ "@types/send": "*" } }, + "node_modules/@types/spritesmith": { + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/@types/spritesmith/-/spritesmith-3.4.5.tgz", + "integrity": "sha512-LRyCIJ+7LW59eFnUVfF4Wwhs23MceEqFQQtV7l7hHYz/z0zeN24J5TJOE2qZjaUOsGcSZ0ISDTIhe2dvpWrnmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/vinyl": "*" + } + }, "node_modules/@types/superagent": { "version": "8.1.9", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", @@ -3766,6 +3802,17 @@ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, + "node_modules/@types/vinyl": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/@types/vinyl/-/vinyl-2.0.12.tgz", + "integrity": "sha512-Sr2fYMBUVGYq8kj3UthXFAu5UN6ZW+rYr4NACjZQJvHvj+c8lYv0CahmZ2P/r7iUkN44gGUBwqxZkrKXYPb7cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/expect": "^1.20.4", + "@types/node": "*" + } + }, "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", @@ -4360,7 +4407,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4610,7 +4656,6 @@ "version": "0.2.6", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -4619,7 +4664,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, "engines": { "node": ">=0.8" } @@ -4679,7 +4723,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true, "engines": { "node": "*" } @@ -4687,8 +4730,7 @@ "node_modules/aws4": { "version": "1.13.2", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "dev": true + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==" }, "node_modules/axios": { "version": "1.13.2", @@ -4741,11 +4783,16 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } }, + "node_modules/bin-pack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bin-pack/-/bin-pack-1.0.2.tgz", + "integrity": "sha512-aOk0SxEon5LF9cMxQFViSKb4qccG6rs7XKyMXIb1J8f8LA2acTIWnHdT0IOTe4gYBbqgjdbuTZ5f+UP+vlh4Mw==", + "license": "MIT" + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -5099,8 +5146,7 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "node_modules/chalk": { "version": "4.1.2", @@ -5245,6 +5291,21 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", + "license": "MIT" + }, "node_modules/cluster-key-slot": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", @@ -5380,6 +5441,36 @@ "node": ">= 0.6" } }, + "node_modules/contentstream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/contentstream/-/contentstream-1.0.0.tgz", + "integrity": "sha512-jqWbfFZFG9tZbdej7+TzXI4kanABh3BLtTWY6NxqTK5zo6iTIeo5aq4iRVfYsLQ0y8ccQqmJR/J4NeMmEdnR2w==", + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.33-1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/contentstream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/contentstream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -5411,6 +5502,12 @@ "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/crc": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/crc/-/crc-4.3.2.tgz", @@ -5454,11 +5551,19 @@ "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==", "dev": true }, + "node_modules/cwise-compiler": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", + "integrity": "sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==", + "license": "MIT", + "dependencies": { + "uniq": "^1.0.0" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -5466,6 +5571,12 @@ "node": ">=0.10" } }, + "node_modules/data-uri-to-buffer": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-0.0.3.tgz", + "integrity": "sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==", + "license": "MIT" + }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -5707,7 +5818,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5716,8 +5826,7 @@ "node_modules/ecc-jsbn/node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/ee-first": { "version": "1.1.1", @@ -6769,14 +6878,12 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true, "engines": [ "node >=0.6.0" ] @@ -6789,8 +6896,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.3", @@ -6810,8 +6916,7 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -6977,6 +7082,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha512-ArRi5axuv66gEsyl3UuK80CzW7t56hem73YGNYxNWTGNKFJUadSb9Gu9SHijYEUi8ulQMf1bJomYNwSCPHhtTQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/fix-dts-default-cjs-exports": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", @@ -7063,7 +7177,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true, "engines": { "node": "*" } @@ -7211,6 +7324,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-pixels": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/get-pixels/-/get-pixels-3.3.3.tgz", + "integrity": "sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "0.0.3", + "jpeg-js": "^0.4.1", + "mime-types": "^2.0.1", + "ndarray": "^1.0.13", + "ndarray-pack": "^1.1.1", + "node-bitmap": "0.0.1", + "omggif": "^1.0.5", + "parse-data-uri": "^0.2.0", + "pngjs": "^3.3.3", + "request": "^2.44.0", + "through": "^2.3.4" + } + }, "node_modules/get-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", @@ -7256,11 +7388,39 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" } }, + "node_modules/gif-encoder": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/gif-encoder/-/gif-encoder-0.4.3.tgz", + "integrity": "sha512-HMfSa+EIng62NbDhM63QGYoc49/m8DcZ9hhBtw+CXX9mKboSpeFVxjZ2WEWaMFZ14MUjfACK7jsrxrJffIVrCg==", + "dependencies": { + "readable-stream": "~1.1.9" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/gif-encoder/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/gif-encoder/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -7367,7 +7527,6 @@ "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", @@ -7388,7 +7547,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true, "engines": { "node": ">=4" } @@ -7398,7 +7556,6 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", - "dev": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -7649,6 +7806,12 @@ "node": ">= 0.4" } }, + "node_modules/iota-array": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", + "integrity": "sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==", + "license": "MIT" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -7735,6 +7898,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, "node_modules/is-bun-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", @@ -8023,8 +8192,7 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-unicode-supported": { "version": "2.1.0", @@ -8039,6 +8207,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "license": "MIT" + }, "node_modules/is-weakmap": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", @@ -8082,6 +8256,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -8091,8 +8271,7 @@ "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "node_modules/iterator.prototype": { "version": "1.1.5", @@ -8192,6 +8371,12 @@ "node": ">=10" } }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "license": "BSD-3-Clause" + }, "node_modules/js-md4": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/js-md4/-/js-md4-0.3.2.tgz", @@ -8239,14 +8424,12 @@ "node_modules/json-schema": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -8257,8 +8440,7 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "node_modules/json5": { "version": "1.0.2", @@ -8335,6 +8517,17 @@ "json-buffer": "3.0.1" } }, + "node_modules/layout": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/layout/-/layout-2.2.0.tgz", + "integrity": "sha512-+kdgg25XW11BA4cl9vF+SH01HaBipld2Nf/PlU2kSYncAbdUbDoahzrlh6yhR93N/wR2TGgcFoxebzR1LKmZUg==", + "dependencies": { + "bin-pack": "~1.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -8875,6 +9068,35 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/ndarray": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.19.tgz", + "integrity": "sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==", + "license": "MIT", + "dependencies": { + "iota-array": "^1.0.0", + "is-buffer": "^1.0.2" + } + }, + "node_modules/ndarray-ops": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ndarray-ops/-/ndarray-ops-1.2.2.tgz", + "integrity": "sha512-BppWAFRjMYF7N/r6Ie51q6D4fs0iiGmeXIACKY66fLpnwIui3Wc3CXiD/30mgLbDjPpSLrsqcp3Z62+IcHZsDw==", + "license": "MIT", + "dependencies": { + "cwise-compiler": "^1.0.0" + } + }, + "node_modules/ndarray-pack": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ndarray-pack/-/ndarray-pack-1.2.1.tgz", + "integrity": "sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==", + "license": "MIT", + "dependencies": { + "cwise-compiler": "^1.1.2", + "ndarray": "^1.0.13" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -8886,8 +9108,7 @@ "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/newman": { "version": "6.2.1", @@ -9062,6 +9283,14 @@ "dev": true, "license": "MIT" }, + "node_modules/node-bitmap": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/node-bitmap/-/node-bitmap-0.0.1.tgz", + "integrity": "sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==", + "engines": { + "node": ">=v0.6.5" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -9401,7 +9630,15 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/obj-extend": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/obj-extend/-/obj-extend-0.1.0.tgz", + "integrity": "sha512-or9c7Ue2wWCun41DuLP3+LKEUjSZcDSxfCM4HZQSX9tcjLL/yuzTW7MmtVNs+MmN16uDRpDrFmFK/WVSm4vklg==", + "license": "MIT", "engines": { "node": "*" } @@ -9528,6 +9765,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "license": "MIT" + }, "node_modules/on-exit-leak-free": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", @@ -9750,6 +9993,15 @@ "node": ">=6" } }, + "node_modules/parse-data-uri": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/parse-data-uri/-/parse-data-uri-0.2.0.tgz", + "integrity": "sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==", + "license": "ISC", + "dependencies": { + "data-uri-to-buffer": "0.0.3" + } + }, "node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -9844,8 +10096,7 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "node_modules/picocolors": { "version": "1.1.1", @@ -9981,6 +10232,64 @@ "node": ">= 6" } }, + "node_modules/pixelsmith": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/pixelsmith/-/pixelsmith-2.6.0.tgz", + "integrity": "sha512-1W0C8EVxAPJwsCodw/+dfeEtdSc8JuHFipVylf51PIvh7S7Q33qmVCCzeWQp1y1sXpZ52iXGY2D/ICMyHPIULw==", + "dependencies": { + "async": "^3.2.3", + "concat-stream": "~1.5.1", + "get-pixels": "~3.3.0", + "mime-types": "~2.1.7", + "ndarray": "~1.0.15", + "obj-extend": "~0.1.0", + "save-pixels": "~2.3.0", + "vinyl-file": "~1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/pixelsmith/node_modules/concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha512-H6xsIBfQ94aESBG8jGHXQ7i5AEpy5ZeVaLDOisDICiTCKpqEfr34/KmTrspKQNoLKNu9gTkovlpQcUi630AKiQ==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "node_modules/pixelsmith/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/pixelsmith/node_modules/readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/pixelsmith/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/pjax": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/pjax/-/pjax-0.2.8.tgz", @@ -9999,6 +10308,25 @@ "pathe": "^2.0.1" } }, + "node_modules/pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pngjs-nozlib": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pngjs-nozlib/-/pngjs-nozlib-1.0.0.tgz", + "integrity": "sha512-N1PggqLp9xDqwAoKvGohmZ3m4/N9xpY0nDZivFqQLcpLHmliHnCp9BuNCsOeqHWMuEEgFjpEaq9dZq6RZyy0fA==", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -10509,6 +10837,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==", + "license": "MIT" + }, "node_modules/process-warning": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", @@ -10594,7 +10928,6 @@ "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", - "dev": true, "dependencies": { "punycode": "^2.3.1" }, @@ -10850,6 +11183,99 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/request/node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -11093,6 +11519,21 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/save-pixels": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/save-pixels/-/save-pixels-2.3.6.tgz", + "integrity": "sha512-/ayfEWBxt0tFpf5lxSU1S0+/TBn7EiaTZD+6GL+mwizHm3BKCBysnzT6Js7BusDUVcNVLkeJJKLZcBgdpM2leQ==", + "license": "MIT", + "dependencies": { + "contentstream": "^1.0.0", + "gif-encoder": "~0.4.1", + "jpeg-js": "^0.4.3", + "ndarray": "^1.0.18", + "ndarray-ops": "^1.2.2", + "pngjs-nozlib": "^1.0.0", + "through": "^2.3.4" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -11182,16 +11623,6 @@ "uuid": "^3.0.0" } }, - "node_modules/serialised-error/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/serve-static": { "version": "1.16.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", @@ -11428,7 +11859,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -11486,11 +11916,75 @@ "node": ">= 10.x" } }, + "node_modules/spritesmith": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/spritesmith/-/spritesmith-3.5.1.tgz", + "integrity": "sha512-FrzGx9cD5SkH3Kxuk24vJJLBYHLyDskUJ2t6DSWfWkCd8+yFQAfBGVE7F0IhOpKu+aq1CZ9rgXnpaa4luIQgGg==", + "license": "MIT", + "dependencies": { + "concat-stream": "~1.5.1", + "layout": "~2.2.0", + "pixelsmith": "^2.3.0", + "semver": "~5.7.2", + "through2": "~2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/spritesmith/node_modules/concat-stream": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", + "integrity": "sha512-H6xsIBfQ94aESBG8jGHXQ7i5AEpy5ZeVaLDOisDICiTCKpqEfr34/KmTrspKQNoLKNu9gTkovlpQcUi630AKiQ==", + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "node_modules/spritesmith/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/spritesmith/node_modules/readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/spritesmith/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/spritesmith/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -11514,8 +12008,7 @@ "node_modules/sshpk/node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/stable-hash-x": { "version": "0.2.0", @@ -11774,6 +12267,31 @@ "node": ">=4" } }, + "node_modules/strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha512-7jfJB9YpI2Z0aH3wu10ZqitvYJaE0s5IzFuWE+0pbb4Q/armTloEUShymkDO47YSLnjAW52mlXT//hs9wXNNJQ==", + "license": "MIT", + "dependencies": { + "first-chunk-stream": "^1.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom-stream/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -11988,6 +12506,55 @@ "real-require": "^0.2.0" } }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/through2/node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/tinyexec": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", @@ -12040,6 +12607,19 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/tr46": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", @@ -12722,11 +13302,22 @@ "fsevents": "~2.3.3" } }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "node_modules/type-check": { "version": "0.4.0", @@ -12880,7 +13471,6 @@ "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" @@ -12936,6 +13526,12 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==", + "license": "MIT" + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -13022,7 +13618,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -13058,6 +13653,16 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/uvm": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/uvm/-/uvm-2.1.1.tgz", @@ -13099,7 +13704,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, "engines": [ "node >=0.6.0" ], @@ -13112,8 +13716,54 @@ "node_modules/verror/node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha512-Ci3wnR2uuSAWFMSglZuB8Z2apBdtOyz8CV7dC6/U1XbltXBC+IuutUkXQISz01P+US2ouBuesSbV6zILZ6BuzQ==", + "license": "MIT", + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vinyl-file": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/vinyl-file/-/vinyl-file-1.3.0.tgz", + "integrity": "sha512-i1CGRaiDs3qJ+Yc8cgtOnrZOwlhY02oDBrWSBKD9uYSsxqQG1RhNXLmR/orke0ye0sbKpVtAUHwhF2rs9A46cQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "strip-bom": "^2.0.0", + "strip-bom-stream": "^1.0.0", + "vinyl": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl-file/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wasm-feature-detect": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz", + "integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ==", + "license": "Apache-2.0" }, "node_modules/webidl-conversions": { "version": "7.0.0", @@ -13255,8 +13905,7 @@ "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==" }, "node_modules/wrap-ansi": { "version": "8.1.0", @@ -13465,6 +14114,35 @@ "url": "https://github.com/sponsors/colinhacks" } }, + "packages/esbuild-plugin-oxipng": { + "name": "@repo/esbuild-plugin-oxipng", + "version": "0.0.0", + "hasInstallScript": true, + "dependencies": { + "@jsquash/oxipng": "^2.3.0", + "esbuild": "^0.25.4" + }, + "devDependencies": { + "@types/node": "^22.19.1", + "typescript": "^5.9.3" + } + }, + "packages/esbuild-plugin-spritesmith": { + "name": "@repo/esbuild-plugin-spritesmith", + "version": "0.0.0", + "hasInstallScript": true, + "dependencies": { + "esbuild": "^0.25.4", + "handlebars": "^4.7.8", + "pixelsmith": "^2.6.0", + "spritesmith": "^3.5.1" + }, + "devDependencies": { + "@types/node": "^22.19.1", + "@types/spritesmith": "^3.4.5", + "typescript": "^5.9.3" + } + }, "packages/grpc-client": { "name": "@repo/grpc-client", "version": "0.0.0", diff --git a/packages/esbuild-plugin-oxipng/package.json b/packages/esbuild-plugin-oxipng/package.json new file mode 100644 index 00000000..88e2eb72 --- /dev/null +++ b/packages/esbuild-plugin-oxipng/package.json @@ -0,0 +1,21 @@ +{ + "name": "@repo/esbuild-plugin-oxipng", + "private": true, + "version": "0.0.0", + "description": "ESBuild plugin to optimise PNG images", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "preinstall": "npm run build" + }, + "dependencies": { + "@jsquash/oxipng": "^2.3.0", + "esbuild": "^0.25.4" + }, + "devDependencies": { + "@types/node": "^22.19.1", + "typescript": "^5.9.3" + } +} diff --git a/packages/esbuild-plugin-oxipng/src/index.ts b/packages/esbuild-plugin-oxipng/src/index.ts new file mode 100644 index 00000000..209a3404 --- /dev/null +++ b/packages/esbuild-plugin-oxipng/src/index.ts @@ -0,0 +1,48 @@ +import { Loader, OnLoadArgs, OnLoadResult, OnStartResult, Plugin, PluginBuild } from 'esbuild'; +import { readFile } from 'node:fs/promises'; +// This is really what they recommend doing https://github.com/jamsinclair/jSquash/blob/main/examples/with-node/index.js +import { default as optimiseOxi, init as initOxi } from '@jsquash/oxipng/optimise.js'; +import { basename } from 'node:path'; +import { OptimiseOptions } from '@jsquash/oxipng/meta'; + +const NAMESPACE = 'esbuild-plugin-oxipng'; +const FILTER = /.png$/; + +export type Options = { + loader?: Loader, + opts?: Partial +} + +export function oxipng(options?: Options): Plugin { + const loader = options?.loader ?? 'file'; + const oxiOpts = options?.opts ?? { level: 3, optimiseAlpha: true }; + + async function onLoad(args: OnLoadArgs): Promise { + const data = await readFile(args.path); + const optimised = await optimiseOxi(data.buffer, oxiOpts); + console.log(`OXI ${basename(args.path)}: ${data.length}b -> ${optimised.byteLength}b`) + + return { + contents: new Uint8Array(optimised), + loader: loader, + pluginName: NAMESPACE, + } + } + + return { + name: NAMESPACE, + setup(build: PluginBuild) { + build.onLoad({ + filter: FILTER, + namespace: 'file', + }, onLoad) + } + } +} + +async function init() { + const wasmPath = new URL(import.meta.resolve('@jsquash/oxipng/codec/pkg/squoosh_oxipng_bg.wasm')); + const wasm = await readFile(wasmPath); + await initOxi(wasm); +} +await init(); diff --git a/packages/esbuild-plugin-oxipng/tsconfig.json b/packages/esbuild-plugin-oxipng/tsconfig.json new file mode 100644 index 00000000..a17d849e --- /dev/null +++ b/packages/esbuild-plugin-oxipng/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "skipLibCheck": true, + "declaration": true, + "module": "ES2022", + "target": "es2022", + "outDir": "dist", + "strict": true, + "noEmitOnError": true, + "esModuleInterop": true, + }, + "include": [ + "src" + ], + "exclude": [] +} \ No newline at end of file diff --git a/packages/esbuild-plugin-spritesmith/package.json b/packages/esbuild-plugin-spritesmith/package.json new file mode 100644 index 00000000..88f68382 --- /dev/null +++ b/packages/esbuild-plugin-spritesmith/package.json @@ -0,0 +1,24 @@ +{ + "name": "@repo/esbuild-plugin-spritesmith", + "private": true, + "version": "0.0.0", + "description": "ESBuild plugin to create spritesheets", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc -p tsconfig.json", + "preinstall": "npm run build" + }, + "dependencies": { + "esbuild": "^0.25.4", + "handlebars": "^4.7.8", + "pixelsmith": "^2.6.0", + "spritesmith": "^3.5.1" + }, + "devDependencies": { + "@types/node": "^22.19.1", + "@types/spritesmith": "^3.4.5", + "typescript": "^5.9.3" + } +} diff --git a/packages/esbuild-plugin-spritesmith/src/index.ts b/packages/esbuild-plugin-spritesmith/src/index.ts new file mode 100644 index 00000000..39922de7 --- /dev/null +++ b/packages/esbuild-plugin-spritesmith/src/index.ts @@ -0,0 +1,65 @@ +import { OnStartResult, Plugin, PluginBuild } from 'esbuild'; +import { readdir, writeFile } from 'node:fs/promises'; +import { basename } from 'node:path'; +import { promisify } from 'node:util'; +import Spritesmith from 'spritesmith'; +import Handlebars from 'handlebars'; + +const NAMESPACE = 'esbuild-plugin-spritesmith'; + +export type Options = { + input_folder: string, + output_css: string, + output_image: string, + output_image_url: string, +} + +export function spritesmith(options: Options): Plugin { + const { input_folder, output_css, output_image, output_image_url } = options; + + return { + name: NAMESPACE, + setup(build: PluginBuild) { + build.onStart(async (): Promise => { + const sprite_paths = (await readdir(input_folder)) + .filter(path => path.endsWith('.png')) + .map(path => input_folder + path); + + + const { coordinates, image } = await promisify(Spritesmith.run)({ + src: sprite_paths + }); + + const sprites = Object.entries(coordinates).map(([name, coords]) => { + return { + name: basename(name, '.png').replaceAll('_', ':'), + ...coords + }; + }); + + // make the css + const css = Handlebars.compile(` + /* This file is generated by @repo/esbuild-plugin-spritesmith */ + .sprite { + background-image: url(${output_image_url}); + } + {{#each sprites}} + .sprite.sp-{{name}} { + background-position: -{{x}}px -{{y}}px; + width: {{width}}px; + height: {{height}}px; + } + {{/each}} + `)({ sprites }); + + + await writeFile(output_css, css, { + encoding: 'utf-8' + }); + await writeFile(output_image, image); + console.info(`SMTH: wrote ${sprite_paths.length} sprites`); + return {}; + }); + } + } +} diff --git a/packages/esbuild-plugin-spritesmith/tsconfig.json b/packages/esbuild-plugin-spritesmith/tsconfig.json new file mode 100644 index 00000000..a17d849e --- /dev/null +++ b/packages/esbuild-plugin-spritesmith/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "moduleResolution": "node", + "skipLibCheck": true, + "declaration": true, + "module": "ES2022", + "target": "es2022", + "outDir": "dist", + "strict": true, + "noEmitOnError": true, + "esModuleInterop": true, + }, + "include": [ + "src" + ], + "exclude": [] +} \ No newline at end of file