
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
A set of tools for working with osu! storyboards.
npm i osbtools@latest
import { SbSprite, Storyboard } from "../src";
import { ESbLayer } from "../src/types/enums";
// create storyboard
const sb = new Storyboard();
// create sprite
const sprite = new SbSprite({ path: "bg.png", layer: ESbLayer.Foreground });
// add sprite to storyboard
sb.addElement(sprite);
// convert storyboard to .osb format
const osb = sb.toString();
import { SbSprite, SbVectorValue } from "../src";
import { ESbElementEasing, ESbLayer } from "../src/types/enums";
// create sprite
const sprite = new SbSprite({ path: "bg.png", layer: ESbLayer.Foreground });
sprite
// move sprite in X and Y axes
.move({
startTime: 0,
startPosition: new SbVectorValue({ x: 320, y: 240 })
})
// move sprite only in X axis
.moveX({
startTime: 0,
startPositionX: 320
})
// move sprite only in Y axis
.moveY({
startTime: 0,
startPositionY: 320
})
// proportional sprite scaling
.scale({
easing: ESbElementEasing.Linear,
startTime: 0,
endTime: 200,
startScale: 0,
endScale: 1
})
// change sprite transparency
.fade({
easing: ESbElementEasing.Linear,
startTime: 0,
endTime: 200,
startFade: 0,
endFade: 1
})
// sprite rotating
.rotate({
easing: ESbElementEasing.Linear,
startTime: 0,
endTime: 200,
startRotation: 0,
endRotation: 3.14
})
// vector sprite scaling by x and y axes
.scaleVec({
easing: ESbElementEasing.Linear,
startTime: 0,
endTime: 200,
startScaleVec: new SbVectorValue({ x: 1, y: 1 }),
endScaleVec: new SbVectorValue({ x: 1.5, y: 1 })
})
// change color of sprite
.color({
easing: ESbElementEasing.Linear,
startTime: 0,
endTime: 200,
startColor: new SbColorValue({ r: 255, g: 255, b: 255 }),
endColor: new SbColorValue({ r: 255, g: 255, b: 255 })
})
// horizontally flip sprite
.flipH({
startTime: 633191,
})
// vertically flip sprite
.flipV({
startTime: 633191,
})
// additive sprite effect
.additive({
startTime: 633191,
})
import { SbEmptyElement, SbSprite, SbVectorValue } from "../src";
import { ESbElementEasing, ESbLayer } from "../src/types/enums";
// create sprite
const sprite = new SbSprite({ path: "bg.png", layer: ESbLayer.Foreground });
// create loop
sprite
.loop({
startTime: 640000,
loopCount: 20,
loopedProperties: () => {
const loop = new SbEmptyElement();
loop
.scale({
startTime: 0,
endTime: 200,
startScale: 0.25,
endScale: 0.5
})
.move({
easing: ESbElementEasing.OutExpo,
startTime: 200,
endTime: 400,
startPosition: new SbVectorValue({ x: 320, y: 240 }),
endPosition: new SbVectorValue({ x: 500, y: 240 })
})
return loop.getProperties();
}
})
import { SbEmptyElement, SbSprite, SbVectorValue } from "../src";
import { ESbElementEasing, ESbLayer } from "../src/types/enums";
// create sprite
const sprite = new SbSprite({ path: "bg.png", layer: ESbLayer.Foreground });
// create trigger
sprite
.trigger({
triggerName: "Passing",
startTime: 0,
endTime: 10000,
triggeredProperties: () => {
const trigger = new SbEmptyElement();
trigger
.scale({
startTime: 0,
endTime: 200,
startScale: 0.25,
endScale: 0.5
})
.move({
easing: ESbElementEasing.OutExpo,
startTime: 200,
endTime: 400,
startPosition: new SbVectorValue({ x: 320, y: 240 }),
endPosition: new SbVectorValue({ x: 500, y: 240 })
});
return trigger.getProperties();
},
})
import { SbAnimation } from "../src";
import { ESbElementLoopType, ESbLayer } from "../src/types/enums";
// create sprite
const animation = new SbAnimation({ path: "bg.png", layer: ESbLayer.Background, frameCount: 20, frameDelay: 100, loopType: ESbElementLoopType.LoopForever });
import { SbSample } from "../src";
import { ESbLayerId } from "../src/types/enums";
// create sprite
const sound = new SbSample({ path: "audio.mp3", startTime: 906554, layer: ESbLayerId.Background, volume: 100 });
import { SbSample } from "../src";
import { ESbLayerId } from "../src/types/enums";
// get element type
const sound = new SbSample({ path: "audio.mp3", startTime: 906554, layer: ESbLayerId.Background, volume: 100 });
console.log(sound.getType()); // Sample
import { Storyboard } from "../src";
const osb = `
[Events]
//Background and Video events
//Storyboard Layer 0 (Background)
Animation,Background,Centre,"bg.png",320,240,20,100,LoopForever
M,0,633191,,320,240
T,Passing,0,10000
S,0,0,200,0.25,0.5
M,19,200,400,320,240,500,240
//Storyboard Layer 1 (Fail)
//Storyboard Layer 2 (Pass)
//Storyboard Layer 3 (Foreground)
//Storyboard Layer 4 (Overlay)
//Storyboard Sound Samples
`
// create parsed storyboard
const sb = new Storyboard(osb);
// create new parsed storyboard
const sb = new Storyboard();
const newSb = sb.parse(osb);
// get element's property
sb.getElement(2)?.getProperty(2);
// get element's group property
sb.getElement(2)?.getProperty<ESbElementProperty.L>(8).data.properties?.getProperty(0);
WIP
FAQs
A set of tools for working with osu! storyboards
We found that osbtools demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.