diff --git a/content/post/games/polizei/polizei.md b/content/post/games/polizei/polizei.md index 7eb715c..8b729af 100644 --- a/content/post/games/polizei/polizei.md +++ b/content/post/games/polizei/polizei.md @@ -10,3 +10,7 @@ categories: --- [Polizei Rennspiel](https://www.br0tkasten.de/html/polizei.html) + +## screenshots +![screenshot01](/image/polizei/screenshot01.png#center) +![screenshot02](/image/polizei/screenshot02.png#center) diff --git a/static/html/polizei.html b/static/html/polizei.html index cccc5a4..3e5e460 100644 --- a/static/html/polizei.html +++ b/static/html/polizei.html @@ -409,7 +409,7 @@ return new A(B,"base64").toString("binary")}:"object"==typeof t.base64js?functio return Promise.resolve(false); } }); - for (const extension of []) { + for (const extension of ["data:text/javascript;,(function%20(Scratch)%20%7B%0D%0A%20%20'use%20strict'%3B%0D%0A%0D%0A%20%20if%20(!Scratch.extensions.unsandboxed)%20%7B%0D%0A%20%20%20%20throw%20new%20Error('MouseCursor%20extension%20must%20be%20run%20unsandboxed')%3B%0D%0A%20%20%7D%0D%0A%0D%0A%20%20const%20lazilyCreatedCanvas%20%3D%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20%2F**%20%40type%20%7BHTMLCanvasElement%7D%20*%2F%0D%0A%20%20%20%20let%20canvas%20%3D%20null%3B%0D%0A%20%20%20%20%2F**%20%40type%20%7BCanvasRenderingContext2D%7D%20*%2F%0D%0A%20%20%20%20let%20ctx%20%3D%20null%3B%0D%0A%20%20%20%20%2F**%0D%0A%20%20%20%20%20*%20%40param%20%7Bnumber%7D%20width%0D%0A%20%20%20%20%20*%20%40param%20%7Bnumber%7D%20height%0D%0A%20%20%20%20%20*%20%40returns%20%7B%5BHTMLCanvasElement%2C%20CanvasRenderingContext2D%5D%7D%0D%0A%20%20%20%20%20*%2F%0D%0A%20%20%20%20return%20(width%2C%20height)%20%3D%3E%20%7B%0D%0A%20%20%20%20%20%20if%20(!canvas)%20%7B%0D%0A%20%20%20%20%20%20%20%20canvas%20%3D%20document.createElement('canvas')%3B%0D%0A%20%20%20%20%20%20%20%20ctx%20%3D%20canvas.getContext('2d')%3B%0D%0A%20%20%20%20%20%20%20%20if%20(!ctx)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20throw%20new%20Error('Could%20not%20get%202d%20rendering%20context')%3B%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%2F%2F%20Setting%20canvas%20size%20also%20clears%20it%0D%0A%20%20%20%20%20%20canvas.width%20%3D%20width%3B%0D%0A%20%20%20%20%20%20canvas.height%20%3D%20height%3B%0D%0A%20%20%20%20%20%20return%20%5Bcanvas%2C%20ctx%5D%3B%0D%0A%20%20%20%20%7D%3B%0D%0A%20%20%7D%3B%0D%0A%20%20const%20getRawSkinCanvas%20%3D%20lazilyCreatedCanvas()%3B%0D%0A%0D%0A%20%20%2F**%0D%0A%20%20%20*%20%40param%20%7BRenderWebGL.Skin%7D%20skin%0D%0A%20%20%20*%20%40returns%20%7Bstring%7D%20A%20data%3A%20URI%20for%20the%20skin.%0D%0A%20%20%20*%2F%0D%0A%20%20const%20encodeSkinToURL%20%3D%20(skin)%20%3D%3E%20%7B%0D%0A%20%20%20%20const%20svgSkin%20%3D%20%2F**%20%40type%20%7BRenderWebGL.SVGSkin%7D%20*%2F%20(skin)%3B%0D%0A%20%20%20%20if%20(svgSkin._svgImage)%20%7B%0D%0A%20%20%20%20%20%20%2F%2F%20This%20is%20an%20SVG%20skin%0D%0A%20%20%20%20%20%20return%20svgSkin._svgImage.src%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%2F%2F%20It's%20probably%20a%20bitmap%20skin.%0D%0A%20%20%20%20%2F%2F%20The%20most%20reliable%20way%20to%20get%20the%20bitmap%20in%20every%20runtime%20is%20through%20the%20silhouette.%0D%0A%20%20%20%20%2F%2F%20This%20is%20very%20slow%20and%20could%20involve%20reading%20the%20texture%20from%20the%20GPU.%0D%0A%20%20%20%20const%20silhouette%20%3D%20skin._silhouette%3B%0D%0A%20%20%20%20%2F%2F%20unlazy()%20only%20exists%20in%20TW%0D%0A%20%20%20%20%2F%2F%20%40ts-expect-error%0D%0A%20%20%20%20if%20(silhouette.unlazy)%20%7B%0D%0A%20%20%20%20%20%20%2F%2F%20%40ts-expect-error%0D%0A%20%20%20%20%20%20silhouette.unlazy()%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20const%20colorData%20%3D%20silhouette._colorData%3B%0D%0A%20%20%20%20const%20width%20%3D%20silhouette._width%3B%0D%0A%20%20%20%20const%20height%20%3D%20silhouette._height%3B%0D%0A%20%20%20%20const%20imageData%20%3D%20new%20ImageData(colorData%2C%20silhouette._width%2C%20silhouette._height)%3B%0D%0A%20%20%20%20const%20%5Bcanvas%2C%20ctx%5D%20%3D%20getRawSkinCanvas(width%2C%20height)%3B%0D%0A%20%20%20%20ctx.putImageData(imageData%2C%200%2C%200)%3B%0D%0A%20%20%20%20return%20canvas.toDataURL()%3B%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20%2F**%0D%0A%20%20%20*%20%40param%20%7BVM.Costume%7D%20costume%0D%0A%20%20%20*%20%40param%20%7Bnumber%7D%20maxWidth%0D%0A%20%20%20*%20%40param%20%7Bnumber%7D%20maxHeight%0D%0A%20%20%20*%20%40returns%20%7B%7Buri%3A%20string%2C%20width%3A%20number%2C%20height%3A%20number%7D%7D%0D%0A%20%20%20*%2F%0D%0A%20%20const%20costumeToCursor%20%3D%20(costume%2C%20maxWidth%2C%20maxHeight)%20%3D%3E%20%7B%0D%0A%20%20%20%20const%20skin%20%3D%20Scratch.vm.renderer._allSkins%5Bcostume.skinId%5D%3B%0D%0A%20%20%20%20const%20imageURI%20%3D%20encodeSkinToURL(skin)%3B%0D%0A%0D%0A%20%20%20%20let%20width%20%3D%20skin.size%5B0%5D%3B%0D%0A%20%20%20%20let%20height%20%3D%20skin.size%5B1%5D%3B%0D%0A%20%20%20%20if%20(width%20%3E%20maxWidth)%20%7B%0D%0A%20%20%20%20%20%20height%20%3D%20height%20*%20(maxWidth%20%2F%20width)%3B%0D%0A%20%20%20%20%20%20width%20%3D%20maxWidth%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20if%20(height%20%3E%20maxHeight)%20%7B%0D%0A%20%20%20%20%20%20width%20%3D%20width%20*%20(maxHeight%20%2F%20height)%3B%0D%0A%20%20%20%20%20%20height%20%3D%20maxHeight%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%20%20width%20%3D%20Math.round(width)%3B%0D%0A%20%20%20%20height%20%3D%20Math.round(height)%3B%0D%0A%0D%0A%20%20%20%20%2F%2F%20We%20wrap%20the%20encoded%20image%20in%20an%20%3Csvg%3E.%20This%20lets%20us%20do%20some%20clever%20things%3A%0D%0A%20%20%20%20%2F%2F%20%20-%20We%20can%20resize%20the%20image%20without%20a%20canvas.%0D%0A%20%20%20%20%2F%2F%20%20-%20We%20can%20give%20the%20browser%20an%20image%20with%20more%20raw%20pixels%20than%20its%20DPI%20independent%20size.%0D%0A%20%20%20%20%2F%2F%20The%20latter%20is%20important%20so%20that%20cursors%20won't%20look%20horrible%20on%20high%20DPI%20displays.%20For%0D%0A%20%20%20%20%2F%2F%20example%2C%20if%20the%20cursor%20will%20display%20at%2032x32%20in%20DPI%20independent%20units%20on%20a%202x%20high%20DPI%0D%0A%20%20%20%20%2F%2F%20display%2C%20we%20actually%20need%20to%20send%20a%2064x64%20image%20for%20it%20to%20look%20good.%20This%20lets%20us%20do%0D%0A%20%20%20%20%2F%2F%20that%20automatically.%0D%0A%20%20%20%20let%20svg%20%3D%20%60%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22%24%7Bwidth%7D%22%20height%3D%22%24%7Bheight%7D%22%3E%60%3B%0D%0A%20%20%20%20svg%20%2B%3D%20%60%3Cimage%20href%3D%22%24%7BimageURI%7D%22%20width%3D%22%24%7Bwidth%7D%22%20height%3D%22%24%7Bheight%7D%22%20%2F%3E%60%3B%0D%0A%20%20%20%20svg%20%2B%3D%20'%3C%2Fsvg%3E'%3B%0D%0A%20%20%20%20%2F%2F%20URI%20encoding%20usually%20results%20in%20smaller%20string%20than%20base%2064%20for%20the%20types%20of%20data%20we%20get%20here.%0D%0A%20%20%20%20const%20svgURI%20%3D%20%60data%3Aimage%2Fsvg%2Bxml%3B%2C%24%7BencodeURIComponent(svg)%7D%60%3B%0D%0A%0D%0A%20%20%20%20return%20%7B%0D%0A%20%20%20%20%20%20uri%3A%20svgURI%2C%0D%0A%20%20%20%20%20%20width%2C%0D%0A%20%20%20%20%20%20height%0D%0A%20%20%20%20%7D%3B%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20%2F**%20%40type%20%7Bstring%7D%20*%2F%0D%0A%20%20let%20nativeCursor%20%3D%20'default'%3B%0D%0A%20%20%2F**%20%40type%20%7Bnull%7Cstring%7D%20*%2F%0D%0A%20%20let%20customCursorImageName%20%3D%20null%3B%0D%0A%0D%0A%20%20const%20canvas%20%3D%20Scratch.renderer.canvas%3B%0D%0A%20%20%2F**%20%40type%20%7Bstring%7D%20*%2F%0D%0A%20%20let%20currentCanvasCursor%20%3D%20nativeCursor%3B%0D%0A%20%20const%20updateCanvasCursor%20%3D%20()%20%3D%3E%20%7B%0D%0A%20%20%20%20if%20(canvas.style.cursor%20!%3D%3D%20currentCanvasCursor)%20%7B%0D%0A%20%20%20%20%20%20canvas.style.cursor%20%3D%20currentCanvasCursor%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20%2F%2F%20scratch-gui%20will%20sometimes%20reset%20the%20cursor%20when%20resizing%20the%20window%20or%20going%20in%2Fout%20of%20fullscreen%0D%0A%20%20new%20MutationObserver(updateCanvasCursor).observe(canvas%2C%20%7B%0D%0A%20%20%20%20attributeFilter%3A%20%5B'style'%5D%2C%0D%0A%20%20%20%20attributes%3A%20true%0D%0A%20%20%7D)%3B%0D%0A%0D%0A%20%20%2F**%0D%0A%20%20%20*%20Parse%20strings%20like%20%2260x12%22%20or%20%2277%2C1%22%0D%0A%20%20%20*%20%40param%20%7Bstring%7D%20string%0D%0A%20%20%20*%20%40returns%20%7B%5Bnumber%2C%20number%5D%7D%0D%0A%20%20%20*%2F%0D%0A%20%20const%20parseTuple%20%3D%20(string)%20%3D%3E%20%7B%0D%0A%20%20%20%20const%20%5Ba%2C%20b%5D%20%3D%20(''%20%2B%20string).split(%2F%5B%20%2Cx%5D%2F)%3B%0D%0A%20%20%20%20return%20%5B%0D%0A%20%20%20%20%20%20%2Ba%20%7C%7C%200%2C%0D%0A%20%20%20%20%20%20%2Bb%20%7C%7C%200%0D%0A%20%20%20%20%5D%3B%0D%0A%20%20%7D%3B%0D%0A%0D%0A%20%20class%20MouseCursor%20%7B%0D%0A%20%20%20%20getInfo()%20%7B%0D%0A%20%20%20%20%20%20return%20%7B%0D%0A%20%20%20%20%20%20%20%20id%3A%20'MouseCursor'%2C%0D%0A%20%20%20%20%20%20%20%20name%3A%20'Mouse%20Cursor'%2C%0D%0A%20%20%20%20%20%20%20%20blocks%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20'setCur'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.COMMAND%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20'set%20cursor%20to%20%5Bcur%5D'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20cur%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultValue%3A%20'pointer'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20'cursors'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20'setCursorImage'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.COMMAND%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20%22set%20cursor%20to%20current%20costume%20center%3A%20%5Bposition%5D%20max%20size%3A%20%5Bsize%5D%22%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20arguments%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20position%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultValue%3A%20'0%2C0'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20'imagePositions'%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20size%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20type%3A%20Scratch.ArgumentType.STRING%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20defaultValue%3A%20'32x32'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20menu%3A%20'imageSizes'%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20'hideCur'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.COMMAND%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20'hide%20cursor'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20opcode%3A%20'getCur'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20blockType%3A%20Scratch.BlockType.REPORTER%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20'cursor'%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20menus%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20cursors%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20true%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'default'%2C%20value%3A%20'default'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'pointer'%2C%20value%3A%20'pointer'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'move'%2C%20value%3A%20'move'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'grab'%2C%20value%3A%20'grab'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'grabbing'%2C%20value%3A%20'grabbing'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'text'%2C%20value%3A%20'text'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'vertical-text'%2C%20value%3A%20'vertical-text'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'wait'%2C%20value%3A%20'wait'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'progress'%2C%20value%3A%20'progress'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'help'%2C%20value%3A%20'help'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'context-menu'%2C%20value%3A%20'context-menu'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'zoom-in'%2C%20value%3A%20'zoom-in'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'zoom-out'%2C%20value%3A%20'zoom-out'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'crosshair'%2C%20value%3A%20'crosshair'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'cell'%2C%20value%3A%20'cell'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'not-allowed'%2C%20value%3A%20'not-allowed'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'copy'%2C%20value%3A%20'copy'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'alias'%2C%20value%3A%20'alias'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'no-drop'%2C%20value%3A%20'no-drop'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'all-scroll'%2C%20value%3A%20'all-scroll'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'col-resize'%2C%20value%3A%20'col-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'row-resize'%2C%20value%3A%20'row-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'n-resize'%2C%20value%3A%20'n-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'e-resize'%2C%20value%3A%20'e-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20's-resize'%2C%20value%3A%20's-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'w-resize'%2C%20value%3A%20'w-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'ne-resize'%2C%20value%3A%20'ne-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'nw-resize'%2C%20value%3A%20'nw-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'se-resize'%2C%20value%3A%20'se-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'sw-resize'%2C%20value%3A%20'sw-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'ew-resize'%2C%20value%3A%20'ew-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'ns-resize'%2C%20value%3A%20'ns-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'nesw-resize'%2C%20value%3A%20'nesw-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'nwse-resize'%2C%20value%3A%20'nwse-resize'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20imagePositions%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20true%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20%5Bx%2C%20y%5D%20where%20x%20is%20%5B0%3Dleft%2C%20100%3Dright%5D%20and%20y%20is%20%5B0%3Dtop%2C%20100%3Dbottom%5D%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'top%20left'%2C%20value%3A%20'0%2C0'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'top%20right'%2C%20value%3A%20'100%2C0'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'bottom%20left'%2C%20value%3A%20'0%2C100'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'bottom%20right'%2C%20value%3A%20'100%2C100'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'center'%2C%20value%3A%20'50%2C50'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20imageSizes%3A%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20acceptReporters%3A%20true%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20items%3A%20%5B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Some%20important%20numbers%20to%20keep%20in%20mind%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Browsers%20ignore%20cursor%20images%20%3E128%20in%20any%20dimension%20(https%3A%2F%2Fsearchfox.org%2Fmozilla-central%2Frev%2F43ee5e789b079e94837a21336e9ce2420658fd19%2Fwidget%2Fgtk%2FnsWindow.cpp%233393-3402)%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20Browsers%20may%20refuse%20to%20display%20a%20cursor%20near%20window%20borders%20for%20images%20%3E32%20in%20any%20dimension%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'4x4'%2C%20value%3A%20'4x4'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'8x8'%2C%20value%3A%20'8x4'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'12x12'%2C%20value%3A%20'12x12'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'16x16'%2C%20value%3A%20'16x16'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'32x32'%2C%20value%3A%20'32x32'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'48x48%20(unreliable)'%2C%20value%3A%20'48x48'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'64x64%20(unreliable)'%2C%20value%3A%20'64x64'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%20text%3A%20'128x128%20(unreliable)'%2C%20value%3A%20'128x128'%20%7D%2C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0D%0A%20%20%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20%20%20%7D%2C%0D%0A%20%20%20%20%20%20%7D%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20setCur(args)%20%7B%0D%0A%20%20%20%20%20%20const%20newCursor%20%3D%20args.cur%3B%0D%0A%20%20%20%20%20%20nativeCursor%20%3D%20newCursor%3B%0D%0A%20%20%20%20%20%20customCursorImageName%20%3D%20null%3B%0D%0A%20%20%20%20%20%20currentCanvasCursor%20%3D%20newCursor%3B%0D%0A%20%20%20%20%20%20updateCanvasCursor()%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20setCursorImage(args%2C%20util)%20%7B%0D%0A%20%20%20%20%20%20const%20%5BmaxWidth%2C%20maxHeight%5D%20%3D%20parseTuple(args.size).map(i%20%3D%3E%20Math.max(0%2C%20i))%3B%0D%0A%0D%0A%20%20%20%20%20%20const%20currentCostume%20%3D%20util.target.getCostumes()%5Butil.target.currentCostume%5D%3B%0D%0A%20%20%20%20%20%20const%20costumeName%20%3D%20currentCostume.name%3B%0D%0A%0D%0A%20%20%20%20%20%20let%20encodedCostume%3B%0D%0A%20%20%20%20%20%20try%20%7B%0D%0A%20%20%20%20%20%20%20%20encodedCostume%20%3D%20costumeToCursor(currentCostume%2C%20maxWidth%2C%20maxHeight)%3B%0D%0A%20%20%20%20%20%20%7D%20catch%20(e)%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20This%20could%20happen%20for%20a%20variety%20of%20reasons.%0D%0A%20%20%20%20%20%20%20%20console.error(e)%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%20%20if%20(encodedCostume)%20%7B%0D%0A%20%20%20%20%20%20%20%20const%20%5BpercentX%2C%20percentY%5D%20%3D%20parseTuple(args.position).map(i%20%3D%3E%20Math.max(0%2C%20Math.min(100%2C%20i))%20%2F%20100)%3B%0D%0A%20%20%20%20%20%20%20%20const%20x%20%3D%20percentX%20*%20encodedCostume.width%3B%0D%0A%20%20%20%20%20%20%20%20const%20y%20%3D%20percentY%20*%20encodedCostume.height%3B%0D%0A%0D%0A%20%20%20%20%20%20%20%20currentCanvasCursor%20%3D%20%60url(%22%24%7BencodedCostume.uri%7D%22)%20%24%7Bx%7D%20%24%7By%7D%2C%20%24%7BnativeCursor%7D%60%3B%0D%0A%20%20%20%20%20%20%20%20updateCanvasCursor()%3B%0D%0A%20%20%20%20%20%20%7D%20else%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20If%20for%20some%20reason%20the%20costume%20couldn't%20be%20encoded%2C%20we'll%20leave%20the%20cursor%20unchanged.%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20This%20is%20the%20same%20behavior%20that%20would%20happen%20if%20we%20successfully%20encode%20a%20cursor%20but%20the%20browser%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20is%20unable%20to%20parse%20it%20for%20some%20reason.%0D%0A%20%20%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20%20%20customCursorImageName%20%3D%20costumeName%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20hideCur()%20%7B%0D%0A%20%20%20%20%20%20this.setCur(%7B%0D%0A%20%20%20%20%20%20%20%20cur%3A%20'none'%0D%0A%20%20%20%20%20%20%7D)%3B%0D%0A%20%20%20%20%7D%0D%0A%0D%0A%20%20%20%20getCur()%20%7B%0D%0A%20%20%20%20%20%20if%20(customCursorImageName%20!%3D%3D%20null)%20%7B%0D%0A%20%20%20%20%20%20%20%20return%20customCursorImageName%3B%0D%0A%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%20%20return%20nativeCursor%3B%0D%0A%20%20%20%20%7D%0D%0A%20%20%7D%0D%0A%0D%0A%20%20Scratch.extensions.register(new%20MouseCursor())%3B%0D%0A%7D)(Scratch)%3B%0D%0A"]) { vm.extensionManager.loadExtensionURL(extension); } @@ -418,7 +418,7 @@ return new A(B,"base64").toString("binary")}:"object"==typeof t.base64js?functio } - +