Full Code of karaoke-dev/karaoke for AI

master 38296c690f56 cached
1273 files
3.3 MB
937.1k tokens
6689 symbols
1 requests
Download .txt
Showing preview only (3,747K chars total). Download the full file or copy to clipboard to get everything.
Repository: karaoke-dev/karaoke
Branch: master
Commit: 38296c690f56
Files: 1273
Total size: 3.3 MB

Directory structure:
gitextract_yy2emyho/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── labeler.yml
│   └── workflows/
│       ├── ci.yml
│       ├── crowdin.yml
│       ├── dotnet-format.yml
│       ├── labeler.yml
│       └── release.yml
├── .gitignore
├── .globalconfig
├── CONTRIBUTING.md
├── CodeAnalysis/
│   ├── BannedSymbols.txt
│   └── osu.ruleset
├── Directory.Build.props
├── LICENSE
├── README.md
├── appveyor.yml
├── cake.config
├── osu.Game.Rulesets.Karaoke/
│   ├── Beatmaps/
│   │   ├── ElementId.cs
│   │   ├── Formats/
│   │   │   ├── KaraokeJsonBeatmapDecoder.cs
│   │   │   ├── KaraokeJsonBeatmapEncoder.cs
│   │   │   ├── KaraokeLegacyBeatmapDecoder.cs
│   │   │   └── KaraokeLegacyBeatmapEncoder.cs
│   │   ├── IHasPrimaryKey.cs
│   │   ├── IKaraokeBeatmapResourcesProvider.cs
│   │   ├── KaraokeBeatmap.cs
│   │   ├── KaraokeBeatmapConverter.cs
│   │   ├── KaraokeBeatmapExtension.cs
│   │   ├── KaraokeBeatmapProcessor.cs
│   │   ├── KaraokeBeatmapResourcesProvider.cs
│   │   ├── Metadatas/
│   │   │   ├── NoteInfo.cs
│   │   │   ├── Page.cs
│   │   │   ├── PageInfo.cs
│   │   │   ├── Singer.cs
│   │   │   ├── SingerInfo.cs
│   │   │   ├── SingerState.cs
│   │   │   └── Types/
│   │   │       └── ISinger.cs
│   │   └── Utils/
│   │       └── SingerUtils.cs
│   ├── Bindables/
│   │   ├── BindableCultureInfo.cs
│   │   └── BindableFontUsage.cs
│   ├── Configuration/
│   │   ├── KaraokeRulesetConfigManager.cs
│   │   ├── KaraokeRulesetEditCheckerConfigManager.cs
│   │   ├── KaraokeRulesetEditConfigManager.cs
│   │   ├── KaraokeRulesetEditGeneratorConfigManager.cs
│   │   ├── KaraokeRulesetLyricEditorConfigManager.cs
│   │   └── KaraokeSessionStatics.cs
│   ├── Difficulty/
│   │   ├── KaraokeDifficultyAttributes.cs
│   │   ├── KaraokeDifficultyCalculator.cs
│   │   ├── KaraokePerformanceAttributes.cs
│   │   ├── KaraokePerformanceCalculator.cs
│   │   ├── Preprocessing/
│   │   │   └── KaraokeDifficultyHitObject.cs
│   │   └── Skills/
│   │       └── Strain.cs
│   ├── Edit/
│   │   ├── Blueprints/
│   │   │   ├── KaraokeSelectionBlueprint.cs
│   │   │   ├── Lyrics/
│   │   │   │   └── LyricSelectionBlueprint.cs
│   │   │   └── Notes/
│   │   │       ├── Components/
│   │   │       │   └── EditBodyPiece.cs
│   │   │       └── NoteSelectionBlueprint.cs
│   │   ├── ChangeHandlers/
│   │   │   ├── BeatmapListPropertyChangeHandler.cs
│   │   │   ├── BeatmapPropertyChangeHandler.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPagesChangeHandler.cs
│   │   │   │   ├── BeatmapSingersChangeHandler.cs
│   │   │   │   ├── BeatmapTranslationsChangeHandler.cs
│   │   │   │   ├── IBeatmapPagesChangeHandler.cs
│   │   │   │   ├── IBeatmapSingersChangeHandler.cs
│   │   │   │   └── IBeatmapTranslationsChangeHandler.cs
│   │   │   ├── ChangeForbiddenException.cs
│   │   │   ├── HitObjectChangeHandler.cs
│   │   │   ├── HitObjectPropertyChangeHandler.cs
│   │   │   ├── HitObjectsChangeHandler.cs
│   │   │   ├── IAutoGenerateChangeHandler.cs
│   │   │   ├── IHitObjectPropertyChangeHandler.cs
│   │   │   ├── IImportBeatmapChangeHandler.cs
│   │   │   ├── ILockChangeHandler.cs
│   │   │   ├── ImportBeatmapChangeHandler.cs
│   │   │   ├── LockChangeHandler.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── ILyricLanguageChangeHandler.cs
│   │   │   │   ├── ILyricListPropertyChangeHandler.cs
│   │   │   │   ├── ILyricPropertyAutoGenerateChangeHandler.cs
│   │   │   │   ├── ILyricPropertyChangeHandler.cs
│   │   │   │   ├── ILyricReferenceChangeHandler.cs
│   │   │   │   ├── ILyricRubyTagsChangeHandler.cs
│   │   │   │   ├── ILyricSingerChangeHandler.cs
│   │   │   │   ├── ILyricTextChangeHandler.cs
│   │   │   │   ├── ILyricTimeTagsChangeHandler.cs
│   │   │   │   ├── ILyricTranslationChangeHandler.cs
│   │   │   │   ├── ILyricsChangeHandler.cs
│   │   │   │   ├── LyricLanguageChangeHandler.cs
│   │   │   │   ├── LyricPropertyAutoGenerateChangeHandler.cs
│   │   │   │   ├── LyricPropertyChangeHandler.cs
│   │   │   │   ├── LyricReferenceChangeHandler.cs
│   │   │   │   ├── LyricRubyTagsChangeHandler.cs
│   │   │   │   ├── LyricSingerChangeHandler.cs
│   │   │   │   ├── LyricTextChangeHandler.cs
│   │   │   │   ├── LyricTimeTagsChangeHandler.cs
│   │   │   │   ├── LyricTranslationChangeHandler.cs
│   │   │   │   └── LyricsChangeHandler.cs
│   │   │   ├── Notes/
│   │   │   │   ├── INotePropertyChangeHandler.cs
│   │   │   │   ├── INotesChangeHandler.cs
│   │   │   │   ├── NotePropertyChangeHandler.cs
│   │   │   │   └── NotesChangeHandler.cs
│   │   │   └── Stages/
│   │   │       ├── ClassicStageChangeHandler.cs
│   │   │       ├── IClassicStageChangeHandler.cs
│   │   │       ├── IStageElementCategoryChangeHandler.cs
│   │   │       ├── IStagesChangeHandler.cs
│   │   │       ├── StageElementCategoryChangeHandler.cs
│   │   │       ├── StagePropertyChangeHandler.cs
│   │   │       └── StagesChangeHandler.cs
│   │   ├── Checks/
│   │   │   ├── CheckBeatmapAvailableTranslations.cs
│   │   │   ├── CheckBeatmapNoteInfo.cs
│   │   │   ├── CheckBeatmapPageInfo.cs
│   │   │   ├── CheckBeatmapProperty.cs
│   │   │   ├── CheckClassicStageInfo.cs
│   │   │   ├── CheckHitObjectProperty.cs
│   │   │   ├── CheckHitObjectReferenceProperty.cs
│   │   │   ├── CheckLyricLanguage.cs
│   │   │   ├── CheckLyricReferenceLyric.cs
│   │   │   ├── CheckLyricRubyTag.cs
│   │   │   ├── CheckLyricSinger.cs
│   │   │   ├── CheckLyricText.cs
│   │   │   ├── CheckLyricTimeTag.cs
│   │   │   ├── CheckLyricTranslations.cs
│   │   │   ├── CheckNoteReferenceLyric.cs
│   │   │   ├── CheckNoteText.cs
│   │   │   ├── CheckNoteTime.cs
│   │   │   ├── CheckStageInfo.cs
│   │   │   └── Issues/
│   │   │       ├── BeatmapClassicLyricTimingPointIssue.cs
│   │   │       ├── BeatmapPageIssue.cs
│   │   │       ├── LyricIssue.cs
│   │   │       ├── LyricRubyTagIssue.cs
│   │   │       ├── LyricTimeTagIssue.cs
│   │   │       └── NoteIssue.cs
│   │   ├── Components/
│   │   │   ├── ContextMenu/
│   │   │   │   ├── LyricLockContextMenu.cs
│   │   │   │   └── SingerContextMenu.cs
│   │   │   ├── Cursor/
│   │   │   │   └── TimeTagTooltip.cs
│   │   │   ├── Menus/
│   │   │   │   ├── KaraokeEditorMenu.cs
│   │   │   │   └── KaraokeSkinEditorMenu.cs
│   │   │   └── Sprites/
│   │   │       ├── DrawableTextIndex.cs
│   │   │       └── DrawableTimeTag.cs
│   │   ├── Debugging/
│   │   │   └── DebugBeatmapManager.cs
│   │   ├── DrawableKaraokeEditorRuleset.cs
│   │   ├── EditorNotePlayfield.cs
│   │   ├── Export/
│   │   │   └── ExportLyricManager.cs
│   │   ├── Generator/
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPropertyDetector.cs
│   │   │   │   ├── BeatmapPropertyGenerator.cs
│   │   │   │   └── Pages/
│   │   │   │       ├── PageGenerator.cs
│   │   │   │       └── PageGeneratorConfig.cs
│   │   │   ├── ConfigCategoryAttribute.cs
│   │   │   ├── ConfigSourceAttribute.cs
│   │   │   ├── DetectorNotSupportedException.cs
│   │   │   ├── GeneratorConfig.cs
│   │   │   ├── GeneratorConfigExtension.cs
│   │   │   ├── GeneratorNotSupportedException.cs
│   │   │   ├── GeneratorSelector.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── Language/
│   │   │   │   │   ├── LanguageDetector.cs
│   │   │   │   │   └── LanguageDetectorConfig.cs
│   │   │   │   ├── LyricGeneratorSelector.cs
│   │   │   │   ├── LyricPropertyDetector.cs
│   │   │   │   ├── LyricPropertyGenerator.cs
│   │   │   │   ├── Notes/
│   │   │   │   │   ├── NoteGenerator.cs
│   │   │   │   │   └── NoteGeneratorConfig.cs
│   │   │   │   ├── ReferenceLyric/
│   │   │   │   │   ├── ReferenceLyricDetector.cs
│   │   │   │   │   └── ReferenceLyricDetectorConfig.cs
│   │   │   │   ├── Romanisation/
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   ├── JaRomanisationGenerator.cs
│   │   │   │   │   │   └── JaRomanisationGeneratorConfig.cs
│   │   │   │   │   ├── RomanisationGenerateResult.cs
│   │   │   │   │   ├── RomanisationGenerator.cs
│   │   │   │   │   ├── RomanisationGeneratorConfig.cs
│   │   │   │   │   └── RomanisationGeneratorSelector.cs
│   │   │   │   ├── RubyTags/
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   ├── JaRubyTagGenerator.cs
│   │   │   │   │   │   └── JaRubyTagGeneratorConfig.cs
│   │   │   │   │   ├── RubyTagGenerator.cs
│   │   │   │   │   ├── RubyTagGeneratorConfig.cs
│   │   │   │   │   └── RubyTagGeneratorSelector.cs
│   │   │   │   └── TimeTags/
│   │   │   │       ├── Ja/
│   │   │   │       │   ├── JaTimeTagGenerator.cs
│   │   │   │       │   └── JaTimeTagGeneratorConfig.cs
│   │   │   │       ├── TimeTagGenerator.cs
│   │   │   │       ├── TimeTagGeneratorConfig.cs
│   │   │   │       ├── TimeTagGeneratorSelector.cs
│   │   │   │       └── Zh/
│   │   │   │           ├── ZhTimeTagGenerator.cs
│   │   │   │           └── ZhTimeTagGeneratorConfig.cs
│   │   │   ├── PropertyDetector.cs
│   │   │   ├── PropertyGenerator.cs
│   │   │   └── Stages/
│   │   │       ├── Classic/
│   │   │       │   ├── ClassicLyricLayoutCategoryGenerator.cs
│   │   │       │   ├── ClassicLyricLayoutCategoryGeneratorConfig.cs
│   │   │       │   ├── ClassicLyricTimingInfoGenerator.cs
│   │   │       │   ├── ClassicLyricTimingInfoGeneratorConfig.cs
│   │   │       │   ├── ClassicStageInfoGenerator.cs
│   │   │       │   └── ClassicStageInfoGeneratorConfig.cs
│   │   │       ├── Preview/
│   │   │       │   ├── PreviewStageInfoGenerator.cs
│   │   │       │   └── PreviewStageInfoGeneratorConfig.cs
│   │   │       ├── StageInfoGenerator.cs
│   │   │       ├── StageInfoGeneratorConfig.cs
│   │   │       ├── StageInfoGeneratorSelector.cs
│   │   │       └── StageInfoPropertyGenerator.cs
│   │   ├── KaraokeBeatmapVerifier.cs
│   │   ├── KaraokeBlueprintContainer.cs
│   │   ├── KaraokeEditorPlayfield.cs
│   │   ├── KaraokeHitObjectComposer.cs
│   │   ├── KaraokeSelectionHandler.cs
│   │   ├── Setup/
│   │   │   ├── Components/
│   │   │   │   ├── FormLanguageList.cs
│   │   │   │   └── FormSingerList.cs
│   │   │   ├── KaraokeNoteSection.cs
│   │   │   ├── KaraokeSingerSection.cs
│   │   │   └── KaraokeTranslationSection.cs
│   │   └── Utils/
│   │       ├── EditorBeatmapUtils.cs
│   │       ├── HitObjectWritableUtils.cs
│   │       ├── LockStateUtils.cs
│   │       ├── ValueChangedEventUtils.cs
│   │       └── ZoomableScrollContainerUtils.cs
│   ├── Extensions/
│   │   ├── EnumerableExtensions.cs
│   │   ├── OsuGameExtensions.cs
│   │   ├── RegexExtensions.cs
│   │   ├── ScrollContainerExtensions.cs
│   │   ├── TrickyCompositeDrawableExtension.cs
│   │   └── TypeExtensions.cs
│   ├── Flags/
│   │   └── FlagState.cs
│   ├── Graphics/
│   │   ├── Containers/
│   │   │   ├── OrderRearrangeableListContainer.cs
│   │   │   └── RearrangeableTextFlowListContainer.cs
│   │   ├── Cursor/
│   │   │   ├── BackgroundToolTip.cs
│   │   │   ├── LyricToolTip.cs
│   │   │   └── SingerToolTip.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableCircleSingerAvatar.cs
│   │   │   ├── DrawableSingerAvatar.cs
│   │   │   └── SingerDisplay.cs
│   │   ├── KaraokeIcon.cs
│   │   ├── Shapes/
│   │   │   ├── CornerBackground.cs
│   │   │   └── RightTriangle.cs
│   │   ├── Sprites/
│   │   │   ├── DisplayLyricProcessor.cs
│   │   │   ├── DrawableKaraokeSpriteText.cs
│   │   │   ├── DrawableLyricSpriteText.cs
│   │   │   ├── LyricDisplayProperty.cs
│   │   │   ├── LyricDisplayType.cs
│   │   │   ├── LyricStyle.cs
│   │   │   └── Processor/
│   │   │       ├── BaseDisplayProcessor.cs
│   │   │       ├── LyricFirstDisplayProcessor.cs
│   │   │       └── RomanisedSyllableFirstDisplayProcessor.cs
│   │   ├── UserInterface/
│   │   │   ├── BindableBoolMenuItem.cs
│   │   │   └── BindableEnumMenuItem.cs
│   │   └── UserInterfaceV2/
│   │       ├── FontSelector.cs
│   │       ├── LabelledColourSelector.cs
│   │       ├── LabelledHueSelector.cs
│   │       ├── LabelledImageSelector.cs
│   │       ├── LabelledRealTimeSliderBar.cs
│   │       ├── LanguageSelector.cs
│   │       └── LanguageSelectorPopover.cs
│   ├── IO/
│   │   ├── Archives/
│   │   │   └── CachedFontArchiveReader.cs
│   │   ├── Serialization/
│   │   │   ├── Converters/
│   │   │   │   ├── ColourConverter.cs
│   │   │   │   ├── CultureInfoConverter.cs
│   │   │   │   ├── DictionaryConverter.cs
│   │   │   │   ├── ElementIdConverter.cs
│   │   │   │   ├── FontUsageConverter.cs
│   │   │   │   ├── GenericTypeConverter.cs
│   │   │   │   ├── KaraokeSkinElementConverter.cs
│   │   │   │   ├── LyricConverter.cs
│   │   │   │   ├── ReferenceLyricPropertyConfigConverter.cs
│   │   │   │   ├── RubyTagConverter.cs
│   │   │   │   ├── RubyTagsConverter.cs
│   │   │   │   ├── ShaderConverter.cs
│   │   │   │   ├── SortableJsonConverter.cs
│   │   │   │   ├── StageInfoConverter.cs
│   │   │   │   ├── TimeTagConverter.cs
│   │   │   │   ├── TimeTagsConverter.cs
│   │   │   │   ├── ToneConverter.cs
│   │   │   │   └── TranslationConverter.cs
│   │   │   ├── KaraokeJsonSerializableExtensions.cs
│   │   │   ├── SkinJsonSerializableExtensions.cs
│   │   │   └── WritablePropertiesOnlyResolver.cs
│   │   └── Stores/
│   │       ├── FntGlyphStore.cs
│   │       ├── KaraokeLocalFontStore.cs
│   │       └── TtfGlyphStore.cs
│   ├── Integration/
│   │   └── Formats/
│   │       ├── IDecoder.cs
│   │       ├── IEncoder.cs
│   │       ├── KarDecoder.cs
│   │       ├── KarEncoder.cs
│   │       ├── LrcDecoder.cs
│   │       ├── LrcEncoder.cs
│   │       ├── LrcParserUtils.cs
│   │       ├── LyricTextDecoder.cs
│   │       └── LyricTextEncoder.cs
│   ├── Judgements/
│   │   ├── KaraokeJudgement.cs
│   │   ├── KaraokeJudgementResult.cs
│   │   ├── KaraokeLyricJudgement.cs
│   │   └── KaraokeNoteJudgement.cs
│   ├── KaraokeControlInputManager.cs
│   ├── KaraokeEditInputManager.cs
│   ├── KaraokeInputManager.cs
│   ├── KaraokeRuleset.cs
│   ├── KaraokeSkinComponentLookup.cs
│   ├── KaraokeSkinComponents.cs
│   ├── Localisation/
│   │   ├── ChangelogStrings.cs
│   │   ├── CommonStrings.cs
│   │   └── KaraokeSettingsSubsectionStrings.cs
│   ├── Mods/
│   │   ├── IApplicableToMicrophone.cs
│   │   ├── IApplicableToSettingHUDOverlay.cs
│   │   ├── IApplicableToStage.cs
│   │   ├── IApplicableToStageElement.cs
│   │   ├── IApplicableToStageHitObjectCommand.cs
│   │   ├── IApplicableToStageInfo.cs
│   │   ├── IApplicableToStagePlayfieldCommand.cs
│   │   ├── KaraokeModAutoplay.cs
│   │   ├── KaraokeModAutoplayBySinger.cs
│   │   ├── KaraokeModClassicStage.cs
│   │   ├── KaraokeModDisableNote.cs
│   │   ├── KaraokeModFlashlight.cs
│   │   ├── KaraokeModHiddenNote.cs
│   │   ├── KaraokeModLyricConfiguration.cs
│   │   ├── KaraokeModNoFail.cs
│   │   ├── KaraokeModPerfect.cs
│   │   ├── KaraokeModPractice.cs
│   │   ├── KaraokeModPreviewStage.cs
│   │   ├── KaraokeModSnow.cs
│   │   ├── KaraokeModSuddenDeath.cs
│   │   ├── KaraokeModTranslation.cs
│   │   ├── KaraokeModWindowsUpdate.cs
│   │   ├── LanguageSettingsControl.cs
│   │   └── ModStage.cs
│   ├── Objects/
│   │   ├── BarLine.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableBarLine.cs
│   │   │   ├── DrawableKaraokeHitObject.cs
│   │   │   ├── DrawableKaraokeScrollingHitObject.cs
│   │   │   ├── DrawableLyric.cs
│   │   │   └── DrawableNote.cs
│   │   ├── KaraokeHitObject.cs
│   │   ├── LegacyProperties.cs
│   │   ├── Lyric.cs
│   │   ├── Lyric_Binding.cs
│   │   ├── Lyric_Working.cs
│   │   ├── Note.cs
│   │   ├── Note_Binding.cs
│   │   ├── Note_Working.cs
│   │   ├── Properties/
│   │   │   ├── IReferenceLyricPropertyConfig.cs
│   │   │   ├── ReferenceLyricConfig.cs
│   │   │   └── SyncLyricConfig.cs
│   │   ├── RubyTag.cs
│   │   ├── TimeTag.cs
│   │   ├── Title.cs
│   │   ├── TitlePart.cs
│   │   ├── Tone.cs
│   │   ├── Types/
│   │   │   ├── IHasLock.cs
│   │   │   ├── IHasOrder.cs
│   │   │   ├── IHasPage.cs
│   │   │   ├── IHasSingers.cs
│   │   │   ├── IHasText.cs
│   │   │   └── IHasWorkingProperty.cs
│   │   ├── Utils/
│   │   │   ├── LyricUtils.cs
│   │   │   ├── LyricsUtils.cs
│   │   │   ├── NoteUtils.cs
│   │   │   ├── NotesUtils.cs
│   │   │   ├── OrderUtils.cs
│   │   │   ├── RubyTagUtils.cs
│   │   │   ├── RubyTagsUtils.cs
│   │   │   ├── TimeTagUtils.cs
│   │   │   └── TimeTagsUtils.cs
│   │   └── Workings/
│   │       ├── HitObjectWorkingPropertyValidator.cs
│   │       ├── InvalidWorkingPropertyAssignException.cs
│   │       ├── LyricWorkingProperty.cs
│   │       ├── LyricWorkingPropertyValidator.cs
│   │       ├── NoteWorkingProperty.cs
│   │       └── NoteWorkingPropertyValidator.cs
│   ├── Online/
│   │   └── API/
│   │       └── Requests/
│   │           ├── ChangelogRequestUtils.cs
│   │           ├── GetChangelogBuildRequest.cs
│   │           ├── GetChangelogRequest.cs
│   │           ├── GithubAPIRequest.cs
│   │           └── Responses/
│   │               ├── APIChangelogBuild.cs
│   │               └── APIChangelogIndex.cs
│   ├── Overlays/
│   │   ├── Changelog/
│   │   │   ├── ChangeLogMarkdownContainer.cs
│   │   │   ├── ChangelogBadgeInfo.cs
│   │   │   ├── ChangelogBuild.cs
│   │   │   ├── ChangelogContent.cs
│   │   │   ├── ChangelogHeader.cs
│   │   │   ├── ChangelogListing.cs
│   │   │   ├── ChangelogPullRequestInfo.cs
│   │   │   ├── ChangelogSingleBuild.cs
│   │   │   └── Sidebar/
│   │   │       ├── ChangelogSection.cs
│   │   │       ├── ChangelogSidebar.cs
│   │   │       └── YearsPanel.cs
│   │   ├── Dialog/
│   │   │   └── OkPopupDialog.cs
│   │   └── KaraokeChangelogOverlay.cs
│   ├── Replays/
│   │   ├── KaraokeAutoGenerator.cs
│   │   ├── KaraokeAutoGeneratorBySinger.cs
│   │   ├── KaraokeFramedReplayInputHandler.cs
│   │   └── KaraokeReplayFrame.cs
│   ├── Resources/
│   │   └── Skin/
│   │       └── Default/
│   │           ├── default.json
│   │           ├── lyric-font-infos.json
│   │           └── note-styles.json
│   ├── Scoring/
│   │   ├── KaraokeHitWindows.cs
│   │   ├── KaraokeLyricHitWindows.cs
│   │   ├── KaraokeNoteHitWindows.cs
│   │   └── KaraokeScoreProcessor.cs
│   ├── Screens/
│   │   ├── Edit/
│   │   │   ├── AutoGenerateSection.cs
│   │   │   ├── AutoGenerateSubsection.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapEditorRoundedScreen.cs
│   │   │   │   ├── BeatmapEditorScreen.cs
│   │   │   │   ├── Components/
│   │   │   │   │   ├── Menus/
│   │   │   │   │   │   ├── AutoFocusToEditLyricMenu.cs
│   │   │   │   │   │   ├── GeneratorConfigMenu.cs
│   │   │   │   │   │   ├── ImportLyricMenu.cs
│   │   │   │   │   │   ├── LockStateMenu.cs
│   │   │   │   │   │   ├── LyricEditorModeMenu.cs
│   │   │   │   │   │   ├── LyricEditorPreferLayoutMenu.cs
│   │   │   │   │   │   └── LyricEditorTextSizeMenu.cs
│   │   │   │   │   └── UserInterfaceV2/
│   │   │   │   │       └── LyricSelector.cs
│   │   │   │   ├── ILyricsProvider.cs
│   │   │   │   ├── KaraokeBeatmapEditor.cs
│   │   │   │   ├── KaraokeBeatmapEditorScreenMode.cs
│   │   │   │   ├── Lyrics/
│   │   │   │   │   ├── BindableBlueprintContainer.cs
│   │   │   │   │   ├── CaretPosition/
│   │   │   │   │   │   ├── Algorithms/
│   │   │   │   │   │   │   ├── CaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CharGapCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CharIndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── ClickingCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CreateRubyTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CuttingCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── ICaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── IIndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── IndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── NavigateCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretMoveMode.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   └── TypingCaretPositionAlgorithm.cs
│   │   │   │   │   │   ├── ClickingCaretPosition.cs
│   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPosition.cs
│   │   │   │   │   │   ├── CreateRubyTagCaretPosition.cs
│   │   │   │   │   │   ├── CuttingCaretPosition.cs
│   │   │   │   │   │   ├── ICaretPosition.cs
│   │   │   │   │   │   ├── ICharGapCaretPosition.cs
│   │   │   │   │   │   ├── ICharIndexCaretPosition.cs
│   │   │   │   │   │   ├── IIndexCaretPosition.cs
│   │   │   │   │   │   ├── NavigateCaretPosition.cs
│   │   │   │   │   │   ├── RecordingTimeTagCaretPosition.cs
│   │   │   │   │   │   └── TypingCaretPosition.cs
│   │   │   │   │   ├── ClipboardToast.cs
│   │   │   │   │   ├── Content/
│   │   │   │   │   │   ├── ApplySelectingArea.cs
│   │   │   │   │   │   ├── CircleCheckbox.cs
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── Badges/
│   │   │   │   │   │   │   │   ├── Badge.cs
│   │   │   │   │   │   │   │   ├── LanguageBadge.cs
│   │   │   │   │   │   │   │   ├── ReferenceLyricBadge.cs
│   │   │   │   │   │   │   │   ├── SingerBadge.cs
│   │   │   │   │   │   │   │   └── TimeTagBadge.cs
│   │   │   │   │   │   │   ├── FixedInfo/
│   │   │   │   │   │   │   │   ├── InvalidInfo.cs
│   │   │   │   │   │   │   │   ├── LockInfo.cs
│   │   │   │   │   │   │   │   └── OrderInfo.cs
│   │   │   │   │   │   │   └── Lyrics/
│   │   │   │   │   │   │       ├── BlueprintLayer.cs
│   │   │   │   │   │   │       ├── Blueprints/
│   │   │   │   │   │   │       │   ├── LyricPropertyBlueprintContainer.cs
│   │   │   │   │   │   │       │   ├── RubyBlueprintContainer.cs
│   │   │   │   │   │   │       │   ├── RubyTagSelectionBlueprint.cs
│   │   │   │   │   │   │       │   ├── TimeTagBlueprintContainer.cs
│   │   │   │   │   │   │       │   └── TimeTagSelectionBlueprint.cs
│   │   │   │   │   │   │       ├── CaretLayer.cs
│   │   │   │   │   │   │       ├── Carets/
│   │   │   │   │   │   │       │   ├── DrawableCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCaretState.cs
│   │   │   │   │   │   │       │   ├── DrawableCreateRemoveTimeTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCreateRubyTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCuttingCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableRangeCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableRecordingTimeTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableTypingCaret.cs
│   │   │   │   │   │   │       │   └── ICanAcceptRangeIndex.cs
│   │   │   │   │   │   │       ├── EditLyricLayer.cs
│   │   │   │   │   │   │       ├── GridLayer.cs
│   │   │   │   │   │   │       ├── IInteractableLyricState.cs
│   │   │   │   │   │   │       ├── IPreviewLyricPositionProvider.cs
│   │   │   │   │   │   │       ├── InteractLyricLayer.cs
│   │   │   │   │   │   │       ├── InteractableLyric.cs
│   │   │   │   │   │   │       ├── Layer.cs
│   │   │   │   │   │   │       ├── LayerLoader.cs
│   │   │   │   │   │   │       ├── LyricLayer.cs
│   │   │   │   │   │   │       ├── PreviewKaraokeSpriteText.cs
│   │   │   │   │   │   │       ├── TimeTagLayer.cs
│   │   │   │   │   │   │       └── UIEventLayer.cs
│   │   │   │   │   │   ├── Compose/
│   │   │   │   │   │   │   ├── BottomEditor/
│   │   │   │   │   │   │   │   ├── AdjustTimeTagBottomEditor.cs
│   │   │   │   │   │   │   │   ├── AdjustTimeTags/
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagBlueprintContainer.cs
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagScrollContainer.cs
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagSelectionBlueprint.cs
│   │   │   │   │   │   │   │   │   ├── CurrentTimeMarker.cs
│   │   │   │   │   │   │   │   │   └── TimeTagOrderedSelectionContainer.cs
│   │   │   │   │   │   │   │   ├── BaseBottomEditor.cs
│   │   │   │   │   │   │   │   ├── NoteBottomEditor.cs
│   │   │   │   │   │   │   │   ├── Notes/
│   │   │   │   │   │   │   │   │   ├── NoteEditPopover.cs
│   │   │   │   │   │   │   │   │   ├── NoteEditor.cs
│   │   │   │   │   │   │   │   │   ├── NoteEditorBlueprintContainer.cs
│   │   │   │   │   │   │   │   │   └── NoteEditorSelectionBlueprint.cs
│   │   │   │   │   │   │   │   ├── RecordingTimeTagBottomEditor.cs
│   │   │   │   │   │   │   │   ├── RecordingTimeTags/
│   │   │   │   │   │   │   │   │   ├── CentreMarker.cs
│   │   │   │   │   │   │   │   │   ├── RecordingTimeTagPart.cs
│   │   │   │   │   │   │   │   │   ├── RecordingTimeTagScrollContainer.cs
│   │   │   │   │   │   │   │   │   └── TimeTagsVisualisation.cs
│   │   │   │   │   │   │   │   └── TimeTagScrollContainer.cs
│   │   │   │   │   │   │   ├── ComposeContent.cs
│   │   │   │   │   │   │   ├── CreateNewLyricDetailRow.cs
│   │   │   │   │   │   │   ├── DetailLyricList.cs
│   │   │   │   │   │   │   ├── DetailRow.cs
│   │   │   │   │   │   │   ├── EditLyricDetailRow.cs
│   │   │   │   │   │   │   ├── LyricComposer.cs
│   │   │   │   │   │   │   ├── LyricEditor.cs
│   │   │   │   │   │   │   ├── Panel.cs
│   │   │   │   │   │   │   ├── PanelDirection.cs
│   │   │   │   │   │   │   ├── Panels/
│   │   │   │   │   │   │   │   ├── InvalidPanel.cs
│   │   │   │   │   │   │   │   ├── IssueSection.cs
│   │   │   │   │   │   │   │   ├── PanelSection.cs
│   │   │   │   │   │   │   │   └── PropertyPanel.cs
│   │   │   │   │   │   │   ├── SpecialActionToolbar.cs
│   │   │   │   │   │   │   └── Toolbar/
│   │   │   │   │   │   │       ├── Carets/
│   │   │   │   │   │   │       │   ├── MoveToCaretPositionButton.cs
│   │   │   │   │   │   │       │   ├── MoveToFirstIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToLastIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToNextIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToNextLyricButton.cs
│   │   │   │   │   │   │       │   ├── MoveToPreviousIndexButton.cs
│   │   │   │   │   │   │       │   └── MoveToPreviousLyricButton.cs
│   │   │   │   │   │   │       ├── Panels/
│   │   │   │   │   │   │       │   ├── ToggleInvalidInfoPanelButton.cs
│   │   │   │   │   │   │       │   └── TogglePropertyPanelButton.cs
│   │   │   │   │   │   │       ├── Playback/
│   │   │   │   │   │   │       │   └── PlaybackSwitchButton.cs
│   │   │   │   │   │   │       ├── Separator.cs
│   │   │   │   │   │   │       ├── ToolbarButton.cs
│   │   │   │   │   │   │       ├── ToolbarEditActionButton.cs
│   │   │   │   │   │   │       ├── ToolbarToggleButton.cs
│   │   │   │   │   │   │       └── View/
│   │   │   │   │   │   │           └── AdjustFontSizeButton.cs
│   │   │   │   │   │   ├── ContentWrapper.cs
│   │   │   │   │   │   ├── List/
│   │   │   │   │   │   │   ├── CreateNewLyricPreviewRow.cs
│   │   │   │   │   │   │   ├── EditLyricPreviewRow.cs
│   │   │   │   │   │   │   ├── InfoControl.cs
│   │   │   │   │   │   │   ├── ListContent.cs
│   │   │   │   │   │   │   ├── PreviewLyricList.cs
│   │   │   │   │   │   │   └── PreviewRow.cs
│   │   │   │   │   │   ├── LyricList.cs
│   │   │   │   │   │   ├── MainContent.cs
│   │   │   │   │   │   └── Row.cs
│   │   │   │   │   ├── DeleteLyricDialog.cs
│   │   │   │   │   ├── IIssueNavigator.cs
│   │   │   │   │   ├── ILyricEditorClipboard.cs
│   │   │   │   │   ├── ILyricEditorState.cs
│   │   │   │   │   ├── ILyricEditorVerifier.cs
│   │   │   │   │   ├── IssueNavigator.cs
│   │   │   │   │   ├── LyricEditor.cs
│   │   │   │   │   ├── LyricEditorClipboard.cs
│   │   │   │   │   ├── LyricEditorColourProvider.cs
│   │   │   │   │   ├── LyricEditorIssueTable.cs
│   │   │   │   │   ├── LyricEditorLayout.cs
│   │   │   │   │   ├── LyricEditorMode.cs
│   │   │   │   │   ├── LyricEditorScreen.cs
│   │   │   │   │   ├── LyricEditorSkin.cs
│   │   │   │   │   ├── LyricEditorVerifier.cs
│   │   │   │   │   ├── OsuColourExtensions.cs
│   │   │   │   │   ├── Settings/
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── BlockSectionWrapper.cs
│   │   │   │   │   │   │   └── Markdown/
│   │   │   │   │   │   │       ├── LyricEditorDescriptionTextFlowContainer.cs
│   │   │   │   │   │   │       ├── SwitchModeDescriptionAction.cs
│   │   │   │   │   │   │       └── SwitchMoteText.cs
│   │   │   │   │   │   ├── LabelledObjectFieldSwitchButton.cs
│   │   │   │   │   │   ├── LabelledObjectFieldTextBox.cs
│   │   │   │   │   │   ├── Language/
│   │   │   │   │   │   │   ├── AssignLanguageSubsection.cs
│   │   │   │   │   │   │   ├── LanguageAutoGenerateSubsection.cs
│   │   │   │   │   │   │   ├── LanguageEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── LanguageIssueSection.cs
│   │   │   │   │   │   │   ├── LanguageSettingsHeader.cs
│   │   │   │   │   │   │   └── LanguageSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── LanguageSettings.cs
│   │   │   │   │   │   ├── LyricEditorAutoGenerateSubsection.cs
│   │   │   │   │   │   ├── LyricEditorIssueSection.cs
│   │   │   │   │   │   ├── LyricEditorSettings.cs
│   │   │   │   │   │   ├── LyricEditorSettingsHeader.cs
│   │   │   │   │   │   ├── LyricPropertiesSection.cs
│   │   │   │   │   │   ├── LyricPropertySection.cs
│   │   │   │   │   │   ├── NoteSettings.cs
│   │   │   │   │   │   ├── Notes/
│   │   │   │   │   │   │   ├── NoteAutoGenerateSubsection.cs
│   │   │   │   │   │   │   ├── NoteClearSubsection.cs
│   │   │   │   │   │   │   ├── NoteConfigSection.cs
│   │   │   │   │   │   │   ├── NoteEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── NoteEditPropertyMode.cs
│   │   │   │   │   │   │   ├── NoteEditPropertyModeSection.cs
│   │   │   │   │   │   │   ├── NoteEditPropertySection.cs
│   │   │   │   │   │   │   ├── NoteIssueSection.cs
│   │   │   │   │   │   │   ├── NoteSettingsHeader.cs
│   │   │   │   │   │   │   └── NoteSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── Reference/
│   │   │   │   │   │   │   ├── LabelledReferenceLyricSelector.cs
│   │   │   │   │   │   │   ├── ReferenceLyricAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricConfigSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricIssueSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricSection.cs
│   │   │   │   │   │   │   └── ReferenceLyricSettingsHeader.cs
│   │   │   │   │   │   ├── ReferenceSettings.cs
│   │   │   │   │   │   ├── Romanisation/
│   │   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   │   └── LabelledRomanisedTextBox.cs
│   │   │   │   │   │   │   ├── RomanisationAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── RomanisationEditSection.cs
│   │   │   │   │   │   │   ├── RomanisationIssueSection.cs
│   │   │   │   │   │   │   └── RomanisationSettingsHeader.cs
│   │   │   │   │   │   ├── RomanisationSettings.cs
│   │   │   │   │   │   ├── Ruby/
│   │   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   │   └── LabelledRubyTagTextBox.cs
│   │   │   │   │   │   │   ├── RubyTagAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── RubyTagConfigToolSection.cs
│   │   │   │   │   │   │   ├── RubyTagEditModeSubsection.cs
│   │   │   │   │   │   │   ├── RubyTagEditSection.cs
│   │   │   │   │   │   │   ├── RubyTagIssueSection.cs
│   │   │   │   │   │   │   └── RubyTagSettingsHeader.cs
│   │   │   │   │   │   ├── RubyTagSettings.cs
│   │   │   │   │   │   ├── SelectLyricButton.cs
│   │   │   │   │   │   ├── SettingsDirection.cs
│   │   │   │   │   │   ├── SingerSettings.cs
│   │   │   │   │   │   ├── Singers/
│   │   │   │   │   │   │   └── SingerEditSection.cs
│   │   │   │   │   │   ├── SpecialActionSection.cs
│   │   │   │   │   │   ├── SwitchSubsection.cs
│   │   │   │   │   │   ├── Text/
│   │   │   │   │   │   │   ├── TextDeleteSubsection.cs
│   │   │   │   │   │   │   ├── TextEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── TextIssueSection.cs
│   │   │   │   │   │   │   ├── TextSettingsHeader.cs
│   │   │   │   │   │   │   └── TextSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── TextSettings.cs
│   │   │   │   │   │   ├── TimeTagSettings.cs
│   │   │   │   │   │   └── TimeTags/
│   │   │   │   │   │       ├── Components/
│   │   │   │   │   │       │   └── LabelledOpacityAdjustment.cs
│   │   │   │   │   │       ├── CreateTimeTagActionSection.cs
│   │   │   │   │   │       ├── CreateTimeTagTypeSubsection.cs
│   │   │   │   │   │       ├── RecordingTapControl.cs
│   │   │   │   │   │       ├── TapButton.cs
│   │   │   │   │   │       ├── TimeTagAdjustConfigSection.cs
│   │   │   │   │   │       ├── TimeTagAutoGenerateSection.cs
│   │   │   │   │   │       ├── TimeTagIssueSection.cs
│   │   │   │   │   │       ├── TimeTagRecordingConfigSection.cs
│   │   │   │   │   │       ├── TimeTagRecordingToolSection.cs
│   │   │   │   │   │       └── TimeTagSettingsHeader.cs
│   │   │   │   │   └── States/
│   │   │   │   │       ├── ILyricCaretState.cs
│   │   │   │   │       ├── ILyricSelectionState.cs
│   │   │   │   │       ├── LyricCaretState.cs
│   │   │   │   │       ├── LyricEditorSelectingAction.cs
│   │   │   │   │       ├── LyricSelectionState.cs
│   │   │   │   │       ├── Modes/
│   │   │   │   │       │   ├── CreateTimeTagType.cs
│   │   │   │   │       │   ├── EditLanguageModeState.cs
│   │   │   │   │       │   ├── EditNoteModeState.cs
│   │   │   │   │       │   ├── EditReferenceLyricModeState.cs
│   │   │   │   │       │   ├── EditRomanisationModeState.cs
│   │   │   │   │       │   ├── EditRubyModeState.cs
│   │   │   │   │       │   ├── EditTextModeState.cs
│   │   │   │   │       │   ├── EditTimeTagModeState.cs
│   │   │   │   │       │   ├── IEditLanguageModeState.cs
│   │   │   │   │       │   ├── IEditNoteModeState.cs
│   │   │   │   │       │   ├── IEditReferenceLyricModeState.cs
│   │   │   │   │       │   ├── IEditRomanisationModeState.cs
│   │   │   │   │       │   ├── IEditRubyModeState.cs
│   │   │   │   │       │   ├── IEditTextModeState.cs
│   │   │   │   │       │   ├── IEditTimeTagModeState.cs
│   │   │   │   │       │   ├── IHasBlueprintSelection.cs
│   │   │   │   │       │   ├── IHasEditStep.cs
│   │   │   │   │       │   ├── IHasSpecialAction.cs
│   │   │   │   │       │   ├── LanguageEditStep.cs
│   │   │   │   │       │   ├── ModeStateWithBlueprintContainer.cs
│   │   │   │   │       │   ├── NoteEditStep.cs
│   │   │   │   │       │   ├── ReferenceLyricEditStep.cs
│   │   │   │   │       │   ├── RomanisationTagEditStep.cs
│   │   │   │   │       │   ├── RubyTagEditMode.cs
│   │   │   │   │       │   ├── RubyTagEditStep.cs
│   │   │   │   │       │   ├── TextEditStep.cs
│   │   │   │   │       │   └── TimeTagEditStep.cs
│   │   │   │   │       ├── MovingCaretAction.cs
│   │   │   │   │       └── RangeCaretPosition.cs
│   │   │   │   ├── LyricsProvider.cs
│   │   │   │   ├── Pages/
│   │   │   │   │   ├── Components/
│   │   │   │   │   │   └── Timeline/
│   │   │   │   │   │       ├── LyricBlueprintContainer.cs
│   │   │   │   │   │       ├── PageBlueprintContainer.cs
│   │   │   │   │   │       ├── PageSelectionBlueprint.cs
│   │   │   │   │   │       ├── PagesTimeLine.cs
│   │   │   │   │   │       └── PreviewLyricSelectionBlueprint.cs
│   │   │   │   │   ├── IPageEditorVerifier.cs
│   │   │   │   │   ├── IPageStateProvider.cs
│   │   │   │   │   ├── PageEditor.cs
│   │   │   │   │   ├── PageEditorEditMode.cs
│   │   │   │   │   ├── PageEditorVerifier.cs
│   │   │   │   │   ├── PageScreen.cs
│   │   │   │   │   └── Settings/
│   │   │   │   │       ├── ConfirmReGeneratePageDialog.cs
│   │   │   │   │       ├── PageAutoGenerateSection.cs
│   │   │   │   │       ├── PageEditorIssueSection.cs
│   │   │   │   │       ├── PageEditorSettingsHeader.cs
│   │   │   │   │       ├── PageSettings.cs
│   │   │   │   │       └── PagesSection.cs
│   │   │   │   ├── Singers/
│   │   │   │   │   ├── DeleteSingerDialog.cs
│   │   │   │   │   ├── Detail/
│   │   │   │   │   │   ├── AvatarSection.cs
│   │   │   │   │   │   ├── EditSingerSection.cs
│   │   │   │   │   │   ├── MetadataSection.cs
│   │   │   │   │   │   └── SingerEditPopover.cs
│   │   │   │   │   ├── ISingerScreenScrollingInfoProvider.cs
│   │   │   │   │   ├── Rows/
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── SingerAvatar.cs
│   │   │   │   │   │   │   └── Timeline/
│   │   │   │   │   │   │       ├── LyricTimelineSelectionBlueprint.cs
│   │   │   │   │   │   │       ├── SingerLyricEditorBlueprintContainer.cs
│   │   │   │   │   │   │       └── SingerLyricTimeline.cs
│   │   │   │   │   │   ├── CreateNewLyricPlacementRow.cs
│   │   │   │   │   │   ├── DefaultLyricPlacementRow.cs
│   │   │   │   │   │   ├── LyricPlacementRow.cs
│   │   │   │   │   │   └── SingerLyricPlacementRow.cs
│   │   │   │   │   ├── SingerEditSection.cs
│   │   │   │   │   ├── SingerRearrangeableList.cs
│   │   │   │   │   ├── SingerRearrangeableListItem.cs
│   │   │   │   │   └── SingerScreen.cs
│   │   │   │   └── Translations/
│   │   │   │       ├── Components/
│   │   │   │       │   ├── CreateNewTranslationButton.cs
│   │   │   │       │   ├── LanguageDropdown.cs
│   │   │   │       │   ├── LyricTranslationTextBox.cs
│   │   │   │       │   ├── PreviewLyricSpriteText.cs
│   │   │   │       │   └── RemoveTranslationButton.cs
│   │   │   │       ├── DeleteLanguagePopupDialog.cs
│   │   │   │       ├── ITranslationInfoProvider.cs
│   │   │   │       ├── TranslationEditSection.cs
│   │   │   │       └── TranslationScreen.cs
│   │   │   ├── BottomBar.cs
│   │   │   ├── Components/
│   │   │   │   ├── Containers/
│   │   │   │   │   └── BindableScrollContainer.cs
│   │   │   │   ├── Issues/
│   │   │   │   │   ├── IssueIcon.cs
│   │   │   │   │   └── IssuesToolTip.cs
│   │   │   │   ├── Markdown/
│   │   │   │   │   ├── DescriptionFormat.cs
│   │   │   │   │   ├── DescriptionTextFlowContainer.cs
│   │   │   │   │   ├── IDescriptionAction.cs
│   │   │   │   │   ├── InputKeyDescriptionAction.cs
│   │   │   │   │   └── InputKeyText.cs
│   │   │   │   ├── Menus/
│   │   │   │   │   └── GenericScreenSelectionTabControl.cs
│   │   │   │   ├── Timeline/
│   │   │   │   │   ├── EditableLyricTimelineSelectionBlueprint.cs
│   │   │   │   │   ├── EditableTimeline.cs
│   │   │   │   │   ├── EditableTimelineBlueprintContainer.cs
│   │   │   │   │   └── EditableTimelineSelectionBlueprint.cs
│   │   │   │   └── UserInterface/
│   │   │   │       ├── DeleteIconButton.cs
│   │   │   │       └── LanguagesSelector.cs
│   │   │   ├── EditorSection.cs
│   │   │   ├── EditorSectionButton.cs
│   │   │   ├── EditorSettings.cs
│   │   │   ├── EditorSettingsHeader.cs
│   │   │   ├── EditorTable.cs
│   │   │   ├── EditorVerifier.cs
│   │   │   ├── GeneratorConfigPopover.cs
│   │   │   ├── GenericEditor.cs
│   │   │   ├── GenericEditorScreen.cs
│   │   │   ├── IEditorVerifier.cs
│   │   │   ├── ISectionItemsEditorProvider.cs
│   │   │   ├── Import/
│   │   │   │   └── Lyrics/
│   │   │   │       ├── AssignLanguage/
│   │   │   │       │   ├── AssignLanguageNavigation.cs
│   │   │   │       │   ├── AssignLanguageStepScreen.cs
│   │   │   │       │   └── UseLanguageDetectorPopupDialog.cs
│   │   │   │       ├── DragFile/
│   │   │   │       │   ├── Components/
│   │   │   │       │   │   └── DrawableDragFile.cs
│   │   │   │       │   ├── DragFileStepScreen.cs
│   │   │   │       │   └── ImportLyricDialog.cs
│   │   │   │       ├── EditLyric/
│   │   │   │       │   ├── EditLyricNavigation.cs
│   │   │   │       │   └── EditLyricStepScreen.cs
│   │   │   │       ├── GenerateRuby/
│   │   │   │       │   ├── GenerateRubyNavigation.cs
│   │   │   │       │   ├── GenerateRubyStepScreen.cs
│   │   │   │       │   └── UseAutoGenerateRubyPopupDialog.cs
│   │   │   │       ├── GenerateTimeTag/
│   │   │   │       │   ├── AlreadyContainTimeTagPopupDialog.cs
│   │   │   │       │   ├── GenerateTimeTagNavigation.cs
│   │   │   │       │   ├── GenerateTimeTagStepScreen.cs
│   │   │   │       │   ├── UseAutoGenerateRomanisationPopupDialog.cs
│   │   │   │       │   └── UseAutoGenerateTimeTagPopupDialog.cs
│   │   │   │       ├── IHasTopNavigation.cs
│   │   │   │       ├── IImportStateResolver.cs
│   │   │   │       ├── ILyricImporterStepScreen.cs
│   │   │   │       ├── ImportLyricHeader.cs
│   │   │   │       ├── ImportLyricManager.cs
│   │   │   │       ├── ImportLyricOverlay.cs
│   │   │   │       ├── LyricImporter.cs
│   │   │   │       ├── LyricImporterStep.cs
│   │   │   │       ├── LyricImporterStepScreen.cs
│   │   │   │       ├── LyricImporterStepScreenWithLyricEditor.cs
│   │   │   │       ├── LyricImporterSubScreenStack.cs
│   │   │   │       ├── NotImportStepScreenException.cs
│   │   │   │       ├── RollBackPopupDialog.cs
│   │   │   │       ├── RollBackResetPopupDialog.cs
│   │   │   │       ├── Success/
│   │   │   │       │   └── SuccessStepScreen.cs
│   │   │   │       └── TopNavigation.cs
│   │   │   ├── IssueSection.cs
│   │   │   ├── IssueTable.cs
│   │   │   ├── SectionItemsEditor.cs
│   │   │   ├── SectionTimingInfoItemsEditor.cs
│   │   │   ├── Stages/
│   │   │   │   └── Classic/
│   │   │   │       ├── ClassicStageEditor.cs
│   │   │   │       ├── ClassicStageEditorScreenMode.cs
│   │   │   │       ├── ClassicStageScreen.cs
│   │   │   │       ├── Config/
│   │   │   │       │   └── ConfigScreen.cs
│   │   │   │       └── Stage/
│   │   │   │           ├── IStageEditorStateProvider.cs
│   │   │   │           ├── IStageEditorVerifier.cs
│   │   │   │           ├── Settings/
│   │   │   │           │   ├── StageEditorIssueSection.cs
│   │   │   │           │   ├── StageEditorSettingsHeader.cs
│   │   │   │           │   ├── StageSettings.cs
│   │   │   │           │   └── TimingPointsSection.cs
│   │   │   │           ├── StageCategoryScreenStack.cs
│   │   │   │           ├── StageEditor.cs
│   │   │   │           ├── StageEditorEditCategory.cs
│   │   │   │           ├── StageEditorEditMode.cs
│   │   │   │           ├── StageEditorVerifier.cs
│   │   │   │           └── StageScreen.cs
│   │   │   ├── WorkspaceScreen.cs
│   │   │   └── WorkspaceScreenStack.cs
│   │   ├── Section.cs
│   │   ├── Settings/
│   │   │   ├── Header.cs
│   │   │   ├── KaraokeSettings.cs
│   │   │   ├── KaraokeSettingsColourProvider.cs
│   │   │   ├── KaraokeSettingsPanel.cs
│   │   │   ├── KaraokeSettingsSection.cs
│   │   │   ├── KaraokeSettingsSubsection.cs
│   │   │   ├── KaraokeVersionManager.cs
│   │   │   ├── Previews/
│   │   │   │   ├── DefaultPreview.cs
│   │   │   │   ├── Gameplay/
│   │   │   │   │   ├── LyricPreview.cs
│   │   │   │   │   ├── NotePlayfieldPreview.cs
│   │   │   │   │   └── ShowCursorPreview.cs
│   │   │   │   ├── Graphics/
│   │   │   │   │   └── ManageFontPreview.cs
│   │   │   │   ├── Input/
│   │   │   │   │   ├── MicrophoneDevicePreview.cs
│   │   │   │   │   └── MicrophoneSoundVisualizer.cs
│   │   │   │   ├── SettingsSubsectionPreview.cs
│   │   │   │   └── UnderConstructionPreview.cs
│   │   │   ├── Sections/
│   │   │   │   ├── ConfigSection.cs
│   │   │   │   ├── Gameplay/
│   │   │   │   │   ├── GeneralSettings.cs
│   │   │   │   │   ├── NoteSettings.cs
│   │   │   │   │   └── ScoringSettings.cs
│   │   │   │   ├── Graphics/
│   │   │   │   │   ├── LyricFontSettings.cs
│   │   │   │   │   ├── ManageFontSettings.cs
│   │   │   │   │   ├── NoteFontSettings.cs
│   │   │   │   │   └── TransparentSettings.cs
│   │   │   │   ├── Input/
│   │   │   │   │   └── MicrophoneSettings.cs
│   │   │   │   ├── ScoringSection.cs
│   │   │   │   └── StyleSection.cs
│   │   │   ├── SettingsFont.cs
│   │   │   └── SettingsMicrophoneDeviceDropdown.cs
│   │   └── Skin/
│   │       ├── Config/
│   │       │   ├── ConfigScreen.cs
│   │       │   ├── IntervalSection.cs
│   │       │   ├── LyricConfigSection.cs
│   │       │   ├── LyricFontInfoManager.cs
│   │       │   ├── PositionSection.cs
│   │       │   └── RubyAndRomanisationSection.cs
│   │       ├── KaraokeSkinEditor.cs
│   │       ├── KaraokeSkinEditorScreen.cs
│   │       ├── KaraokeSkinEditorScreenMode.cs
│   │       └── Style/
│   │           ├── LyricColorSection.cs
│   │           ├── LyricFontSection.cs
│   │           ├── LyricShadowSection.cs
│   │           ├── LyricStylePreview.cs
│   │           ├── NoteColorSection.cs
│   │           ├── NoteFontSection.cs
│   │           ├── NoteStylePreview.cs
│   │           ├── StyleScreen.cs
│   │           └── StyleSection.cs
│   ├── Skinning/
│   │   ├── Argon/
│   │   │   └── KaraokeArgonSkinTransformer.cs
│   │   ├── Default/
│   │   │   ├── DefaultBodyPiece.cs
│   │   │   └── KaraokeDefaultSkinTransformer.cs
│   │   ├── Elements/
│   │   │   ├── ElementType.cs
│   │   │   ├── IKaraokeSkinElement.cs
│   │   │   ├── InvalidDrawableTypeException.cs
│   │   │   ├── LayoutGroup.cs
│   │   │   ├── LyricFontInfo.cs
│   │   │   └── NoteStyle.cs
│   │   ├── Fonts/
│   │   │   ├── BitmapFontCompressor.cs
│   │   │   ├── BitmapFontImageGenerator.cs
│   │   │   ├── FontInfo.cs
│   │   │   └── FontManager.cs
│   │   ├── InternalSkinStorageResourceProvider.cs
│   │   ├── KaraokeBeatmapSkin.cs
│   │   ├── KaraokeIndexLookup.cs
│   │   ├── KaraokeSkin.cs
│   │   ├── KaraokeSkinConfigurationLookup.cs
│   │   ├── KaraokeSkinLookup.cs
│   │   ├── Legacy/
│   │   │   ├── KaraokeClassicSkinTransformer.cs
│   │   │   ├── KaraokeLegacySkinTransformer.cs
│   │   │   ├── LegacyColumnBackground.cs
│   │   │   ├── LegacyHitExplosion.cs
│   │   │   ├── LegacyJudgementLine.cs
│   │   │   ├── LegacyKaraokeColumnElement.cs
│   │   │   ├── LegacyKaraokeElement.cs
│   │   │   ├── LegacyNotePiece.cs
│   │   │   └── LegacyStageBackground.cs
│   │   ├── Tools/
│   │   │   └── SkinConverterTool.cs
│   │   └── Triangles/
│   │       └── KaraokeTrianglesSkinTransformer.cs
│   ├── Stages/
│   │   ├── Commands/
│   │   │   ├── IStageCommand.cs
│   │   │   ├── Lyrics/
│   │   │   │   └── LyricStyleCommand.cs
│   │   │   ├── StageAlphaCommand.cs
│   │   │   ├── StageAnchorCommand.cs
│   │   │   ├── StageCommand.cs
│   │   │   ├── StageHeightCommand.cs
│   │   │   ├── StageOriginCommand.cs
│   │   │   ├── StagePaddingCommand.cs
│   │   │   ├── StageScaleCommand.cs
│   │   │   ├── StageWidthCommand.cs
│   │   │   ├── StageXCommand.cs
│   │   │   └── StageYCommand.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableStage.cs
│   │   │   ├── DrawableStageBeatmapCoverInfo.cs
│   │   │   ├── IStageElementRunner.cs
│   │   │   ├── IStageHitObjectRunner.cs
│   │   │   ├── IStagePlayfieldRunner.cs
│   │   │   ├── StageElementRunner.cs
│   │   │   ├── StageHitObjectRunner.cs
│   │   │   ├── StagePlayfieldRunner.cs
│   │   │   └── StageRunner.cs
│   │   ├── HitObjectCommandProvider.cs
│   │   ├── IHitObjectCommandProvider.cs
│   │   ├── IPlayfieldCommandProvider.cs
│   │   ├── IStageElement.cs
│   │   ├── IStageElementProvider.cs
│   │   ├── IStageElementWithDuration.cs
│   │   ├── Infos/
│   │   │   ├── Classic/
│   │   │   │   ├── ClassicLyricCommandProvider.cs
│   │   │   │   ├── ClassicLyricLayout.cs
│   │   │   │   ├── ClassicLyricLayoutAlignment.cs
│   │   │   │   ├── ClassicLyricLayoutCategory.cs
│   │   │   │   ├── ClassicLyricTimingInfo.cs
│   │   │   │   ├── ClassicLyricTimingPoint.cs
│   │   │   │   ├── ClassicPlayfieldCommandProvider.cs
│   │   │   │   ├── ClassicStageDefinition.cs
│   │   │   │   ├── ClassicStageInfo.cs
│   │   │   │   ├── ClassicStyle.cs
│   │   │   │   └── ClassicStyleCategory.cs
│   │   │   ├── Preview/
│   │   │   │   ├── PreviewElementProvider.cs
│   │   │   │   ├── PreviewLyricCommandProvider.cs
│   │   │   │   ├── PreviewLyricLayout.cs
│   │   │   │   ├── PreviewLyricLayoutCategory.cs
│   │   │   │   ├── PreviewPlayfieldCommandProvider.cs
│   │   │   │   ├── PreviewStageDefinition.cs
│   │   │   │   ├── PreviewStageInfo.cs
│   │   │   │   ├── PreviewStageTimingCalculator.cs
│   │   │   │   ├── PreviewStyle.cs
│   │   │   │   └── PreviewStyleCategory.cs
│   │   │   ├── StageDefinition.cs
│   │   │   ├── StageElement.cs
│   │   │   ├── StageElementCategory.cs
│   │   │   ├── StageInfo.cs
│   │   │   └── Types/
│   │   │       └── IHasCalculatedProperty.cs
│   │   ├── PlayfieldCommandProvider.cs
│   │   ├── StageBeatmapCoverInfo.cs
│   │   ├── StageElementProvider.cs
│   │   └── StageSprite.cs
│   ├── Statistics/
│   │   ├── BeatmapMetadataGraph.cs
│   │   ├── NotScorableGraph.cs
│   │   └── ScoringResultGraph.cs
│   ├── Timing/
│   │   └── StopClock.cs
│   ├── UI/
│   │   ├── Components/
│   │   │   ├── CenterLine.cs
│   │   │   ├── DefaultColumnBackground.cs
│   │   │   ├── DefaultJudgementLine.cs
│   │   │   ├── RealTimeScoringVisualization.cs
│   │   │   ├── ReplayScoringVisualization.cs
│   │   │   ├── ScoringMarker.cs
│   │   │   ├── ScoringStatus.cs
│   │   │   └── VoiceVisualization.cs
│   │   ├── DefaultHitExplosion.cs
│   │   ├── DrawableKaraokeRuleset.cs
│   │   ├── DrawableNoteJudgement.cs
│   │   ├── HUD/
│   │   │   ├── BindableNumberExtension.cs
│   │   │   ├── GeneralSettingOverlay.cs
│   │   │   ├── ISettingHUDOverlay.cs
│   │   │   ├── PracticeOverlay.cs
│   │   │   ├── SettingButton.cs
│   │   │   ├── SettingButtonsDisplay.cs
│   │   │   ├── SettingOverlay.cs
│   │   │   └── SettingOverlayContainer.cs
│   │   ├── KaraokePlayfield.cs
│   │   ├── KaraokePlayfieldAdjustmentContainer.cs
│   │   ├── KaraokeReplayRecorder.cs
│   │   ├── KaraokeScrollingDirection.cs
│   │   ├── KaraokeSettingsSubsection.cs
│   │   ├── LyricPlayfield.cs
│   │   ├── NotePlayfield.cs
│   │   ├── PlayerSettings/
│   │   │   ├── ClickablePlayerSliderBar.cs
│   │   │   ├── ILyricNavigator.cs
│   │   │   ├── LyricsPreview.cs
│   │   │   ├── PitchSettings.cs
│   │   │   ├── PlaybackSettings.cs
│   │   │   ├── PlayerDropdown.cs
│   │   │   └── PracticeSettings.cs
│   │   ├── Position/
│   │   │   ├── INotePositionInfo.cs
│   │   │   ├── NotePositionCalculator.cs
│   │   │   └── NotePositionInfo.cs
│   │   └── Scrolling/
│   │       └── ScrollingNotePlayfield.cs
│   ├── Utils/
│   │   ├── ActivatorUtils.cs
│   │   ├── AssemblyUtils.cs
│   │   ├── BindablesUtils.cs
│   │   ├── CharUtils.cs
│   │   ├── ComparableUtils.cs
│   │   ├── CultureInfoUtils.cs
│   │   ├── EnumUtils.cs
│   │   ├── FontUsageUtils.cs
│   │   ├── FontUtils.cs
│   │   ├── JpStringUtils.cs
│   │   ├── RectangleFUtils.cs
│   │   ├── StackTraceUtils.cs
│   │   ├── TextIndexUtils.cs
│   │   ├── TypeUtils.cs
│   │   └── VersionUtils.cs
│   └── osu.Game.Rulesets.Karaoke.csproj
├── osu.Game.Rulesets.Karaoke.Architectures/
│   ├── BaseTest.cs
│   ├── Edit/
│   │   └── Checks/
│   │       ├── TestCheck.cs
│   │       └── TestCheckTest.cs
│   ├── Extensions.cs
│   ├── MethodUtils.cs
│   ├── Project.cs
│   ├── TestClass.cs
│   ├── TestTestClass.cs
│   └── osu.Game.Rulesets.Karaoke.Architectures.csproj
├── osu.Game.Rulesets.Karaoke.Tests/
│   ├── .vscode/
│   │   ├── launch.json
│   │   └── tasks.json
│   ├── Asserts/
│   │   ├── ObjectAssert.cs
│   │   ├── RubyTagAssert.cs
│   │   └── TimeTagAssert.cs
│   ├── Beatmaps/
│   │   ├── ElementIdTest.cs
│   │   ├── Formats/
│   │   │   ├── KaraokeLegacyBeatmapDecoderTest.cs
│   │   │   └── KaraokeLegacyBeatmapEncoderTest.cs
│   │   ├── KaraokeBeatmapConversionTest.cs
│   │   ├── Metadatas/
│   │   │   ├── PageInfoTest.cs
│   │   │   └── SingerInfoTest.cs
│   │   ├── TestKaraokeBeatmap.cs
│   │   └── Utils/
│   │       └── SingerUtilsTest.cs
│   ├── Bindables/
│   │   ├── BindableCultureInfoTest.cs
│   │   └── BindableFontUsageTest.cs
│   ├── Difficulty/
│   │   ├── DifficultyCalculatorTest.cs
│   │   └── KaraokeDifficultyCalculatorTest.cs
│   ├── Editor/
│   │   ├── ChangeHandlers/
│   │   │   ├── BaseChangeHandlerTest.cs
│   │   │   ├── BaseHitObjectChangeHandlerTest.cs
│   │   │   ├── BaseHitObjectPropertyChangeHandlerTest.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPagesChangeHandlerTest.cs
│   │   │   │   ├── BeatmapSingersChangeHandlerTest.cs
│   │   │   │   └── BeatmapTranslationsChangeHandlerTest.cs
│   │   │   ├── ImportBeatmapChangeHandlerTest.cs
│   │   │   ├── LockChangeHandlerTest.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── LyricLanguageChangeHandlerTest.cs
│   │   │   │   ├── LyricPropertyAutoGenerateChangeHandlerTest.cs
│   │   │   │   ├── LyricPropertyChangeHandlerTest.cs
│   │   │   │   ├── LyricReferenceChangeHandlerTest.cs
│   │   │   │   ├── LyricRubyTagsChangeHandlerTest.cs
│   │   │   │   ├── LyricSingerChangeHandlerTest.cs
│   │   │   │   ├── LyricTextChangeHandlerTest.cs
│   │   │   │   ├── LyricTimeTagsChangeHandlerTest.cs
│   │   │   │   ├── LyricTranslationChangeHandlerTest.cs
│   │   │   │   └── LyricsChangeHandlerTest.cs
│   │   │   ├── Notes/
│   │   │   │   ├── NotePropertyChangeHandlerTest.cs
│   │   │   │   └── NotesChangeHandlerTest.cs
│   │   │   └── Stages/
│   │   │       ├── BaseStageInfoChangeHandlerTest.cs
│   │   │       ├── ClassicStageChangeHandlerTest.cs
│   │   │       ├── StageElementCategoryChangeHandlerTest.cs
│   │   │       └── StagesChangeHandlerTest.cs
│   │   ├── Checks/
│   │   │   ├── BaseCheckTest.cs
│   │   │   ├── BeatmapPropertyCheckTest.cs
│   │   │   ├── CheckBeatmapAvailableTranslationsTest.cs
│   │   │   ├── CheckBeatmapNoteInfoTest.cs
│   │   │   ├── CheckBeatmapPageInfoTest.cs
│   │   │   ├── CheckClassicStageInfoTest.cs
│   │   │   ├── CheckLyricLanguageTest.cs
│   │   │   ├── CheckLyricReferenceLyricTest.cs
│   │   │   ├── CheckLyricRubyTagTest.cs
│   │   │   ├── CheckLyricSingerTest.cs
│   │   │   ├── CheckLyricTextTest.cs
│   │   │   ├── CheckLyricTimeTagTest.cs
│   │   │   ├── CheckLyricTranslationsTest.cs
│   │   │   ├── CheckNoteReferenceLyricTest.cs
│   │   │   ├── CheckNoteTextTest.cs
│   │   │   ├── CheckNoteTimeTest.cs
│   │   │   ├── CheckStageInfoTest.cs
│   │   │   └── HitObjectCheckTest.cs
│   │   ├── Generator/
│   │   │   ├── BaseGeneratorSelectorTest.cs
│   │   │   ├── BasePropertyDetectorTest.cs
│   │   │   ├── BasePropertyGeneratorTest.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BaseBeatmapDetectorTest.cs
│   │   │   │   ├── BaseBeatmapGeneratorTest.cs
│   │   │   │   └── Pages/
│   │   │   │       └── PageGeneratorTest.cs
│   │   │   ├── GeneratorConfigExtensionTest.cs
│   │   │   ├── GeneratorConfigHelper.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── BaseLyricDetectorTest.cs
│   │   │   │   ├── BaseLyricGeneratorSelectorTest.cs
│   │   │   │   ├── BaseLyricGeneratorTest.cs
│   │   │   │   ├── Language/
│   │   │   │   │   └── LanguageDetectorTest.cs
│   │   │   │   ├── Notes/
│   │   │   │   │   └── NoteGeneratorTest.cs
│   │   │   │   ├── ReferenceLyric/
│   │   │   │   │   └── ReferenceLyricDetectorTest.cs
│   │   │   │   ├── Romanisation/
│   │   │   │   │   ├── BaseRomanisationGeneratorTest.cs
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   └── JaRomanisationGeneratorTest.cs
│   │   │   │   │   ├── RomanisationGenerateResultHelper.cs
│   │   │   │   │   └── RomanisationGeneratorSelectorTest.cs
│   │   │   │   ├── RubyTags/
│   │   │   │   │   ├── BaseRubyTagGeneratorTest.cs
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   └── JaRubyTagGeneratorTest.cs
│   │   │   │   │   └── RubyTagGeneratorSelectorTest.cs
│   │   │   │   └── TimeTags/
│   │   │   │       ├── BaseTimeTagGeneratorTest.cs
│   │   │   │       ├── Ja/
│   │   │   │       │   └── JaTimeTagGeneratorTest.cs
│   │   │   │       ├── TimeTagGeneratorSelectorTest.cs
│   │   │   │       └── Zh/
│   │   │   │           └── ZhTimeTagGeneratorTest.cs
│   │   │   └── Stages/
│   │   │       ├── BaseStageElementCategoryGeneratorTest.cs
│   │   │       ├── BaseStageInfoGeneratorTest.cs
│   │   │       ├── BaseStageInfoPropertyGeneratorTest.cs
│   │   │       ├── Classic/
│   │   │       │   ├── ClassicLyricLayoutCategoryGeneratorTest.cs
│   │   │       │   ├── ClassicLyricTimingInfoGeneratorTest.cs
│   │   │       │   └── ClassicStageInfoGeneratorTest.cs
│   │   │       ├── Preview/
│   │   │       │   └── PreviewStageInfoGeneratorTest.cs
│   │   │       └── StageInfoGeneratorSelectorTest.cs
│   │   ├── TestSceneEditor.cs
│   │   ├── TestSceneSetupScreen.cs
│   │   ├── TestSceneTimeTagTooltip.cs
│   │   └── Utils/
│   │       ├── HitObjectWritableUtilsTest.cs
│   │       ├── LockStateUtilsTest.cs
│   │       └── ValueChangedEventUtilsTest.cs
│   ├── Extensions/
│   │   ├── EnumerableExtensionsTest.cs
│   │   ├── PlayerTestSceneExtensions.cs
│   │   └── PrimaryKeyObjectExtension.cs
│   ├── Flags/
│   │   └── FlagStateTest.cs
│   ├── Graphics/
│   │   ├── Sprites/
│   │   │   ├── DisplayLyricProcessorTest.cs
│   │   │   └── Processor/
│   │   │       ├── DisplayProcessorTestScene.cs
│   │   │       ├── TestSceneLyricFirstDisplayProcessor.cs
│   │   │       └── TestSceneRomanisedSyllableFirstDisplayProcessor.cs
│   │   ├── TestSceneFontSelector.cs
│   │   ├── TestSceneLanguageSelector.cs
│   │   ├── TestSceneLyricTooltip.cs
│   │   ├── TestSceneRightTriangle.cs
│   │   └── TestSceneSingerToolTip.cs
│   ├── Helper/
│   │   ├── TestCaseCheckHelper.cs
│   │   ├── TestCaseElementIdHelper.cs
│   │   ├── TestCaseNoteHelper.cs
│   │   ├── TestCaseTagHelper.cs
│   │   └── TestCaseToneHelper.cs
│   ├── IO/
│   │   ├── Serialization/
│   │   │   ├── Converters/
│   │   │   │   ├── BaseSingleConverterTest.cs
│   │   │   │   ├── ColourConverterTest.cs
│   │   │   │   ├── CultureInfoConverterTest.cs
│   │   │   │   ├── ElementIdConverterTest.cs
│   │   │   │   ├── FontUsageConverterTest.cs
│   │   │   │   ├── KaraokeSkinElementConverterTest.cs
│   │   │   │   ├── LyricConverterTest.cs
│   │   │   │   ├── ReferenceLyricPropertyConfigConverterTest.cs
│   │   │   │   ├── RubyTagConverterTest.cs
│   │   │   │   ├── RubyTagsConverterTest.cs
│   │   │   │   ├── ShaderConverterTest.cs
│   │   │   │   ├── StageInfoConverterTest.cs
│   │   │   │   ├── TimeTagConverterTest.cs
│   │   │   │   ├── TimeTagsConverterTest.cs
│   │   │   │   ├── ToneConverterTest.cs
│   │   │   │   └── TranslationConverterTest.cs
│   │   │   ├── KaraokeJsonSerializableExtensionsTest.cs
│   │   │   └── SkinJsonSerializableExtensionsTest.cs
│   │   └── Stores/
│   │       ├── BaseGlyphStoreTest.cs
│   │       └── TtfGlyphStoreTest.cs
│   ├── Integration/
│   │   └── Formats/
│   │       ├── KarDecoderTest.cs
│   │       ├── KarEncoderTest.cs
│   │       ├── KarFileTest.cs
│   │       ├── LrcDecoderTest.cs
│   │       ├── LrcEncoderTest.cs
│   │       ├── LrcParserUtilsTest.cs
│   │       ├── LyricTextDecoderTest.cs
│   │       └── LyricTextEncoderTest.cs
│   ├── KaraokeTestBrowser.cs
│   ├── Mods/
│   │   ├── KaraokeModStageTestScene.cs
│   │   ├── KaraokeModTestScene.cs
│   │   ├── ModsTest.cs
│   │   ├── TestSceneKaraokeModAutoplay.cs
│   │   ├── TestSceneKaraokeModAutoplayBySinger.cs
│   │   ├── TestSceneKaraokeModClassicStage.cs
│   │   ├── TestSceneKaraokeModDisableNote.cs
│   │   ├── TestSceneKaraokeModFlashlight.cs
│   │   ├── TestSceneKaraokeModFun.cs
│   │   ├── TestSceneKaraokeModLyricConfiguration.cs
│   │   ├── TestSceneKaraokeModPerfect.cs
│   │   ├── TestSceneKaraokeModPractice.cs
│   │   ├── TestSceneKaraokeModPreviewStage.cs
│   │   ├── TestSceneKaraokeModSuddenDeath.cs
│   │   └── TestSceneKaraokeModTranslation.cs
│   ├── Objects/
│   │   ├── LyricTest.cs
│   │   ├── NoteTest.cs
│   │   ├── RubyTagTest.cs
│   │   ├── TimeTagTest.cs
│   │   ├── ToneCalculationTest.cs
│   │   ├── Utils/
│   │   │   ├── LyricUtilsTest.cs
│   │   │   ├── LyricsUtilsTest.cs
│   │   │   ├── NoteUtilsTest.cs
│   │   │   ├── NotesUtilsTest.cs
│   │   │   ├── OrderUtilsTest.cs
│   │   │   ├── RubyTagUtilsTest.cs
│   │   │   ├── RubyTagsUtilsTest.cs
│   │   │   ├── TimeTagUtilsTest.cs
│   │   │   └── TimeTagsUtilsTest.cs
│   │   └── Workings/
│   │       ├── HitObjectWorkingPropertyValidatorTest.cs
│   │       ├── LyricWorkingPropertyValidatorTest.cs
│   │       └── NoteWorkingPropertyValidatorTest.cs
│   ├── Overlays/
│   │   ├── Changelog/
│   │   │   ├── ChangelogPullRequestInfoTest.cs
│   │   │   ├── TestSceneKaraokeChangeLogMarkdownContainer.cs
│   │   │   └── TestSceneKaraokeChangeLogOverlay.cs
│   │   └── TestSceneOverlayColourProvider.cs
│   ├── Ranking/
│   │   ├── TestKaraokeScoreInfo.cs
│   │   ├── TestSceneBeatmapMetadataGraph.cs
│   │   ├── TestSceneHitEventTimingDistributionGraph.cs
│   │   ├── TestSceneNotScorableGraph.cs
│   │   ├── TestSceneScoringResultGraph.cs
│   │   └── TestSceneStatisticsPanel.cs
│   ├── Replays/
│   │   ├── TestSceneAutoGeneration.cs
│   │   └── TestSceneAutoGenerationBySinger.cs
│   ├── Resources/
│   │   ├── TestResources.cs
│   │   ├── Testing/
│   │   │   ├── Beatmaps/
│   │   │   │   ├── karaoke-file-samples-expected-conversion.json
│   │   │   │   ├── karaoke-file-samples-without-note.osu
│   │   │   │   ├── karaoke-file-samples.osu
│   │   │   │   ├── karaoke-note-samples.osu
│   │   │   │   └── karaoke-translation-samples.osu
│   │   │   ├── Fonts/
│   │   │   │   └── Fnt/
│   │   │   │       └── OpenSans/
│   │   │   │           └── LICENSE.txt
│   │   │   ├── Kar/
│   │   │   │   ├── default.kar
│   │   │   │   └── light.kar
│   │   │   └── Track/
│   │   │       └── demo.json
│   │   └── special-skin/
│   │       ├── default.json
│   │       ├── lyric-font-infos.json
│   │       └── note-styles.json
│   ├── Screens/
│   │   ├── Edit/
│   │   │   ├── Beatmap/
│   │   │   │   ├── BeatmapEditorScreenTestScene.cs
│   │   │   │   ├── Components/
│   │   │   │   │   └── TestSceneLyricSelector.cs
│   │   │   │   ├── Lyrics/
│   │   │   │   │   ├── CaretPosition/
│   │   │   │   │   │   ├── Algorithms/
│   │   │   │   │   │   │   ├── BaseCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── BaseCharIndexCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── BaseIndexCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── ClickingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CreateRubyTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CuttingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── NavigateCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   └── TypingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   └── IndexCaretPositionTest.cs
│   │   │   │   │   ├── Content/
│   │   │   │   │   │   ├── SingleLyricEditorTest.cs
│   │   │   │   │   │   ├── TestSceneInteractableLyric.cs
│   │   │   │   │   │   └── TestScenePreviewKaraokeSpriteText.cs
│   │   │   │   │   ├── LyricEditorTest.cs
│   │   │   │   │   ├── LyricEditorVerifierTest.cs
│   │   │   │   │   ├── Settings/
│   │   │   │   │   │   └── TestSceneLyricEditorDescriptionTextFlowContainer.cs
│   │   │   │   │   ├── States/
│   │   │   │   │   │   ├── BaseLyricCaretStateTest.cs
│   │   │   │   │   │   ├── LyricCaretStateActionTest.cs
│   │   │   │   │   │   ├── LyricCaretStateMoveCaretTest.cs
│   │   │   │   │   │   └── LyricCaretStateSwitchModeTest.cs
│   │   │   │   │   └── TestSceneLyricEditorColourProvider.cs
│   │   │   │   ├── TestSceneEditorMenuBar.cs
│   │   │   │   ├── TestSceneKaraokeBeatmapEditor.cs
│   │   │   │   ├── TestSceneLyricEditorScreen.cs
│   │   │   │   ├── TestScenePageScreen.cs
│   │   │   │   ├── TestSceneSingerScreen.cs
│   │   │   │   └── TestSceneTranslationsScreen.cs
│   │   │   ├── Components/
│   │   │   │   ├── Issues/
│   │   │   │   │   ├── TestSceneIssueIcon.cs
│   │   │   │   │   └── TestSceneIssuesToolTip.cs
│   │   │   │   └── Markdown/
│   │   │   │       └── TestSceneDescriptionTextFlowContainer.cs
│   │   │   ├── GenericEditorScreenTestScene.cs
│   │   │   ├── GenericEditorTestScene.cs
│   │   │   ├── Import/
│   │   │   │   └── TestSceneLyricImporter.cs
│   │   │   └── Stages/
│   │   │       └── Classic/
│   │   │           ├── ClassicStageScreenTestScene.cs
│   │   │           ├── TestSceneClassicStageEditor.cs
│   │   │           ├── TestSceneConfigScreen.cs
│   │   │           └── TestSceneStageScreen.cs
│   │   ├── ScreenTestScene.cs
│   │   ├── Settings/
│   │   │   ├── Previews/
│   │   │   │   └── TestSceneMicrophoneSoundVisualizer.cs
│   │   │   └── TestSceneKaraokeSettings.cs
│   │   ├── Skin/
│   │   │   ├── KaraokeSkinEditorScreenTestScene.cs
│   │   │   ├── TestSceneConfigScreen.cs
│   │   │   ├── TestSceneKaraokeSkinEditor.cs
│   │   │   └── TestSceneStyleScreen.cs
│   │   ├── TestManageFontPreview.cs
│   │   └── TestSceneGeneratorConfigPopover.cs
│   ├── Skinning/
│   │   ├── Fonts/
│   │   │   ├── BitmapFontCompressorTest.cs
│   │   │   └── BitmapFontImageGeneratorTest.cs
│   │   ├── KaraokeBeatmapSkinDecodingTest.cs
│   │   ├── KaraokeHitObjectTestScene.cs
│   │   ├── KaraokeSkinDecodingTest.cs
│   │   ├── KaraokeSkinnableColumnTestScene.cs
│   │   ├── KaraokeSkinnableTestScene.cs
│   │   ├── NotePlayfieldTestContainer.cs
│   │   ├── TestSceneColumnBackground.cs
│   │   ├── TestSceneDrawableJudgement.cs
│   │   ├── TestSceneHitExplosion.cs
│   │   ├── TestSceneLyric.cs
│   │   ├── TestSceneNote.cs
│   │   └── TestSceneNotePlayfield.cs
│   ├── Stages/
│   │   ├── Drawables/
│   │   │   └── TestSceneDrawableStageBeatmapCoverInfo.cs
│   │   └── Infos/
│   │       ├── Classic/
│   │       │   └── ClassicLyricTimingInfoTest.cs
│   │       ├── Preview/
│   │       │   └── PreviewStageTimingCalculatorTest.cs
│   │       └── StageElementCategoryTest.cs
│   ├── TestSceneOsuGame.cs
│   ├── UI/
│   │   ├── Position/
│   │   │   └── NotePositionCalculatorTest.cs
│   │   ├── TestSceneControlLayer.cs
│   │   ├── TestSceneKaraokePlayer.cs
│   │   ├── TestSceneNotePlayfield.cs
│   │   ├── TestSceneRulesetIcon.cs
│   │   └── TestSceneScoringStatus.cs
│   ├── Utils/
│   │   ├── BindablesUtilsTest.cs
│   │   ├── CharUtilsTest.cs
│   │   ├── ComparableUtilsTest.cs
│   │   ├── CultureInfoUtilsTest.cs
│   │   ├── EnumUtilsTest.cs
│   │   ├── FontUsageUtilsTest.cs
│   │   ├── FontUtilsTest.cs
│   │   ├── JpStringUtilsTest.cs
│   │   ├── RectangleFUtilsTest.cs
│   │   ├── TextIndexUtilsTest.cs
│   │   ├── TypeUtilsTest.cs
│   │   └── VersionUtilsTest.cs
│   ├── VisualTestRunner.cs
│   └── osu.Game.Rulesets.Karaoke.Tests.csproj
├── osu.Game.Rulesets.Karaoke.sln
├── osu.Game.Rulesets.Karaoke.sln.DotSettings
└── osu.licenseheader

================================================
FILE CONTENTS
================================================

================================================
FILE: .config/dotnet-tools.json
================================================
{
  "version": 1,
  "isRoot": true,
  "tools": {
    "ppy.localisationanalyser.tools": {
      "version": "2024.802.0",
      "commands": [
        "localisation"
      ]
    },
    "jetbrains.resharper.globaltools": {
      "version": "2025.1.3",
      "commands": [
        "jb"
      ]
    },
    "nvika": {
      "version": "4.0.0",
      "commands": [
        "nvika"
      ]
    },
    "codefilesanity": {
      "version": "0.0.37",
      "commands": [
        "CodeFileSanity"
      ]
    }
  }
}

================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome: http://editorconfig.org
root = true

[*.{csproj,props,targets}]
charset = utf-8-bom
end_of_line = crlf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

[g_*.cs]
generated_code = true

[*.cs]
end_of_line = crlf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

#license header
file_header_template = Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\nSee the LICENCE file in the repository root for full licence text.

#Roslyn naming styles

#PascalCase for public and protected members
dotnet_naming_style.pascalcase.capitalization = pascal_case
dotnet_naming_symbols.public_members.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_members.applicable_kinds = property,method,field,event
dotnet_naming_rule.public_members_pascalcase.severity = error
dotnet_naming_rule.public_members_pascalcase.symbols = public_members
dotnet_naming_rule.public_members_pascalcase.style = pascalcase

#camelCase for private members
dotnet_naming_style.camelcase.capitalization = camel_case

dotnet_naming_symbols.private_members.applicable_accessibilities = private
dotnet_naming_symbols.private_members.applicable_kinds = property,method,field,event
dotnet_naming_rule.private_members_camelcase.severity = warning
dotnet_naming_rule.private_members_camelcase.symbols = private_members
dotnet_naming_rule.private_members_camelcase.style = camelcase

dotnet_naming_symbols.local_function.applicable_kinds = local_function
dotnet_naming_rule.local_function_camelcase.severity = warning
dotnet_naming_rule.local_function_camelcase.symbols = local_function
dotnet_naming_rule.local_function_camelcase.style = camelcase

#all_lower for private and local constants/static readonlys
dotnet_naming_style.all_lower.capitalization = all_lower
dotnet_naming_style.all_lower.word_separator = _

dotnet_naming_symbols.private_constants.applicable_accessibilities = private
dotnet_naming_symbols.private_constants.required_modifiers = const
dotnet_naming_symbols.private_constants.applicable_kinds = field
dotnet_naming_rule.private_const_all_lower.severity = warning
dotnet_naming_rule.private_const_all_lower.symbols = private_constants
dotnet_naming_rule.private_const_all_lower.style = all_lower

dotnet_naming_symbols.private_static_readonly.applicable_accessibilities = private
dotnet_naming_symbols.private_static_readonly.required_modifiers = static,readonly
dotnet_naming_symbols.private_static_readonly.applicable_kinds = field
dotnet_naming_rule.private_static_readonly_all_lower.severity = warning
dotnet_naming_rule.private_static_readonly_all_lower.symbols = private_static_readonly
dotnet_naming_rule.private_static_readonly_all_lower.style = all_lower

dotnet_naming_symbols.local_constants.applicable_kinds = local
dotnet_naming_symbols.local_constants.required_modifiers = const
dotnet_naming_rule.local_const_all_lower.severity = warning
dotnet_naming_rule.local_const_all_lower.symbols = local_constants
dotnet_naming_rule.local_const_all_lower.style = all_lower

#ALL_UPPER for non private constants/static readonlys
dotnet_naming_style.all_upper.capitalization = all_upper
dotnet_naming_style.all_upper.word_separator = _

dotnet_naming_symbols.public_constants.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_constants.required_modifiers = const
dotnet_naming_symbols.public_constants.applicable_kinds = field
dotnet_naming_rule.public_const_all_upper.severity = warning
dotnet_naming_rule.public_const_all_upper.symbols = public_constants
dotnet_naming_rule.public_const_all_upper.style = all_upper

dotnet_naming_symbols.public_static_readonly.applicable_accessibilities = public,internal,protected,protected_internal,private_protected
dotnet_naming_symbols.public_static_readonly.required_modifiers = static,readonly
dotnet_naming_symbols.public_static_readonly.applicable_kinds = field
dotnet_naming_rule.public_static_readonly_all_upper.severity = warning
dotnet_naming_rule.public_static_readonly_all_upper.symbols = public_static_readonly
dotnet_naming_rule.public_static_readonly_all_upper.style = all_upper

#Roslyn formating options

#Formatting - indentation options
csharp_indent_case_contents = true
csharp_indent_case_contents_when_block = false
csharp_indent_labels = one_less_than_current
csharp_indent_switch_labels = true

#Formatting - new line options
csharp_new_line_before_catch = true
csharp_new_line_before_else = true
csharp_new_line_before_finally = true
csharp_new_line_before_open_brace = all
#csharp_new_line_before_members_in_anonymous_types = true
#csharp_new_line_before_members_in_object_initializers = true # Currently no effect in VS/dotnet format (16.4), and makes Rider confusing
csharp_new_line_between_query_expression_clauses = true

#Formatting - organize using options
dotnet_sort_system_directives_first = true

#Formatting - spacing options
csharp_space_after_cast = false
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_parameter_list_parentheses = false

#Formatting - wrapping options
csharp_preserve_single_line_blocks = true
csharp_preserve_single_line_statements = true

#Roslyn language styles

#Style - this. qualification
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning

#Style - type names
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning
csharp_style_var_when_type_is_apparent = true:none
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_elsewhere = true:silent

#Style - modifiers
dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
csharp_preferred_modifier_order = public,private,protected,internal,new,abstract,virtual,sealed,override,static,readonly,extern,unsafe,volatile,async:warning

#Style - parentheses
# Skipped because roslyn cannot separate +-*/ with << >>

#Style - expression bodies
csharp_style_expression_bodied_accessors = true:warning
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_indexers = true:warning
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = true:warning
csharp_style_expression_bodied_properties = true:warning
csharp_style_expression_bodied_local_functions = true:silent

#Style - expression preferences
dotnet_style_object_initializer = true:warning
dotnet_style_collection_initializer = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_prefer_compound_assignment = true:warning

#Style - null/type checks
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_throw_expression = true:silent
csharp_style_conditional_delegate_call = true:warning

#Style - unused
dotnet_style_readonly_field = true:silent
dotnet_code_quality_unused_parameters = non_public:silent
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_style_unused_value_assignment_preference = discard_variable:warning

#Style - variable declaration
csharp_style_inlined_variable_declaration = true:warning
csharp_style_deconstructed_variable_declaration = false:silent

#Style - other C# 7.x features
dotnet_style_prefer_inferred_tuple_names = true:warning
csharp_prefer_simple_default_expression = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent

#Style - C# 8 features
csharp_prefer_static_local_function = true:warning
csharp_prefer_simple_using_statement = true:silent
csharp_style_prefer_index_operator = false:silent
csharp_style_prefer_range_operator = false:silent
csharp_style_prefer_switch_expression = false:none

#Style - C# 10 features
csharp_style_namespace_declarations = file_scoped:suggestion

#Style - C# 12 features
csharp_style_prefer_primary_constructors = false

[*.{yaml,yml}]
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true

dotnet_diagnostic.OLOC001.words_in_name = 5
dotnet_diagnostic.OLOC001.license_header = // Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\n// See the LICENCE file in the repository root for full licence text.


================================================
FILE: .git-blame-ignore-revs
================================================
# Partial everything
c3d76bde9f3d78b420ab6a18b8191c00a503b2be
# Make test project to the file-scope namespace
3546a366f24d23dee1188758df0f8c6744dd1001
# Make main project to the file-scope namespace
5597711949c30a9699c4ab3957c0d98e6ff2212c
# Apply the trailing comma in the whole solution.
70fa847a40aa6a6c8ea3f1b277e4c2a23c8484a4

================================================
FILE: .gitattributes
================================================
# Autodetect text files and ensure that we normalise their
# line endings to lf internally. When checked out they may
# use different line endings.
* text=auto

# Check out with crlf (Windows) line endings
*.sln text eol=crlf
*.csproj text eol=crlf
*.cs text diff=csharp eol=crlf
*.resx text eol=crlf
*.vsixmanifest text eol=crlf
packages.config text eol=crlf
App.config text eol=crlf
*.bat text eol=crlf
*.cmd text eol=crlf
*.snippet text eol=crlf
*.manifest text eol=crlf
*.licenseheader text eol=crlf

# Check out with lf (UNIX) line endings
*.sh text eol=lf
.gitignore text eol=lf
.gitattributes text eol=lf
*.md text eol=lf
.travis.yml text eol=lf

================================================
FILE: .github/CODEOWNERS
================================================
# License related
/CodeAnalysis/      @andy840119
/LICENSE            @andy840119
/README.md          @andy840119
/osu.licenseheader  @andy840119


# CI config
/.github/               @andy840119
/Directory.Build.props  @andy840119
/appveyor.yml           @andy840119
/cake.config            @andy840119

# Resource related
/assets/                                      @andy840119
/osu.Game.Rulesets.Karaoke/Resources/         @andy840119
/osu.Game.Rulesets.Karaoke.Tests/Resources/   @andy840119

# Editor or git config
/.config/dotnet-tools.json                    @andy840119
/.editorconfig                                @andy840119
/.gitattributes                               @andy840119
/.gitignore                                   @andy840119
/osu.Game.Rulesets.Karaoke.sln                @andy840119
/osu.Game.Rulesets.Karaoke.sln.DotSettings    @andy840119


================================================
FILE: .github/labeler.yml
================================================
localization:
  - osu.Game.Rulesets.Karaoke/Localisation/*


================================================
FILE: .github/workflows/ci.yml
================================================
name: .NET Core

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:
    name: Build and Test
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
    - name: Install dependencies
      run: dotnet restore
    - name: Build with .NET
      run: dotnet build --no-restore --configuration Release
    - name: Unit Tests
      run: dotnet test --no-build --no-restore --configuration Release


================================================
FILE: .github/workflows/crowdin.yml
================================================
name: Crowdin Action

on:
  push:
    branches: [ master ]
    paths:
      - 'osu.Game.Rulesets.Karaoke/Localisation/**'

jobs:
  generate-localization-file:
    name: Generate the localization file
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Install dependencies
        run: dotnet restore
      - name: Install the localization tools.
        run: dotnet tool restore
      - name: Generate the localization file
        run: dotnet localisation to-resx ./osu.Game.Rulesets.Karaoke/osu.Game.Rulesets.Karaoke.csproj --output ./crowdin

      - name: Upload the localization into crowdin
        uses: crowdin/github-action@1.4.9
        with:
          # upload the source to the target path of the https://github.com/karaoke-dev/karaoke-resources
          # see the document in the https://support.crowdin.com/configuration-file/?q=dest
          upload_sources: true
          upload_sources_args: '--dest master/osu.Game.Rulesets.Karaoke.Resources/Localisation/%file_name%.%file_extension%'
          source: crowdin/*.resx
          # there's no translation can be uploaded in this repo, but we still need to give it a value.
          translation: crowdin/%file_name%.%locale%.%file_extension%
          # This is a numeric id, not to be confused with Crowdin API v1 "project identifier" string.
          # See "API v2" on https://crowdin.com/project/<your-project>/settings#api
          project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
          # A personal access token, not to be confused with Crowdin API v1 "API key".
          # See https://crowdin.com/settings#api-key to generate a token.
          token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
          CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}

      - name: Send notification after upload success or failed.
        uses: mshick/add-pr-comment@v2
        with:
          if: always()
          message: |
            🚀🚀🚀 New localization string has been successfully uploaded to the crowdin 🚀🚀🚀
            Go to https://crowdin.com/project/karaoke-dev to fill the translation.
          message-failure: |
            💥💥💥 New localization string uploaded failed to the crowdin. 💥💥💥
            You can ignore this message or contact to the developer if you want to translate it now.


================================================
FILE: .github/workflows/dotnet-format.yml
================================================
name: Format check on pull request
on: pull_request

jobs:
  dotnet-format:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4

      - name: Install .NET 8.0.x
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "8.0.x"

      - name: Restore Tools
        run: dotnet tool restore

      - name: Restore Packages
        run: dotnet restore osu.Game.Rulesets.Karaoke.sln

      - name: Restore inspectcode cache
        uses: actions/cache@v4
        with:
          path: ${{ github.workspace }}/inspectcode
          key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu*.sln', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}

      - name: Dotnet code style
        # The EnforceCodeStyleInBuild might cause false positive errors, disabling.
        # run: dotnet build -c Debug -warnaserror osu.Game.Rulesets.Karaoke.sln -p:EnforceCodeStyleInBuild=true
        run: dotnet build -c Debug -warnaserror osu.Game.Rulesets.Karaoke.sln

      - name: CodeFileSanity
        run: |
          exit_code=0
          while read -r line; do
            if [[ ! -z "$line" ]]; then
              echo "::error::$line"
              exit_code=1
            fi
          done <<< $(dotnet codefilesanity)
          exit $exit_code

      - name: InspectCode
        # Still use XML output since vika's poor support for new formats
        run: dotnet jb inspectcode $(pwd)/osu.Game.Rulesets.Karaoke.sln --no-build -f="xml" --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN

      - name: NVika
        run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors


================================================
FILE: .github/workflows/labeler.yml
================================================
name: Pull Request Labeler

on:
  pull_request_target:
    paths:
      # we only add use this action for add the localization label for now, so run this action if localization changed.
      - 'osu.Game.Rulesets.Karaoke/Localisation/**'

jobs:
  triage:
    permissions:
      contents: read
      pull-requests: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@v4
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"


================================================
FILE: .github/workflows/release.yml
================================================
name: Tagged Release
on:
  push:
    tags: ['*']

jobs:
  build:
    name: Build and Create Release
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2
    - name: Setup .NET 8.0.x
      uses: actions/setup-dotnet@v3
      with:
        dotnet-version: "8.0.x"
    - name: Fetch all tags
      run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
    - name: Get current tag
      run: echo "CURRENT_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --max-count=1))" >> $GITHUB_ENV
    - name: Install dependencies
      run: dotnet restore
    - name: Build
      run: dotnet build osu.Game.Rulesets.Karaoke --configuration Release -p:version=${{env.CURRENT_TAG}} --no-restore
    - name: Create Release
      id: create_release
      uses: actions/create-release@latest
      env:
        GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
      with:
        tag_name: ${{ github.ref }}
        release_name: ${{ github.ref }}
    - name: Zip the dlls
      run: |
        cd osu.Game.Rulesets.Karaoke/bin/Release/net8.0/DLLs
        zip -r ../osu.Game.Rulesets.Karaoke.zip ./*
    - name: Upload Release Asset
      uses: softprops/action-gh-release@v1
      with:
        token: ${{ secrets.RELEASE_TOKEN }}
        files: |
          osu.Game.Rulesets.Karaoke/bin/Release/net8.0/osu.Game.Rulesets.Karaoke.zip
        draft: true
        body: |
          Thank you for showing interest in this ruleset. This is a tagged release (${{ env.CURRENT_TAG }}).
    - name: Generate changelog
      run: |
        sudo npm install github-release-notes -g
        gren release -T ${{secrets.RELEASE_TOKEN}} --tags=${{env.CURRENT_TAG}} --override


================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
project.fragment.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
Resource.designer.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

# Cake #
/tools/**
/build/tools/**
/build/temp/**

# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
.idea/modules.xml
.idea/*.iml
.idea/modules
*.iml
*.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

# fastlane
fastlane/report.xml

# inspectcode
inspectcodereport.xml
inspectcode

# BenchmarkDotNet
/BenchmarkDotNet.Artifacts

*.GeneratedMSBuildEditorConfig.editorconfig


================================================
FILE: .globalconfig
================================================
is_global = true

# .NET Code Style
# IDE styles reference: https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/

# IDE0001: Simplify names
dotnet_diagnostic.IDE0001.severity = warning

# IDE0002: Simplify member access
dotnet_diagnostic.IDE0002.severity = warning

# IDE0003: Remove qualification
dotnet_diagnostic.IDE0003.severity = warning

# IDE0004: Remove unnecessary cast
dotnet_diagnostic.IDE0004.severity = warning

# IDE0005: Remove unnecessary imports
dotnet_diagnostic.IDE0005.severity = warning

# IDE0034: Simplify default literal
dotnet_diagnostic.IDE0034.severity = warning

# IDE0036: Sort modifiers
dotnet_diagnostic.IDE0036.severity = warning

# IDE0040: Add accessibility modifier
dotnet_diagnostic.IDE0040.severity = warning

# IDE0049: Use keyword for type name
dotnet_diagnostic.IDE0040.severity = warning

# IDE0055: Fix formatting
dotnet_diagnostic.IDE0055.severity = warning

# IDE0051: Private method is unused
dotnet_diagnostic.IDE0051.severity = silent

# IDE0052: Private member is unused
dotnet_diagnostic.IDE0052.severity = silent

# IDE0073: File header
dotnet_diagnostic.IDE0073.severity = warning

# IDE0130: Namespace mismatch with folder
dotnet_diagnostic.IDE0130.severity = warning

# IDE1006: Naming style
dotnet_diagnostic.IDE1006.severity = warning

#Disable operator overloads requiring alternate named methods
dotnet_diagnostic.CA2225.severity = none

# Banned APIs
dotnet_diagnostic.RS0030.severity = error


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing Guidelines

Thank you for showing interest in the development of karaoke ruleset. We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience.

## Table of contents

1. [Reporting bugs](#reporting-bugs)
2. [Providing general feedback](#providing-general-feedback)
3. [Issue or discussion?](#issue-or-discussion)
4. [Submitting pull requests](#submitting-pull-requests)
5. [Resources](#resources)

## Reporting bugs

A **bug** is a situation in which there is something clearly *and objectively* wrong with the ruleset. Examples of applicable bug reports are:

- The ruleset crashes to desktop when I start a beatmap
- Cannot load karoake beatmap that edited before.
- The ruleset slows down a lot when I play this specific map.
- Text effect looks weird if using directX renderer.

To track bug reports, we primarily use GitHub **issues**. When opening an issue, please keep in mind the following:

- Before opening the issue, please search for any similar existing issues using the text search bar and the issue labels. This includes both open and closed issues (we may have already fixed something, but the fix hasn't yet been released).
- When opening the issue, please fill out as much of the issue template as you can. In particular, please make sure to include logs and screenshots as much as possible. The instructions on how to find the log files are included in the issue template.
- We may ask you for follow-up information to reproduce or debug the problem. Please look out for this and provide follow-up info if we request it.

If we cannot reproduce the issue, it is deemed low priority, or it is deemed to be specific to your setup in some way, the issue may be downgraded to a discussion. This will be done by a maintainer for you.

## Providing general feedback

If you wish to:

- Provide *subjective* feedback on the ruleset (about how the UI looks, about how the default skin works, about ruleset mechanics, about how the PP and scoring systems work, etc.),
- Suggest a new feature to be added to the ruleset.
- Report a non-specific problem with the ruleset that you think may be connected to your hardware or operating system specifically.

then it is generally best to start with a **discussion** first. Discussions are a good avenue to group subjective feedback on a single topic, or gauge interest in a particular feature request.

When opening a discussion, please keep in mind the following:

- Use the search function to see if your idea has been proposed before, or if there is already a thread about a particular issue you wish to raise.
- If proposing a feature, please try to explain the feature in as much detail as possible.
- If you're reporting a non-specific problem, please provide applicable logs, screenshots, or video that illustrate the issue.

If a discussion gathers enough traction, then it may be converted into an issue. This will be done by a maintainer for you.

## Issue or discussion?

We realise that the line between an issue and a discussion may be fuzzy, so while we ask you to use your best judgement based on the description above, please don't think about it too hard either. Feedback in a slightly wrong place is better than no feedback at all.

When in doubt, it's probably best to start with a discussion first. We will escalate to issues as needed.

## Submitting pull requests

The [issue tracker](https://github.com/karaoke-dev/karaoke/issues) should provide plenty of issues to start with. We also have a [`Good for contributor`](https://github.com/karaoke-dev/karaoke/issues?q=is%3Aissue+is%3Aopen+label%3A"Good+for+contributor") label.

In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.

If you'd like to propose a subjective change to one of the visual aspects of the ruleset, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort.

Aside from the above, below is a brief checklist of things to watch out when you're preparing your code changes:

- Make sure you're comfortable with the principles of object-oriented programming, the syntax of `C\#` and your `development environment`.
- Make sure you are familiar with [git](https://git-scm.com/) and [the pull request workflow](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests).
- Discuss with us first if you're planning to work on a `bigger change`, or `it's UI/UX related`.
- Please do not make code changes via the GitHub web interface.
- Please add tests for your changes. We expect most new features and bugfixes to have test coverage, unless the effort of adding them is prohibitive. The visual testing methodology we use is described in more detail [here](https://github.com/ppy/osu-framework/wiki/Development-and-Testing).

After you're done with your changes and you wish to open the PR, please observe the following recommendations:

- Please submit the pull request from a [topic branch](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) (not `master`), and keep the *Allow edits from maintainers* check box selected, so that we can push fixes to your PR if necessary.
- Please write the commit messages with useful information in mind. We recommend reading [this article](https://chris.beams.io/posts/git-commit/) for some good tips.
- Unlike osu! project, `force-push` is allowed in here. Use it if you need to.
- Rebase the PR branch to the `master` if PR is too old or has conflicts.

We are highly committed to quality when it comes to the karaoke ruleset project.
This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state.

If you're uncertain about some part of the codebase or some inner workings of the karaoke ruleset, please reach out either by leaving a comment in the relevant issue, discussion, or PR thread, or by posting a message in the [development Discord server](https://discord.gg/ga2xZXk).
We will try to help you as much as we can.

## Resources

- [`ppy/osu`](https://github.com/ppy/osu): The game that karaoke ruleset is running on.
- [`ppy/osu` wiki](https://github.com/ppy/osu/wiki): Contains articles about various technical aspects of the game
- [`ppy/osu-framework`](https://github.com/ppy/osu-framework): The game framework that karaoke ruleset is running on.
- [`ppy/osu-framework` wiki](https://github.com/ppy/osu-framework/wiki): Contains introductory information about osu!framework, the bespoke 2D game framework we use for the game.
.


================================================
FILE: CodeAnalysis/BannedSymbols.txt
================================================
M:System.Object.Equals(System.Object,System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or EqualityComparer<T>.Default instead.
M:System.Object.Equals(System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or EqualityComparer<T>.Default instead.
M:System.ValueType.Equals(System.Object)~System.Boolean;Don't use object.Equals(Fallbacks to ValueType). Use IEquatable<T> or EqualityComparer<T>.Default instead.
M:System.Nullable`1.Equals(System.Object)~System.Boolean;Use == instead.
T:System.IComparable;Don't use non-generic IComparable. Use generic version instead.
T:SixLabors.ImageSharp.IDeepCloneable`1;Use osu.Game.Utils.IDeepCloneable<T> instead.
M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText.
M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900)
T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods.
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods.
M:Realms.IRealmCollection`1.SubscribeForNotifications`1(Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IRealmCollection<T>,NotificationCallbackDelegate<T>) instead.
M:System.Guid.#ctor;Probably meaning to use Guid.NewGuid() instead. If actually wanting empty, use Guid.Empty.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IQueryable<T>,NotificationCallbackDelegate<T>) instead.
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.


================================================
FILE: CodeAnalysis/osu.ruleset
================================================
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="osu!karaoke Rule Set" Description=" " ToolsVersion="16.0">
  <Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
    <Rule Id="CA1016" Action="None" />
    <Rule Id="CA1028" Action="None" />
    <Rule Id="CA1031" Action="None" />
    <Rule Id="CA1034" Action="None" />
    <Rule Id="CA1036" Action="None" />
    <Rule Id="CA1040" Action="None" />
    <Rule Id="CA1044" Action="None" />
    <Rule Id="CA1051" Action="None" />
    <Rule Id="CA1054" Action="None" />
    <Rule Id="CA1056" Action="None" />
    <Rule Id="CA1062" Action="None" />
    <Rule Id="CA1063" Action="None" />
    <Rule Id="CA1067" Action="None" />
    <Rule Id="CA1707" Action="None" />
    <Rule Id="CA1710" Action="None" />
    <Rule Id="CA1714" Action="None" />
    <Rule Id="CA1716" Action="None" />
    <Rule Id="CA1717" Action="None" />
    <Rule Id="CA1720" Action="None" />
    <Rule Id="CA1721" Action="None" />
    <Rule Id="CA1724" Action="None" />
    <Rule Id="CA1801" Action="None" />
    <Rule Id="CA1806" Action="None" />
    <Rule Id="CA1812" Action="None" />
    <Rule Id="CA1814" Action="None" />
    <Rule Id="CA1815" Action="None" />
    <Rule Id="CA1819" Action="None" />
    <Rule Id="CA1822" Action="None" />
    <Rule Id="CA1823" Action="None" />
    <Rule Id="CA2007" Action="Warning" />
    <Rule Id="CA2214" Action="None" />
    <Rule Id="CA2227" Action="None" />
  </Rules>
  <Rules AnalyzerId="Microsoft.CodeQuality.CSharp.Analyzers" RuleNamespace="Microsoft.CodeQuality.CSharp.Analyzers">
    <Rule Id="CA1001" Action="None" />
    <Rule Id="CA1032" Action="None" />
  </Rules>
  <Rules AnalyzerId="Microsoft.NetCore.Analyzers" RuleNamespace="Microsoft.NetCore.Analyzers">
    <Rule Id="CA1303" Action="None" />
    <Rule Id="CA1304" Action="None" />
    <Rule Id="CA1305" Action="None" />
    <Rule Id="CA1307" Action="None" />
    <Rule Id="CA1308" Action="None" />
    <Rule Id="CA1816" Action="None" />
    <Rule Id="CA1826" Action="None" />
    <Rule Id="CA2000" Action="None" />
    <Rule Id="CA2008" Action="None" />
    <Rule Id="CA2213" Action="None" />
    <Rule Id="CA2235" Action="None" />
  </Rules>
  <Rules AnalyzerId="Microsoft.NetCore.CSharp.Analyzers" RuleNamespace="Microsoft.NetCore.CSharp.Analyzers">
    <Rule Id="CA1309" Action="Warning" />
    <Rule Id="CA2201" Action="Warning" />
  </Rules>
</RuleSet>

================================================
FILE: Directory.Build.props
================================================
<!-- Contains required properties for osu!framework projects. -->
<Project>
  <PropertyGroup Label="C#">
    <LangVersion>12.0</LangVersion>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup Label="License">
    <None Include="$(MSBuildThisFileDirectory)osu.licenseheader">
      <Link>osu.licenseheader</Link>
    </None>
  </ItemGroup>
  <ItemGroup Label="Resources">
    <EmbeddedResource Include="Resources\**\*.*"/>
  </ItemGroup>
  <ItemGroup Label="Code Analysis">
    <PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3" PrivateAssets="All"/>
    <AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt"/>
  </ItemGroup>
  <PropertyGroup Label="Code Analysis">
    <CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
  </PropertyGroup>
  <PropertyGroup Label="Documentation">
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);CS1591</NoWarn>
  </PropertyGroup>
</Project>


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.


================================================
FILE: README.md
================================================
![](assets/logo.png)

# karaoke --dev
[![CodeFactor](https://www.codefactor.io/repository/github/karaoke-dev/karaoke/badge)](https://www.codefactor.io/repository/github/karaoke-dev/karaoke)
[![Build status](https://ci.appveyor.com/api/projects/status/07ytm0sei6l5oy08?svg=true)](https://ci.appveyor.com/project/andy840119/karaoke)
[![Crowdin](https://badges.crowdin.net/karaoke-dev/localized.svg)](https://crowdin.com/project/karaoke-dev)
[![Waifu](https://img.shields.io/badge/月子我婆-passed-ff69b4.svg)](https://github.com/karaoke-dev/karaoke)
[![GitHub last commit](https://img.shields.io/github/last-commit/karaoke-dev/karaoke)](https://github.com/karaoke-dev/karaoke/releases)
[![Tagged Release](https://github.com/karaoke-dev/karaoke/workflows/Tagged%20Release/badge.svg)](https://github.com/karaoke-dev/karaoke/releases)
[![dev chat](https://discordapp.com/api/guilds/299006062323826688/widget.png?style=shield)](https://discord.gg/ga2xZXk)
[![Total lines](https://tokei.rs/b1/github/karaoke-dev/karaoke)](https://ghloc.vercel.app/karaoke-dev/karaoke?branch=master)
[![Dashboard](https://img.shields.io/badge/Dashboard-stonks!-informational)](https://www.repotrends.com/karaoke-dev/karaoke)
[![Star History Chart](https://img.shields.io/github/stars/karaoke-dev/karaoke?style=flat&label=Stars&color=yellow&cacheSeconds=86000)](https://seladb.github.io/StarTrack-js/#/preload?r=karaoke-dev,karaoke)
[![airpods pro](https://img.shields.io/badge/Andy's%20airpods%20pro-missing-red.svg)](https://github.com/karaoke-dev/karaoke/issues/1514)
[![airpods 2](https://img.shields.io/badge/Andy's%20airpods%202-missing-red)](https://github.com/karaoke-dev/karaoke/issues/1513)


The source code of the `karaoke` ruleset, running on [osu!lazer](https://github.com/ppy/osu).

## Status

This project is still not very stable, `so we recommend looking around this project to find new features instead of actually using it`. 

Also:
- This project doesn't have much of a [demo](https://github.com/karaoke-dev/sample-beatmap) currently available. And most demos are Japanese only.
- This project is not very stable, especially in the editor.
- Beatmap does not support save feature.

Reccommend using this ruleset until [support batch import song](https://github.com/karaoke-dev/karaoke/issues/2144).

If you run into any problems, you can shoot us an email (support@karaoke.dev) or send me a message on [Discord](https://discord.gg/ga2xZXk). I will typically reply faster on Discord.

And feel free to report any bugs if found.

## How to run this project

See [this tutorial](https://karaoke-dev.github.io/how-to-install/) to get the ruleset from the existing build.

Or you can compile it yourself: `release build` then copy `Packed/osu.Game.Rulesets.Karaoke.dll` into your [ruleset folder](https://github.com/LumpBloom7/sentakki/wiki/Ruleset-installation-guide)

## License

This repo is covered under the [GPL V3](LICENSE) license.
If you plan on using this repo for commercial purposes, please contact us at (support@karaoke.dev) to get permission first.

Using this repo to create, use or using the beatmap format to distribution any `PIRATED`, `unauthorized` karaoke songs/beatmaps is absolutely forbidden.
This repo is trying to make song author(or people has copyright) ability to distribution their songs with karaoke format without any restriction, not for copycat to make thing with copyright issue.

## Thanks to

- [osu!](https://github.com/ppy/osu) and it's [framework](https://github.com/ppy/osu-framework) for karaoke!

- [RhythmKaTTE](http://juna-idler.blogspot.com/2016/05/rhythmkatte-version-01.html), [RhythmicaLyrics](http://suwa.pupu.jp/RhythmicaLyrics.html) and [Aegisub](https://github.com/Aegisub/Aegisub), an open-source software used to create lyrics with time tags.
Parts of the lyrics editor in this ruleset were inspired by them.

- [ニコカラメーカー](http://shinta0806be.ldblog.jp/tag/%E3%83%8B%E3%82%B3%E3%82%AB%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC), a software to convert `.lrc` files into karaoke video with beautiful text effects.

- [JetBrains](https://www.jetbrains.com/?from=osu-karaoke), for contributing a free [Rider](https://www.jetbrains.com/rider/) license used to developing.

- [Appveyor](https://www.appveyor.com/), [CodeFactor](https://www.codefactor.io/) and [Github action](https://github.com/features/actions) for providing free `CI`/`CD` service.

- [Figma](https://www.figma.com/), for quick creation of assets like logos or icon.

- [Miro](https://miro.com/). Used for flow-charts and deciding how to structure some parts.


================================================
FILE: appveyor.yml
================================================
clone_depth: 1
version: '{branch}-{build}'
image: Visual Studio 2022
branches:
  only:
    - master
dotnet_csproj:
  patch: true
  file: 'osu.Game.Rulesets.Karaoke\osu.Game.Rulesets.Karaoke.csproj' # Use wildcard when it's able to exclude Xamarin projects
  version: '0.0.{build}'
cache:
  - '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml'
before_build:
  - ps: dotnet --info # Useful when version mismatch between CI and local
  - ps: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
build:
  project: osu.Game.Rulesets.Karaoke.sln
  parallel: true
  verbosity: minimal
after_build:
  - ps: dotnet tool restore
test:
  assemblies:
    except:
      - '**\*Android*'
      - '**\*iOS*'
      - 'build\**\*'


================================================
FILE: cake.config
================================================

[Nuget]
Source=https://api.nuget.org/v3/index.json
UseInProcessClient=true
LoadDependencies=true


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/ElementId.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

/// <summary>
/// As unique identifier for the elements in the <see cref="KaraokeBeatmap"/>
/// Like how <see cref="Guid"/> works.
/// </summary>
public readonly struct ElementId : IComparable, IComparable<ElementId>, IEquatable<ElementId>
{
    public static ElementId Empty => default;

    private const int length = 7;

    private readonly string? id;

    public ElementId(string id)
    {
        if (string.IsNullOrEmpty(id))
        {
            throw new ArgumentException("id should not be empty", nameof(id));
        }

        if (id.Length != length)
        {
            throw new ArgumentException($"id length must be {length}.", nameof(id));
        }

        if (!checkFormat(id))
        {
            throw new ArgumentException("id format is not correct", nameof(id));
        }

        this.id = id;
    }

    // char should be 0~9 and a~f
    private static bool checkFormat(string id)
        => id.Where(c => c is < '0' or > '9').All(c => c >= 'a' && c <= 'f');

    public static ElementId NewElementId()
    {
        // take 7 digits
        string str = Guid.NewGuid().ToString("N");
        string id = str[..length];
        return new ElementId(id);
    }

    public int CompareTo(ElementId other)
    {
        return string.Compare(id, other.id, StringComparison.Ordinal);
    }

    public int CompareTo(object? obj)
    {
        if (obj == null)
        {
            return 1;
        }

        if (obj is not ElementId elementId)
        {
            throw new ArgumentException("Compared object should be the same type.", nameof(obj));
        }

        return CompareTo(elementId);
    }

    public bool Equals(ElementId other)
    {
        return id == other.id;
    }

    public override bool Equals(object? obj)
    {
        return obj is ElementId other && Equals(other);
    }

    public static bool operator ==(ElementId id1, ElementId id2) => id1.Equals(id2);

    public static bool operator !=(ElementId id1, ElementId id2) => !id1.Equals(id2);

    public override int GetHashCode()
    {
        return (id ?? string.Empty).GetHashCode();
    }

    public override string ToString()
    {
        return id ?? string.Empty;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapDecoder.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.IO;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets.Karaoke.IO.Serialization;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Formats;

public class KaraokeJsonBeatmapDecoder : JsonBeatmapDecoder
{
    public new static void Register()
    {
        AddDecoder<Beatmap>("// karaoke json file format v", m => new KaraokeJsonBeatmapDecoder());

        // use this weird way to let all the fall-back beatmap(include karaoke beatmap) become karaoke beatmap.
        SetFallbackDecoder<Beatmap>(() => new KaraokeJsonBeatmapDecoder());
    }

    protected override void ParseStreamInto(LineBufferedReader stream, Beatmap output)
    {
        var globalSetting = KaraokeJsonSerializableExtensions.CreateGlobalSettings();
        globalSetting.ContractResolver = new KaraokeBeatmapContractResolver();

        // create id if object is by reference.
        globalSetting.PreserveReferencesHandling = PreserveReferencesHandling.Objects;

        // should not let json decoder to read this line.
        if (stream.PeekLine()?.Contains("// karaoke json file format v") ?? false)
        {
            stream.ReadLine();
        }

        // equal to stream.ReadToEnd().DeserializeInto(output); in the base class.
        JsonConvert.PopulateObject(stream.ReadToEnd(), output, globalSetting);
    }

    private class KaraokeBeatmapContractResolver : SnakeCaseKeyContractResolver
    {
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            var props = base.CreateProperties(type, memberSerialization);

            return type == typeof(BeatmapInfo)
                ? props.Where(p => p.PropertyName != "ruleset_id").ToList()
                : props;
        }
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapEncoder.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.IO.Serialization;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Formats;

public class KaraokeJsonBeatmapEncoder
{
    public string Encode(Beatmap output)
    {
        var globalSetting = KaraokeJsonSerializableExtensions.CreateGlobalSettings();
        string json = JsonConvert.SerializeObject(output, globalSetting);
        return "// karaoke json file format v1" + '\n' + json;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapDecoder.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Notes;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Formats;

public class KaraokeLegacyBeatmapDecoder : LegacyBeatmapDecoder
{
    public new const int LATEST_VERSION = 1;

    public new static void Register()
    {
        AddDecoder<Beatmap>("karaoke file format v", m => new KaraokeLegacyBeatmapDecoder(Parsing.ParseInt(m.Split('v').Last())));

        // use this weird way to let all the fall-back beatmap(include karaoke beatmap) become karaoke beatmap.
        SetFallbackDecoder<Beatmap>(() => new KaraokeLegacyBeatmapDecoder());
    }

    public KaraokeLegacyBeatmapDecoder(int version = LATEST_VERSION)
        : base(version)
    {
    }

    private readonly IList<string> karFormatLines = new List<string>();
    private readonly IList<string> noteLines = new List<string>();
    private readonly IList<string> translations = new List<string>();

    protected override void ParseLine(Beatmap beatmap, Section section, string line)
    {
        if (section != Section.HitObjects)
        {
            // should not let base.ParseLine read the line like "Mode: 111"
            if (line.StartsWith("Mode", StringComparison.Ordinal))
            {
                beatmap.BeatmapInfo.Ruleset = new KaraokeRuleset().RulesetInfo;
                return;
            }

            base.ParseLine(beatmap, section, line);
            return;
        }

        if (line.ToLower().StartsWith("@ruby", StringComparison.Ordinal))
        {
            // kar format queue
            karFormatLines.Add(line);
        }
        else if (line.ToLower().StartsWith("@note", StringComparison.Ordinal))
        {
            // add tone line queue
            noteLines.Add(line);
        }
        else if (line.ToLower().StartsWith("@tr", StringComparison.Ordinal))
        {
            // add translation queue
            translations.Add(line);
        }
        else if (line.StartsWith('@'))
        {
            // Remove @ in time tag and add into kar queue
            karFormatLines.Add(line[1..]);
        }
        else if (line.ToLower() == "end")
        {
            string content = string.Join("\n", karFormatLines);

            // Create decoder
            var decoder = new KarDecoder();
            var lyrics = decoder.Decode(content);

            // Apply hitobjects
            beatmap.HitObjects = lyrics.OfType<HitObject>().ToList();

            processNotes(beatmap, noteLines);
            processTranslations(beatmap, translations);
        }
    }

    private void processNotes(Beatmap beatmap, IList<string> lines)
    {
        var noteGenerator = new NoteGenerator(new NoteGeneratorConfig());

        // Remove all karaoke note
        beatmap.HitObjects.RemoveAll(x => x is Note);

        var lyrics = beatmap.HitObjects.OfType<Lyric>().ToList();

        for (int l = 0; l < lyrics.Count; l++)
        {
            var lyric = lyrics[l];
            string? line = lines.ElementAtOrDefault(l)?.Split('=').Last();

            // Create default note if not exist
            if (string.IsNullOrEmpty(line))
            {
                beatmap.HitObjects.AddRange(noteGenerator.Generate(lyric));
                continue;
            }

            string[] notes = line.Split(',');
            var defaultNotes = noteGenerator.Generate(lyric).ToList();
            int minNoteNumber = Math.Min(notes.Length, defaultNotes.Count);

            // Process each note
            for (int i = 0; i < minNoteNumber; i++)
            {
                string note = notes[i];
                var defaultNote = defaultNotes[i];

                // Support multi note in one time tag, format like ([1;0.5;か]|1#|...)
                if (!note.StartsWith('(') || !note.EndsWith(')'))
                {
                    // Process and add note
                    applyNote(defaultNote, note);
                    beatmap.HitObjects.Add(defaultNote);
                }
                else
                {
                    float startPercentage = 0;
                    string[] rubyNotes = note.Replace("(", string.Empty).Replace(")", string.Empty).Split('|');

                    for (int j = 0; j < rubyNotes.Length; j++)
                    {
                        string rubyNote = rubyNotes[j];

                        string tone;
                        float percentage = (float)Math.Round((float)1 / rubyNotes.Length, 2, MidpointRounding.AwayFromZero);
                        string? ruby = defaultNote.RubyText?.ElementAtOrDefault(j).ToString();

                        // Format like [1;0.5;か]
                        if (note.StartsWith('[') && note.EndsWith(']'))
                        {
                            string[] rubyNoteProperty = note.Replace("[", string.Empty).Replace("]", string.Empty).Split(';');

                            // Copy tome property
                            tone = rubyNoteProperty[0];

                            // Copy percentage property
                            if (rubyNoteProperty.Length >= 2)
                                float.TryParse(rubyNoteProperty[1], out percentage);

                            // Copy text property
                            if (rubyNoteProperty.Length >= 3)
                                ruby = rubyNoteProperty[2];
                        }
                        else
                        {
                            tone = rubyNote;
                        }

                        // Split note and apply them
                        var splitDefaultNote = SliceNote(defaultNote, startPercentage, percentage);
                        startPercentage += percentage;
                        if (!string.IsNullOrEmpty(ruby))
                            splitDefaultNote.Text = ruby;

                        // Process and add note
                        applyNote(splitDefaultNote, tone);
                        beatmap.HitObjects.Add(splitDefaultNote);
                    }
                }
            }
        }

        static void applyNote(Note note, string noteStr, string? ruby = null, double? duration = null)
        {
            if (noteStr == "-")
                note.Display = false;
            else
            {
                note.Display = true;
                note.Tone = convertTone(noteStr);
            }

            if (!string.IsNullOrEmpty(ruby))
                note.Text = ruby;

            if (duration != null)
                note.Duration = duration.Value;

            //Support format : 1  1.  1.5  1+  1#
            static Tone convertTone(string tone)
            {
                bool half = false;

                if (tone.Contains('.') || tone.Contains('#'))
                {
                    half = true;

                    // only get digit part
                    tone = tone.Split('.').FirstOrDefault()?.Split('#').FirstOrDefault() ?? string.Empty;
                }

                if (!int.TryParse(tone, out int scale))
                    throw new InvalidCastException($"{tone} does not support in {nameof(KaraokeLegacyBeatmapDecoder)}");

                return new Tone
                {
                    Scale = scale,
                    Half = half,
                };
            }
        }
    }

    private void processTranslations(Beatmap beatmap, IEnumerable<string> translationLines)
    {
        var availableTranslations = new List<CultureInfo>();

        var lyrics = beatmap.HitObjects.OfType<Lyric>().ToList();
        var translations = translationLines.Select(translation => new
        {
            key = translation.Split('=').FirstOrDefault()?.Split('[').LastOrDefault()?.Split(']').FirstOrDefault(),
            value = translation.Split('=').LastOrDefault() ?? string.Empty,
        }).GroupBy(x => x.key, y => y.value).ToList();

        foreach (var translation in translations)
        {
            // get culture and translation
            string? languageCode = translation.Key;
            if (string.IsNullOrEmpty(languageCode))
                continue;

            var cultureInfo = new CultureInfo(languageCode);
            var values = translation.ToList();

            int size = Math.Min(lyrics.Count, translation.Count());

            for (int j = 0; j < size; j++)
            {
                lyrics[j].Translations.Add(cultureInfo, values[j]);
            }

            availableTranslations.Add(cultureInfo);
        }

        var dictionary = new LegacyProperties
        {
            AvailableTranslationLanguages = availableTranslations,
        };

        beatmap.HitObjects.Add(dictionary);
    }

    internal static Note SliceNote(Note note, double startPercentage, double durationPercentage)
    {
        if (startPercentage < 0 || startPercentage + durationPercentage > 1)
            throw new ArgumentOutOfRangeException($"{nameof(Note)} cannot assign split range of start from {startPercentage} and duration {durationPercentage}");

        double durationFromStartTime = note.Duration * startPercentage;
        double secondNoteDuration = note.Duration * (1 - startPercentage - durationPercentage);

        // todo: there's no need to create the new note.
        var newNote = note.DeepClone();
        newNote.StartTimeOffset = note.StartTimeOffset + durationFromStartTime;
        newNote.EndTimeOffset = note.EndTimeOffset - secondNoteDuration;

        return newNote;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapEncoder.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Integration.Formats;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Formats;

public class KaraokeLegacyBeatmapEncoder
{
    public string Encode(Beatmap output)
    {
        var encoder = new KarEncoder();
        var results = new List<string>
        {
            encoder.Encode(output),
            string.Join("\n", encodeNotes(output)),
            string.Join("\n", encodeTranslations(output)),
        };

        return string.Join("\n\n", results.Where(x => !string.IsNullOrEmpty(x)));
    }

    private IEnumerable<string> encodeNotes(Beatmap output)
    {
        var notes = output.HitObjects.OfType<Note>().ToList();
        var lyrics = output.HitObjects.OfType<Lyric>().ToList();
        return notes.GroupBy(x => x.ReferenceLyric).Select(g =>
        {
            var lyric = g.Key;
            if (lyric == null)
                throw new ArgumentNullException();

            // Get note group
            var noteGroup = g.ToList().GroupBy(n => n.ReferenceTimeTagIndex);

            // Convert to group format
            string noteGroupStr = string.Join(",", noteGroup.Select(x =>
            {
                if (x.Count() == 1)
                    return convertNote(x.First());

                return "(" + string.Join("|", x.Select(convertNote)) + ")";
            }));

            return $"note{lyrics.IndexOf(lyric) + 1}={noteGroupStr}";
        }).ToList();

        // Convert single note
        static string convertNote(Note note)
        {
            return !note.Display
                ? "-"
                : convertTone(note.Tone);

            // Convert tone to string
            static string convertTone(Tone tone) => tone.Scale + (tone.Half ? "#" : string.Empty);
        }
    }

    private IEnumerable<string> encodeTranslations(Beatmap output)
    {
        if (!output.AnyTranslation())
            yield break;

        var lyrics = output.HitObjects.OfType<Lyric>().ToList();
        var availableTranslations = output.AvailableTranslationLanguages();

        foreach (var translation in availableTranslations)
        {
            foreach (var lyric in lyrics)
            {
                string translationString = lyric.Translations.TryGetValue(translation, out string? value) ? value : string.Empty;
                yield return $"@tr[{translation.Name}]={translationString}";
            }
        }
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/IHasPrimaryKey.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public interface IHasPrimaryKey
{
    ElementId ID { get; }
}

public static class PrimaryKeyObjectExtension
{
    public static TObject ChangeId<TObject>(this TObject obj, ElementId id)
        where TObject : IHasPrimaryKey
    {
        // get id from the obj and override the id.
        var propertyInfo = obj.GetType().GetProperty(nameof(IHasPrimaryKey.ID));
        if (propertyInfo == null)
            throw new InvalidOperationException();

        propertyInfo.SetValue(obj, id);

        return obj;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/IKaraokeBeatmapResourcesProvider.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public interface IKaraokeBeatmapResourcesProvider
{
    Texture? GetSingerAvatar(ISinger singer);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmap.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public class KaraokeBeatmap : Beatmap<KaraokeHitObject>
{
    public IList<CultureInfo> AvailableTranslationLanguages { get; set; } = new List<CultureInfo>();

    public SingerInfo SingerInfo { get; set; } = new();

    public PageInfo PageInfo { get; set; } = new();

    public NoteInfo NoteInfo { get; set; } = new();

    public bool Scorable { get; set; }

    public override IEnumerable<BeatmapStatistic> GetStatistics()
    {
        int singers = SingerInfo.GetAllSingers().Count();
        int lyrics = HitObjects.Count(s => s is Lyric);

        var defaultStatistic = new List<BeatmapStatistic>
        {
            new()
            {
                Name = "Singer",
                Content = singers.ToString(),
                CreateIcon = () => new SpriteIcon { Icon = FontAwesome.Solid.User },
            },
            new()
            {
                Name = "Lyric",
                Content = lyrics.ToString(),
                CreateIcon = () => new SpriteIcon { Icon = FontAwesome.Solid.AlignLeft },
            },
        };

        if (Scorable)
        {
            int notes = HitObjects.Count(s => s is Note { Display: true });
            defaultStatistic.Add(new BeatmapStatistic
            {
                Name = "Note",
                Content = notes.ToString(),
                CreateIcon = () => new SpriteIcon { Icon = FontAwesome.Solid.Music },
            });
        }
        else
        {
            defaultStatistic.Add(new BeatmapStatistic
            {
                Name = "This beatmap is not scorable.",
                Content = "This beatmap is not scorable.",
                CreateIcon = () => new SpriteIcon { Icon = FontAwesome.Solid.Times },
            });
        }

        return defaultStatistic.ToArray();
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapConverter.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public class KaraokeBeatmapConverter : BeatmapConverter<KaraokeHitObject>
{
    public KaraokeBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
        : base(beatmap, ruleset)
    {
    }

    public override bool CanConvert() => Beatmap.HitObjects.All(h => h is KaraokeHitObject);

    protected override Beatmap<KaraokeHitObject> ConvertBeatmap(IBeatmap original, CancellationToken cancellationToken)
    {
        var beatmap = base.ConvertBeatmap(original, cancellationToken);

        // Apply property created from legacy decoder
        var propertyDictionary = beatmap.HitObjects.OfType<LegacyProperties>().FirstOrDefault();

        if (propertyDictionary == null)
            return beatmap;

        if (beatmap is not KaraokeBeatmap karaokeBeatmap)
            throw new InvalidCastException(nameof(beatmap));

        karaokeBeatmap.AvailableTranslationLanguages = propertyDictionary.AvailableTranslationLanguages;
        beatmap.HitObjects.Remove(propertyDictionary);

        return beatmap;
    }

    protected override IEnumerable<KaraokeHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
        => throw new NotImplementedException();

    protected override Beatmap<KaraokeHitObject> CreateBeatmap() => new KaraokeBeatmap();
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapExtension.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using osu.Game.Beatmaps;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public static class KaraokeBeatmapExtension
{
    public static bool IsScorable(this IBeatmap beatmap)
    {
        // we should throw invalidate exception here but it will cause test case failed.
        // because beatmap in the working beatmap in test case not always be karaoke beatmap class.
        return beatmap is KaraokeBeatmap karaokeBeatmap && karaokeBeatmap.Scorable;
    }

    public static IList<CultureInfo> AvailableTranslationLanguages(this IBeatmap beatmap) => (beatmap as KaraokeBeatmap)?.AvailableTranslationLanguages ?? new List<CultureInfo>();

    public static bool AnyTranslation(this IBeatmap beatmap) => beatmap.AvailableTranslationLanguages().Any();

    public static float PitchToScale(this IBeatmap beatmap, float pitch)
    {
        return pitch / 20 - 7;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Objects.Types;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public class KaraokeBeatmapProcessor : BeatmapProcessor
{
    public KaraokeBeatmapProcessor(IBeatmap beatmap)
        : base(beatmap)
    {
    }

    public override void PreProcess()
    {
        var karaokeBeatmap = getKaraokeBeatmap(Beatmap);

        base.PreProcess();
        applyInvalidProperty(karaokeBeatmap);
        return;

        static KaraokeBeatmap getKaraokeBeatmap(IBeatmap beatmap) =>
            beatmap switch
            {
                // goes to there while parsing the beatmap.
                KaraokeBeatmap karaokeBeatmap => karaokeBeatmap,
                // goes to there while editing the beatmap.
                EditorBeatmap editorBeatmap => getKaraokeBeatmap(editorBeatmap.PlayableBeatmap),
                _ => throw new InvalidCastException($"The beatmap is not a {nameof(KaraokeBeatmap)}"),
            };
    }

    private void applyInvalidProperty(KaraokeBeatmap beatmap)
    {
        // should convert to array here because validate the working property might change the start-time and the end time.
        // which will cause got the wrong item in the array.
        foreach (var hitObject in beatmap.HitObjects.OfType<IHasWorkingProperty>().ToArray())
        {
            hitObject.ValidateWorkingProperty(beatmap);
        }
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapResourcesProvider.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps;

public partial class KaraokeBeatmapResourcesProvider : Component, IKaraokeBeatmapResourcesProvider
{
    [Resolved]
    private BeatmapManager beatmapManager { get; set; } = null!;

    [Resolved]
    private IBindable<WorkingBeatmap> working { get; set; } = null!;

    public Texture? GetSingerAvatar(ISinger singer)
    {
        return null;
    }

    /*
    public Texture? GetSingerAvatar(ISinger singer)
    {
        var provider = getBeatmapResourceProvider();
        if (provider == null)
            return null;

        if (singer is not Singer s)
            return null;

        var beatmapSetInfo = working.Value.BeatmapSetInfo;
        if (beatmapSetInfo == null)
            return null;

        string? path = beatmapSetInfo.GetPathForFile($"assets/singers/{s.AvatarFile}");
        return provider.LargeTextureStore.Get(path);
    }

    private IBeatmapResourceProvider? getBeatmapResourceProvider()
    {
        // todo : use better way to get the resource provider.
        var prop = typeof(BeatmapManager).GetField("workingBeatmapCache", BindingFlags.Instance | BindingFlags.NonPublic);
        if (prop == null)
            throw new ArgumentNullException();

        return prop.GetValue(beatmapManager) as WorkingBeatmapCache;
    }
    */
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/NoteInfo.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class NoteInfo
{
    public int Columns { get; set; } = 9;

    public Tone MaxTone =>
        new()
        {
            Scale = Columns / 2,
        };

    public Tone MinTone => -MaxTone;
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Page.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Utils;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class Page : IDeepCloneable<Page>, IComparable<Page>
{
    [JsonIgnore]
    public readonly Bindable<double> TimeBindable = new();

    public double Time
    {
        get => TimeBindable.Value;
        set => TimeBindable.Value = value;
    }

    public Page DeepClone()
    {
        return new Page
        {
            Time = Time,
        };
    }

    public int CompareTo(Page? other) => Time.CompareTo(other?.Time);

    public override int GetHashCode() => Time.GetHashCode();
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/PageInfo.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Utils;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class PageInfo : IDeepCloneable<PageInfo>
{
    [JsonIgnore]
    public IBindable<int> PagesVersion => pagesVersion;

    private readonly Bindable<int> pagesVersion = new();

    public BindableList<Page> Pages = new();

    [JsonIgnore]
    public List<Page> SortedPages { get; private set; } = new();

    public PageInfo()
    {
        Pages.CollectionChanged += (_, args) =>
        {
            switch (args.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    Debug.Assert(args.NewItems != null);

                    foreach (var c in args.NewItems.Cast<Page>())
                        c.TimeBindable.ValueChanged += timeValueChanged;
                    break;

                case NotifyCollectionChangedAction.Reset:
                case NotifyCollectionChangedAction.Remove:
                    Debug.Assert(args.OldItems != null);

                    foreach (var c in args.OldItems.Cast<Page>())
                        c.TimeBindable.ValueChanged -= timeValueChanged;
                    break;
            }

            onPageChanged();

            void timeValueChanged(ValueChangedEvent<double> e) => onPageChanged();
        };

        void onPageChanged()
        {
            SortedPages = Pages.OrderBy(x => x.Time).ToList();
            pagesVersion.Value++;
        }
    }

    public Page? GetPageAt(double time)
    {
        if (SortedPages.Count < 2)
            return null;

        var page = SortedPages.LastOrDefault(x => x.Time <= time);

        // should not be able to get the page if time exceed the last page.
        var lastPage = SortedPages.LastOrDefault();
        if (page == lastPage && page?.Time < time)
            return null;

        return page;
    }

    public int? GetPageIndexAt(double time)
    {
        var page = GetPageAt(time);
        if (page == null)
            return null;

        return SortedPages.IndexOf(page);
    }

    public int? GetPageOrder(Page page)
    {
        int index = SortedPages.IndexOf(page);
        return index == -1 ? null : index + 1;
    }

    public PageInfo DeepClone()
    {
        var controlPointInfo = Activator.CreateInstance<PageInfo>();

        return controlPointInfo;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Singer.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class Singer : ISinger
{
    [JsonProperty]
    public ElementId ID { get; private set; } = ElementId.NewElementId();

    [JsonIgnore]
    public readonly Bindable<int> OrderBindable = new();

    /// <summary>
    /// Order
    /// </summary>
    public int Order
    {
        get => OrderBindable.Value;
        set => OrderBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> AvatarFileBindable = new();

    public string AvatarFile
    {
        get => AvatarFileBindable.Value;
        set => AvatarFileBindable.Value = value;
    }

    [JsonIgnore]
    public Bindable<float> HueBindable = new BindableFloat
    {
        MinValue = 0,
        MaxValue = 1,
    };

    public float Hue
    {
        get => HueBindable.Value;
        set => HueBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> NameBindable = new();

    public string Name
    {
        get => NameBindable.Value;
        set => NameBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> RomanisationBindable = new();

    public string Romanisation
    {
        get => RomanisationBindable.Value;
        set => RomanisationBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> EnglishNameBindable = new();

    public string EnglishName
    {
        get => EnglishNameBindable.Value;
        set => EnglishNameBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> DescriptionBindable = new();

    public string Description
    {
        get => DescriptionBindable.Value;
        set => DescriptionBindable.Value = value;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerInfo.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class SingerInfo
{
    public bool SupportSingerState { get; set; }

    // todo: should make the property as readonly.
    public BindableList<Singer> Singers { get; set; } = new();

    // todo: should make the property as readonly.
    public BindableList<SingerState> SingerState { get; set; } = new();

    public IEnumerable<Singer> GetAllSingers() =>
        Singers.OrderBy(x => x.Order);

    public IEnumerable<SingerState> GetAllAvailableSingerStates(Singer singer) =>
        SingerState.Where(x => x.MainSingerId == singer.ID).OrderBy(x => x.Order);

    public IDictionary<Singer, SingerState[]> GetSingerByIds(ElementId[] singerIds)
    {
        var matchedMainSingers = GetAllSingers().Where(x => singerIds.Contains(x.ID));
        return matchedMainSingers.ToDictionary(k => k, v =>
        {
            var matchedSingerStates = GetAllAvailableSingerStates(v);

            return matchedSingerStates.Where(x => singerIds.Contains(x.ID)).ToArray();
        });
    }

    public IDictionary<Singer, SingerState[]> GetSingerMap()
    {
        var matchedMainSingers = GetAllSingers();
        return matchedMainSingers.ToDictionary(k => k, v => GetAllAvailableSingerStates(v).ToArray());
    }

    public Singer AddSinger(Action<Singer>? action = null)
    {
        var singer = new Singer();
        action?.Invoke(singer);

        Singers.Add(singer);

        return singer;
    }

    public SingerState AddSingerState(Singer singer, Action<SingerState>? action = null)
    {
        if (!Singers.Contains(singer))
            throw new InvalidOperationException("Main singer must in the singer info.");

        var mainSingerId = singer.ID;
        var singerState = new SingerState(mainSingerId);
        action?.Invoke(singerState);

        SingerState.Add(singerState);

        return singerState;
    }

    public bool RemoveSinger(ISinger singer)
    {
        switch (singer)
        {
            case Singer mainSinger:
            {
                var singerStates = GetAllAvailableSingerStates(mainSinger);

                foreach (var singerState in singerStates)
                {
                    RemoveSinger(singerState);
                }

                return Singers.Remove(mainSinger);
            }

            case SingerState singerState:
                return SingerState.Remove(singerState);

            default:
                throw new InvalidCastException();
        }
    }

    public bool HasSinger(ISinger singer)
    {
        return singer switch
        {
            Singer mainSinger => Singers.Contains(mainSinger),
            SingerState singerState => SingerState.Contains(singerState),
            _ => throw new InvalidCastException(),
        };
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerState.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using Newtonsoft.Json;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

public class SingerState : ISinger
{
    public SingerState()
    {
    }

    public SingerState(ElementId mainSingerId)
    {
        MainSingerId = mainSingerId;
    }

    [JsonProperty]
    public ElementId ID { get; private set; } = ElementId.NewElementId();

    [JsonProperty]
    public ElementId MainSingerId { get; private set; }

    [JsonIgnore]
    public readonly Bindable<int> OrderBindable = new();

    /// <summary>
    /// Order
    /// </summary>
    public int Order
    {
        get => OrderBindable.Value;
        set => OrderBindable.Value = value;
    }

    [JsonIgnore]
    public Bindable<float> HueBindable = new BindableFloat
    {
        MinValue = 0,
        MaxValue = 1,
    };

    public float Hue
    {
        get => HueBindable.Value;
        set => HueBindable.Value = value;
    }

    [JsonIgnore]
    public readonly Bindable<string> DescriptionBindable = new();

    public string Description
    {
        get => DescriptionBindable.Value;
        set => DescriptionBindable.Value = value;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Types/ISinger.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Karaoke.Objects.Types;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

public interface ISinger : IHasOrder, IHasPrimaryKey
{
    float Hue { get; }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Utils/SingerUtils.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;
using osuTK.Graphics;

namespace osu.Game.Rulesets.Karaoke.Beatmaps.Utils;

public static class SingerUtils
{
    public static int GetShiftingStyleIndex(IEnumerable<int> singerIds)
        => singerIds.Sum(x => (int)Math.Pow(2, x - 1));

    public static int[] GetSingersIndex(int styleIndex)
    {
        if (styleIndex < 1)
            return Array.Empty<int>();

        string binary = Convert.ToString(styleIndex, 2);

        return binary.Select((v, i) => new { value = v, singer = binary.Length - i })
                     .Where(x => x.value == '1').Select(x => x.singer).OrderBy(x => x).ToArray();
    }

    public static Color4 GetContentColour(ISinger singer)
        => Colour4.FromHSL(singer.Hue, 0.4f, 0.6f);

    public static Color4 GetBackgroundColour(ISinger singer)
        => Colour4.FromHSL(singer.Hue, 0.1f, 0.4f);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Bindables/BindableCultureInfo.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Globalization;
using osu.Framework.Bindables;
using osu.Framework.Logging;
using osu.Game.Rulesets.Karaoke.Utils;

namespace osu.Game.Rulesets.Karaoke.Bindables;

public class BindableCultureInfo : Bindable<CultureInfo?>
{
    public BindableCultureInfo(CultureInfo? value = default)
        : base(value)
    {
    }

    public override void Parse(object? input, IFormatProvider provider)
    {
        if (input == null)
        {
            Value = null;
            return;
        }

        try
        {
            switch (input)
            {
                case string str:
                    Value = CultureInfoUtils.CreateLoadCultureInfoByCode(str);
                    break;

                case int lcid:
                    Value = CultureInfoUtils.CreateLoadCultureInfoById(lcid);
                    break;

                case CultureInfo cultureInfo:
                    Value = cultureInfo;
                    break;

                default:
                    base.Parse(input, provider);
                    break;
            }
        }
        catch (Exception ex)
        {
            Value = null;

            // It might have issue that the culture info is not available in the system.
            // Log it instead of throw exception.
            Logger.Error(ex, $"Failed to parse {input} into {typeof(CultureInfo)}");
        }
    }

    protected override Bindable<CultureInfo?> CreateInstance() => new BindableCultureInfo();

    public override string ToString(string? format, IFormatProvider? formatProvider)
        => Value != null ? CultureInfoUtils.GetSaveCultureInfoCode(Value) : string.Empty;
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Bindables/BindableFontUsage.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Linq;
using System.Text.RegularExpressions;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Karaoke.Extensions;

namespace osu.Game.Rulesets.Karaoke.Bindables;

public class BindableFontUsage : RangeConstrainedBindable<FontUsage>
{
    private const int default_min_font_size = 1;
    private const int default_max_font_size = 72;

    protected override FontUsage DefaultMinValue => Default.With(size: default_min_font_size);
    protected override FontUsage DefaultMaxValue => Default.With(size: default_max_font_size);

    public BindableFontUsage(FontUsage value = default)
        : base(value)
    {
    }

    public float MinFontSize
    {
        get => MinValue.Size;
        set => MinValue = MinValue.With(size: value);
    }

    public float MaxFontSize
    {
        get => MaxValue.Size;
        set => MaxValue = MaxValue.With(size: value);
    }

    // IDK why not being called in here while saving.
    public override string ToString(string? format, IFormatProvider? formatProvider)
        => $"family={Value.Family} weight={Value.Weight} size={Value.Size} italics={Value.Italics} fixedWidth={Value.FixedWidth}";

    public override void Parse(object? input, IFormatProvider provider)
    {
        if (input is not string str || string.IsNullOrEmpty(str))
        {
            Value = default;
            return;
        }

        // because FontUsage.ToString() will have "," symbol.
        str = str.Replace(",", string.Empty);
        var regex = new Regex(@"\b(?<key>font|family|weight|size|italics|fixedWidth)(?<op>[=]+)(?<value>("".*"")|(\S*))", RegexOptions.Compiled | RegexOptions.IgnoreCase);
        var dictionary = regex.Matches(str).ToDictionary(k => k.GetGroupValue<string>("key"), v => v.GetGroupValue<string>("value"));

        if (dictionary.TryGetValue("Font", out string? font))
        {
            string? family = font.Contains('-') ? font.Split('-').FirstOrDefault() : font;
            string? weight = font.Contains('-') ? font.Split('-').LastOrDefault() : string.Empty;
            float size = float.Parse(dictionary["Size"]);
            bool italics = dictionary["Italics"].ToLower() == "true";
            bool fixedWidth = dictionary["FixedWidth"].ToLower() == "true";
            Value = new FontUsage(family, size, weight, italics, fixedWidth);
        }
        else
        {
            string family = dictionary["family"];
            string weight = dictionary["weight"];
            float size = float.Parse(dictionary["size"]);
            bool italics = dictionary["italics"].ToLower() == "true";
            bool fixedWidth = dictionary["fixedWidth"].ToLower() == "true";
            Value = new FontUsage(family, size, weight, italics, fixedWidth);
        }
    }

    protected override Bindable<FontUsage> CreateInstance() => new BindableFontUsage();

    protected sealed override FontUsage ClampValue(FontUsage value, FontUsage minValue, FontUsage maxValue)
    {
        return value.With(size: Math.Clamp(value.Size, minValue.Size, maxValue.Size));
    }

    protected sealed override bool IsValidRange(FontUsage min, FontUsage max)
        => min.Size <= max.Size;
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetConfigManager.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Bindables;
using osu.Framework.Configuration.Tracking;
using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Rulesets.Configuration;
using osu.Game.Rulesets.Karaoke.Bindables;
using osu.Game.Rulesets.Karaoke.UI;
using osu.Game.Rulesets.Karaoke.Utils;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeRulesetConfigManager : RulesetConfigManager<KaraokeRulesetSetting>
{
    public KaraokeRulesetConfigManager(SettingsStore? settings, RulesetInfo ruleset, int? variant = null)
        : base(settings, ruleset, variant)
    {
    }

    protected override void InitialiseDefaults()
    {
        base.InitialiseDefaults();

        // Visual
        SetDefault(KaraokeRulesetSetting.ScrollTime, 5000.0, 1000.0, 10000.0, 100.0);
        SetDefault(KaraokeRulesetSetting.ScrollDirection, KaraokeScrollingDirection.Left);
        SetDefault(KaraokeRulesetSetting.DisplayNoteRubyText, false);
        SetDefault(KaraokeRulesetSetting.ShowCursor, true);
        SetDefault(KaraokeRulesetSetting.NoteAlpha, 1, 0.2, 1, 0.01);
        SetDefault(KaraokeRulesetSetting.LyricAlpha, 1, 0.2, 1, 0.01);

        // Pitch
        SetDefault(KaraokeRulesetSetting.OverridePitchAtGameplay, false);
        SetDefault(KaraokeRulesetSetting.Pitch, 0, -10, 10);
        SetDefault(KaraokeRulesetSetting.OverrideVocalPitchAtGameplay, false);
        SetDefault(KaraokeRulesetSetting.VocalPitch, 0, -10, 10);
        SetDefault(KaraokeRulesetSetting.OverrideScoringPitchAtGameplay, false);
        SetDefault(KaraokeRulesetSetting.ScoringPitch, 0, -10, 10);

        // Playback
        SetDefault(KaraokeRulesetSetting.OverridePlaybackSpeedAtGameplay, false);
        SetDefault(KaraokeRulesetSetting.PlaybackSpeed, 0, -10, 10);

        // Device
        SetDefault(KaraokeRulesetSetting.MicrophoneDevice, string.Empty);

        // Font
        SetDefault(KaraokeRulesetSetting.MainFont, new FontUsage("Torus", 48, "Bold"), 48f, 48f);
        SetDefault(KaraokeRulesetSetting.RubyFont, new FontUsage("Torus", 20, "Bold"), 8f, 48f);
        SetDefault(KaraokeRulesetSetting.RubyMargin, 5, 0, 20);
        SetDefault(KaraokeRulesetSetting.RomanisationFont, new FontUsage("Torus", 20, "Bold"), 8f, 48f);
        SetDefault(KaraokeRulesetSetting.RomanisationMargin, 0, 0, 20);
        SetDefault(KaraokeRulesetSetting.ForceUseDefaultFont, false);
        SetDefault(KaraokeRulesetSetting.TranslationFont, new FontUsage("Torus", 18, "Bold"), 10f, 48f);
        SetDefault(KaraokeRulesetSetting.ForceUseDefaultTranslationFont, false);
        SetDefault(KaraokeRulesetSetting.NoteFont, new FontUsage("Torus", 12, "Bold"), 10f, 32f);
        SetDefault(KaraokeRulesetSetting.ForceUseDefaultNoteFont, false);
    }

    protected override void AddBindable<TBindable>(KaraokeRulesetSetting lookup, Bindable<TBindable> bindable)
    {
        switch (lookup)
        {
            case KaraokeRulesetSetting.MainFont:
            case KaraokeRulesetSetting.RubyFont:
            case KaraokeRulesetSetting.RomanisationFont:
            case KaraokeRulesetSetting.TranslationFont:
            case KaraokeRulesetSetting.NoteFont:
                base.AddBindable(lookup, new BindableFontUsage(TypeUtils.ChangeType<FontUsage>(bindable.Value)));
                break;

            default:
                base.AddBindable(lookup, bindable);
                break;
        }
    }

    protected BindableFontUsage SetDefault(KaraokeRulesetSetting setting, FontUsage fontUsage, float? minFontSize = null, float? maxFontSize = null)
    {
        base.SetDefault(setting, fontUsage);

        // Should not use base.setDefault's value because it will return Bindable<FontUsage>, not BindableFontUsage
        var bindable = GetOriginalBindable<FontUsage>(setting);
        if (bindable is not BindableFontUsage bindableFontUsage)
            throw new InvalidCastException(nameof(bindable));

        // Assign size restriction in here.
        if (minFontSize.HasValue) bindableFontUsage.MinFontSize = minFontSize.Value;
        if (maxFontSize.HasValue) bindableFontUsage.MaxFontSize = maxFontSize.Value;

        return bindableFontUsage;
    }

    public override TrackedSettings CreateTrackedSettings() => new()
    {
        new TrackedSetting<double>(KaraokeRulesetSetting.ScrollTime, v => new SettingDescription(v, "Scroll Time", $"{v}ms")),
        new TrackedSetting<bool>(KaraokeRulesetSetting.DisplayNoteRubyText, b => new SettingDescription(b, "Toggle display", b ? "Show" : "Hide")),
        new TrackedSetting<bool>(KaraokeRulesetSetting.ShowCursor, b => new SettingDescription(b, "Cursor display", b ? "Show" : "Hide")),
        new TrackedSetting<string>(KaraokeRulesetSetting.MicrophoneDevice, d => new SettingDescription(d, "Change to the new microphone device", d)),
    };
}

public enum KaraokeRulesetSetting
{
    // Visual
    ScrollTime,
    ScrollDirection,
    DisplayNoteRubyText,
    ShowCursor,
    NoteAlpha,
    LyricAlpha,

    // Pitch
    OverridePitchAtGameplay,
    Pitch,
    OverrideVocalPitchAtGameplay,
    VocalPitch,
    OverrideScoringPitchAtGameplay,
    ScoringPitch,

    // Playback
    OverridePlaybackSpeedAtGameplay,
    PlaybackSpeed,

    // Device
    MicrophoneDevice,

    // Font
    MainFont,
    RubyFont,
    RubyMargin,
    RomanisationFont,
    RomanisationMargin,
    ForceUseDefaultFont,
    TranslationFont,
    ForceUseDefaultTranslationFont,
    NoteFont,
    ForceUseDefaultNoteFont,
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditCheckerConfigManager.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Configuration;
using osu.Game.Rulesets.Karaoke.Objects.Utils;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeRulesetEditCheckerConfigManager : InMemoryConfigManager<KaraokeRulesetEditCheckerSetting>
{
    protected override void InitialiseDefaults()
    {
        base.InitialiseDefaults();

        // Lyric
        SetDefault(KaraokeRulesetEditCheckerSetting.LyricRubyPositionSorting, RubyTagsUtils.Sorting.Asc);
        SetDefault(KaraokeRulesetEditCheckerSetting.LyricTimeTagTimeSelfCheck, SelfCheck.BasedOnStart);
        SetDefault(KaraokeRulesetEditCheckerSetting.LyricTimeTagTimeGroupCheck, GroupCheck.Asc);
    }
}

public enum KaraokeRulesetEditCheckerSetting
{
    LyricRubyPositionSorting,
    LyricTimeTagTimeSelfCheck,
    LyricTimeTagTimeGroupCheck,
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditConfigManager.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Configuration;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeRulesetEditConfigManager : InMemoryConfigManager<KaraokeRulesetEditSetting>;

public enum KaraokeRulesetEditSetting;


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditGeneratorConfigManager.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Game.Rulesets.Karaoke.Edit.Generator;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps.Pages;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Language;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Notes;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.ReferenceLyric;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.Romanisation.Ja;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.RubyTags.Ja;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.TimeTags.Ja;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Lyrics.TimeTags.Zh;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Stages.Classic;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Stages.Preview;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeRulesetEditGeneratorConfigManager : InMemoryConfigManager<KaraokeRulesetEditGeneratorSetting>
{
    protected override void InitialiseDefaults()
    {
        base.InitialiseDefaults();

        // Beatmap page
        SetDefault<PageGeneratorConfig>();

        // Classic stage.
        SetDefault<ClassicLyricLayoutCategoryGeneratorConfig>();
        SetDefault<ClassicLyricTimingInfoGeneratorConfig>();
        SetDefault<ClassicStageInfoGeneratorConfig>();

        // Preview stage.
        SetDefault<PreviewStageInfoGeneratorConfig>();

        // Language detection
        SetDefault<ReferenceLyricDetectorConfig>();

        // Language detection
        SetDefault<LanguageDetectorConfig>();

        // Ruby generator
        SetDefault<JaRubyTagGeneratorConfig>();

        // Time tag generator
        SetDefault<JaTimeTagGeneratorConfig>();
        SetDefault<ZhTimeTagGeneratorConfig>();

        // Romanisation generator
        SetDefault<JaRomanisationGeneratorConfig>();

        // Note generator
        SetDefault<NoteGeneratorConfig>();
    }

    protected void SetDefault<T>() where T : GeneratorConfig, new()
    {
        var defaultValue = CreateDefaultConfig<T>();
        var setting = GetSettingByType<T>();

        SetDefault(setting, defaultValue);
    }

    protected static T CreateDefaultConfig<T>() where T : GeneratorConfig, new() => new();

    protected static KaraokeRulesetEditGeneratorSetting GetSettingByType<TValue>() =>
        typeof(TValue) switch
        {
            Type t when t == typeof(PageGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.BeatmapPageGeneratorConfig,
            Type t when t == typeof(ClassicLyricLayoutCategoryGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.ClassicLyricLayoutCategoryGeneratorConfig,
            Type t when t == typeof(ClassicLyricTimingInfoGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.ClassicLyricTimingInfoGeneratorConfig,
            Type t when t == typeof(ClassicStageInfoGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.ClassicStageInfoGeneratorConfig,
            Type t when t == typeof(PreviewStageInfoGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.PreviewStageInfoGeneratorConfig,
            Type t when t == typeof(ReferenceLyricDetectorConfig) => KaraokeRulesetEditGeneratorSetting.ReferenceLyricDetectorConfig,
            Type t when t == typeof(LanguageDetectorConfig) => KaraokeRulesetEditGeneratorSetting.LanguageDetectorConfig,
            Type t when t == typeof(JaRubyTagGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.JaRubyTagGeneratorConfig,
            Type t when t == typeof(JaTimeTagGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.JaTimeTagGeneratorConfig,
            Type t when t == typeof(ZhTimeTagGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.ZhTimeTagGeneratorConfig,
            Type t when t == typeof(JaRomanisationGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.JaRomanisationGeneratorConfig,
            Type t when t == typeof(NoteGeneratorConfig) => KaraokeRulesetEditGeneratorSetting.NoteGeneratorConfig,
            _ => throw new NotSupportedException(),
        };

    public TValue Get<TValue>() where TValue : GeneratorConfig, new()
    {
        var lookup = GetSettingByType<TValue>();
        return Get<TValue>(lookup);
    }

    public GeneratorConfig GetGeneratorConfig(KaraokeRulesetEditGeneratorSetting lookup)
    {
        if (!ConfigStore.TryGetValue(lookup, out IBindable? obj))
            throw new KeyNotFoundException();

        var prop = obj.GetType().GetProperty("Value");
        if (prop?.GetValue(obj) is not GeneratorConfig generatorConfig)
            throw new InvalidCastException();

        return generatorConfig;
    }
}

public enum KaraokeRulesetEditGeneratorSetting
{
    // Beatmap
    BeatmapPageGeneratorConfig,

    // Classic stage.
    ClassicLyricLayoutCategoryGeneratorConfig,
    ClassicLyricTimingInfoGeneratorConfig,
    ClassicStageInfoGeneratorConfig,

    // Preview stage.
    PreviewStageInfoGeneratorConfig,

    // Reference lyric detection.
    ReferenceLyricDetectorConfig,

    // Language detection
    LanguageDetectorConfig,

    // Ruby generator
    JaRubyTagGeneratorConfig,

    // Time tag generator
    JaTimeTagGeneratorConfig,
    ZhTimeTagGeneratorConfig,

    // Romanisation generator.
    JaRomanisationGeneratorConfig,

    // Note generator
    NoteGeneratorConfig,
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetLyricEditorConfigManager.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Bindables;
using osu.Game.Configuration;
using osu.Game.Rulesets.Karaoke.Objects.Types;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics;
using osu.Game.Rulesets.Karaoke.Screens.Edit.Beatmaps.Lyrics.CaretPosition.Algorithms;
using osu.Game.Rulesets.Karaoke.Utils;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeRulesetLyricEditorConfigManager : InMemoryConfigManager<KaraokeRulesetLyricEditorSetting>
{
    protected override void InitialiseDefaults()
    {
        base.InitialiseDefaults();

        // General
        SetDefault(KaraokeRulesetLyricEditorSetting.LyricEditorPreferLayout, LyricEditorLayout.List);
        SetDefault(KaraokeRulesetLyricEditorSetting.LyricEditorFontSize, FontUtils.DEFAULT_FONT_SIZE);
        SetDefault(KaraokeRulesetLyricEditorSetting.AutoFocusToEditLyric, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.AutoFocusToEditLyricSkipRows, 1, 0, 4);
        SetDefault(KaraokeRulesetLyricEditorSetting.ClickToLockLyricState, LockState.Partial);

        // Composer
        SetDefault(KaraokeRulesetLyricEditorSetting.ShowPropertyPanelInComposer, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.ShowInvalidInfoInComposer, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.FontSizeInComposer, FontUtils.DEFAULT_FONT_SIZE_IN_COMPOSER);

        // Recording
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingTimeTagMovingCaretMode, RecordingTimeTagCaretMoveMode.None);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingAutoMoveToNextTimeTag, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingChangeTimeWhileMovingTheCaret, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingTimeTagShowWaveform, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingTimeTagWaveformOpacity, 0.5f, 0, 1, 0.01f);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingTimeTagShowTick, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.RecordingTimeTagTickOpacity, 0.5f, 0, 1, 0.01f);

        // Adjust
        SetDefault(KaraokeRulesetLyricEditorSetting.AdjustTimeTagShowWaveform, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.AdjustTimeTagWaveformOpacity, 0.5f, 0, 1, 0.01f);
        SetDefault(KaraokeRulesetLyricEditorSetting.AdjustTimeTagShowTick, true);
        SetDefault(KaraokeRulesetLyricEditorSetting.AdjustTimeTagTickOpacity, 0.5f, 0, 1, 0.01f);
    }

    /// <summary>
    /// Binds a local bindable with a configuration-backed bindable.
    /// </summary>
    public void BindWith<TValue>(KaraokeRulesetLyricEditorSetting lookup, IBindable<TValue> bindable) => bindable.BindTo(GetOriginalBindable<TValue>(lookup));
}

public enum KaraokeRulesetLyricEditorSetting
{
    // General
    LyricEditorPreferLayout,
    LyricEditorFontSize,
    AutoFocusToEditLyric,
    AutoFocusToEditLyricSkipRows,
    ClickToLockLyricState,

    // Composer
    ShowPropertyPanelInComposer,
    ShowInvalidInfoInComposer,
    FontSizeInComposer,

    // Recording
    RecordingTimeTagMovingCaretMode,
    RecordingAutoMoveToNextTimeTag,
    RecordingChangeTimeWhileMovingTheCaret,
    RecordingTimeTagShowWaveform,
    RecordingTimeTagWaveformOpacity,
    RecordingTimeTagShowTick,
    RecordingTimeTagTickOpacity,

    // Adjust
    AdjustTimeTagShowWaveform,
    AdjustTimeTagWaveformOpacity,
    AdjustTimeTagShowTick,
    AdjustTimeTagTickOpacity,
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeSessionStatics.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.UI.Components;

namespace osu.Game.Rulesets.Karaoke.Configuration;

public class KaraokeSessionStatics : InMemoryConfigManager<KaraokeRulesetSession>
{
    private readonly KaraokeRulesetConfigManager rulesetConfigManager;

    public KaraokeSessionStatics(KaraokeRulesetConfigManager config, IBeatmap? beatmap)
    {
        rulesetConfigManager = config;

        // Pitch
        bool overridePitch = getValue<bool>(KaraokeRulesetSetting.OverridePitchAtGameplay);
        int pitchValue = getValue<int>(KaraokeRulesetSetting.Pitch);
        SetDefault(KaraokeRulesetSession.Pitch, overridePitch ? pitchValue : 0, -10, 10);

        bool overrideVocalPitch = getValue<bool>(KaraokeRulesetSetting.OverrideVocalPitchAtGameplay);
        int vocalPitchValue = getValue<int>(KaraokeRulesetSetting.VocalPitch);
        SetDefault(KaraokeRulesetSession.VocalPitch, overrideVocalPitch ? vocalPitchValue : 0, -10, 10);

        bool overrideScoringPitch = getValue<bool>(KaraokeRulesetSetting.OverrideScoringPitchAtGameplay);
        int scoringPitchValue = getValue<int>(KaraokeRulesetSetting.ScoringPitch);
        SetDefault(KaraokeRulesetSession.ScoringPitch, overrideScoringPitch ? scoringPitchValue : 0, -8, 8);

        // Playback
        bool overridePlaybackSpeed = getValue<bool>(KaraokeRulesetSetting.OverridePlaybackSpeedAtGameplay);
        int playbackSpeedValue = getValue<int>(KaraokeRulesetSetting.PlaybackSpeed);
        SetDefault(KaraokeRulesetSession.PlaybackSpeed, overridePlaybackSpeed ? playbackSpeedValue : 0, -10, 10);

        // Practice
        SetDefault(KaraokeRulesetSession.SingingLyrics, Array.Empty<Lyric>());

        // Scoring status
        SetDefault(KaraokeRulesetSession.ScoringStatus, ScoringStatusMode.NotInitialized);
    }

    private T getValue<T>(KaraokeRulesetSetting setting) => rulesetConfigManager.Get<T>(setting);
}

public enum KaraokeRulesetSession
{
    // Pitch
    Pitch,
    VocalPitch,
    ScoringPitch,

    // Playback
    PlaybackSpeed,

    // Practice
    SingingLyrics,

    // Scoring status
    ScoringStatus,
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyAttributes.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;

namespace osu.Game.Rulesets.Karaoke.Difficulty;

public class KaraokeDifficultyAttributes : DifficultyAttributes
{
    /// <summary>
    /// The hit window for a GREAT hit inclusive of rate-adjusting mods (DT/HT/etc).
    /// </summary>
    /// <remarks>
    /// Rate-adjusting mods do not affect the hit window at all in osu-stable.
    /// </remarks>
    [JsonProperty("great_hit_window")]
    public double GreatHitWindow { get; set; }

    /// <summary>
    /// The score multiplier applied via score-reducing mods.
    /// </summary>
    [JsonProperty("score_multiplier")]
    public double ScoreMultiplier { get; set; }

    public override IEnumerable<(int attributeId, object value)> ToDatabaseAttributes()
    {
        foreach (var v in base.ToDatabaseAttributes())
            yield return v;

        yield return (ATTRIB_ID_DIFFICULTY, StarRating);
    }

    public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
    {
        base.FromDatabaseAttributes(values, onlineInfo);

        StarRating = values[ATTRIB_ID_DIFFICULTY];
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyCalculator.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Extensions;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Difficulty.Preprocessing;
using osu.Game.Rulesets.Karaoke.Difficulty.Skills;
using osu.Game.Rulesets.Karaoke.Mods;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Mods;

namespace osu.Game.Rulesets.Karaoke.Difficulty;

public class KaraokeDifficultyCalculator : DifficultyCalculator
{
    private const double star_scaling_factor = 0.018;

    private readonly bool isForCurrentRuleset;
    private readonly double originalOverallDifficulty;

    public KaraokeDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
        : base(ruleset, beatmap)
    {
        isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.MatchesOnlineID(ruleset);
        originalOverallDifficulty = beatmap.BeatmapInfo.Difficulty.OverallDifficulty;
    }

    protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
    {
        if (beatmap.HitObjects.Count == 0)
            return new KaraokeDifficultyAttributes { Mods = mods };

        return new KaraokeDifficultyAttributes
        {
            StarRating = skills[0].DifficultyValue() * star_scaling_factor,
            Mods = mods,
            // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
            GreatHitWindow = (int)Math.Ceiling(getHitWindow300(mods) / clockRate),
            MaxCombo = beatmap.HitObjects.Sum(h => h is Note ? 2 : 1),
        };
    }

    protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
    {
        var sortedObjects = beatmap.HitObjects.OfType<Note>().ToArray();

        // todo : might have a sort.
        // LegacySortHelper<HitObject>.Sort(sortedObjects, Comparer<HitObject>.Create((a, b) => (int)Math.Round(a.StartTime) - (int)Math.Round(b.StartTime)));

        var objects = new List<DifficultyHitObject>();

        for (int i = 1; i < sortedObjects.Length; i++)
            objects.Add(new KaraokeDifficultyHitObject(sortedObjects[i], sortedObjects[i - 1], clockRate, objects, objects.Count));

        return objects;
    }

    // Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required.
    protected override IEnumerable<DifficultyHitObject> SortObjects(IEnumerable<DifficultyHitObject> input) => input;

    protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
    {
        new Strain(mods, ((KaraokeBeatmap)beatmap).NoteInfo),
    };

    protected override Mod[] DifficultyAdjustmentMods =>
        new Mod[]
        {
            new KaraokeModDisableNote(),
            new KaraokeModHiddenNote(),
        };

    private int getHitWindow300(Mod[] mods)
    {
        if (!isForCurrentRuleset)
            return applyModAdjustments(Math.Round(originalOverallDifficulty) > 4 ? 34 : 47, mods);

        double od = Math.Min(10.0, Math.Max(0, 10.0 - originalOverallDifficulty));
        return applyModAdjustments(34 + 3 * od, mods);

        static int applyModAdjustments(double value, Mod[] mods)
        {
            if (mods.Any(m => m is KaraokeModDisableNote))
                value /= 1.4;
            else if (mods.Any(m => m is KaraokeModHiddenNote))
                value *= 1.4;

            return (int)value;
        }
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceAttributes.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using Newtonsoft.Json;
using osu.Game.Rulesets.Difficulty;

namespace osu.Game.Rulesets.Karaoke.Difficulty;

public class KaraokePerformanceAttributes : PerformanceAttributes
{
    [JsonProperty("difficulty")]
    public double Difficulty { get; set; }

    [JsonProperty("accuracy")]
    public double Accuracy { get; set; }

    [JsonProperty("scaled_score")]
    public double ScaledScore { get; set; }

    public override IEnumerable<PerformanceDisplayAttribute> GetAttributesForDisplay()
    {
        foreach (var attribute in base.GetAttributesForDisplay())
            yield return attribute;

        yield return new PerformanceDisplayAttribute(nameof(Difficulty), "Difficulty", Difficulty);
        yield return new PerformanceDisplayAttribute(nameof(Accuracy), "Accuracy", Accuracy);
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceCalculator.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;

namespace osu.Game.Rulesets.Karaoke.Difficulty;

public class KaraokePerformanceCalculator : PerformanceCalculator
{
    // Score after being scaled by non-difficulty-increasing mods
    private double scaledScore;

    private int countPerfect;
    private int countGreat;
    private int countGood;
    private int countOk;
    private int countMeh;
    private int countMiss;

    public KaraokePerformanceCalculator()
        : base(new KaraokeRuleset())
    {
    }

    protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
    {
        var karaokeAttributes = (KaraokeDifficultyAttributes)attributes;

        scaledScore = score.TotalScore;
        countPerfect = score.Statistics.GetValueOrDefault(HitResult.Perfect);
        countGreat = score.Statistics.GetValueOrDefault(HitResult.Great);
        countGood = score.Statistics.GetValueOrDefault(HitResult.Good);
        countOk = score.Statistics.GetValueOrDefault(HitResult.Ok);
        countMeh = score.Statistics.GetValueOrDefault(HitResult.Meh);
        countMiss = score.Statistics.GetValueOrDefault(HitResult.Miss);

        if (karaokeAttributes.ScoreMultiplier > 0)
        {
            // Scale score up, so it's comparable to other keymods
            scaledScore *= 1.0 / karaokeAttributes.ScoreMultiplier;
        }

        // Arbitrary initial value for scaling pp in order to standardize distributions across game modes.
        // The specific number has no intrinsic meaning and can be adjusted as needed.
        double multiplier = 0.8;

        if (score.Mods.Any(m => m is ModNoFail))
            multiplier *= 0.9;
        if (score.Mods.Any(m => m is ModEasy))
            multiplier *= 0.5;

        double difficultyValue = computeDifficultyValue(karaokeAttributes);
        double accValue = computeAccuracyValue(difficultyValue, karaokeAttributes);
        double totalValue =
            Math.Pow(
                Math.Pow(difficultyValue, 1.1) +
                Math.Pow(accValue, 1.1), 1.0 / 1.1
            ) * multiplier;

        return new KaraokePerformanceAttributes
        {
            Difficulty = difficultyValue,
            Accuracy = accValue,
            ScaledScore = scaledScore,
            Total = totalValue,
        };
    }

    private double computeDifficultyValue(KaraokeDifficultyAttributes attributes)
    {
        double difficultyValue = Math.Pow(5 * Math.Max(1, attributes.StarRating / 0.2) - 4.0, 2.2) / 135.0;

        difficultyValue *= 1.0 + 0.1 * Math.Min(1.0, totalHits / 1500.0);

        switch (scaledScore)
        {
            case <= 500000:
                difficultyValue = 0;
                break;

            case <= 600000:
                difficultyValue *= (scaledScore - 500000) / 100000 * 0.3;
                break;

            case <= 700000:
                difficultyValue *= 0.3 + (scaledScore - 600000) / 100000 * 0.25;
                break;

            case <= 800000:
                difficultyValue *= 0.55 + (scaledScore - 700000) / 100000 * 0.20;
                break;

            case <= 900000:
                difficultyValue *= 0.75 + (scaledScore - 800000) / 100000 * 0.15;
                break;

            default:
                difficultyValue *= 0.90 + (scaledScore - 900000) / 100000 * 0.1;
                break;
        }

        return difficultyValue;
    }

    private double computeAccuracyValue(double difficultyValue, KaraokeDifficultyAttributes attributes)
    {
        if (attributes.GreatHitWindow <= 0)
            return 0;

        // Lots of arbitrary values from testing.
        // Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution
        double accuracyValue = Math.Max(0.0, 0.2 - (attributes.GreatHitWindow - 34) * 0.006667)
                               * difficultyValue
                               * Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1);

        return accuracyValue;
    }

    private double totalHits => countPerfect + countOk + countGreat + countGood + countMeh + countMiss;
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/Preprocessing/KaraokeDifficultyHitObject.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Rulesets.Karaoke.Difficulty.Preprocessing;

public class KaraokeDifficultyHitObject : DifficultyHitObject
{
    public new Note BaseObject => (Note)base.BaseObject;

    public KaraokeDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, List<DifficultyHitObject> objects, int index)
        : base(hitObject, lastObject, clockRate, objects, index)
    {
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Difficulty/Skills/Strain.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using osu.Framework.Utils;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Difficulty.Preprocessing;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Mods;

namespace osu.Game.Rulesets.Karaoke.Difficulty.Skills;

public class Strain : StrainDecaySkill
{
    private const double individual_decay_base = 0.125;
    private const double overall_decay_base = 0.30;

    protected override double SkillMultiplier => 1;
    protected override double StrainDecayBase => 1;

    private readonly double[] holdEndTimes;
    private readonly double[] individualStrains;

    private double individualStrain;
    private double overallStrain;

    public Strain(Mod[] mods, NoteInfo noteInfo)
        : base(mods)
    {
        int totalColumns = noteInfo.Columns;

        holdEndTimes = new double[totalColumns * 2 - 1];
        individualStrains = new double[totalColumns * 2 - 1];
        overallStrain = 1;
    }

    protected override double StrainValueOf(DifficultyHitObject current)
    {
        var maniaCurrent = (KaraokeDifficultyHitObject)current;
        double endTime = maniaCurrent.EndTime;
        int column = getColumnIndex(maniaCurrent.BaseObject.Tone);

        double holdFactor = 1.0; // Factor to all additional strains in case something else is held
        double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly

        // Fill up the holdEndTimes array
        for (int i = 0; i < holdEndTimes.Length; ++i)
        {
            // If there is at least one other overlapping end or note, then we get an addition, buuuuuut...
            if (Precision.DefinitelyBigger(holdEndTimes[i], maniaCurrent.StartTime, 1) && Precision.DefinitelyBigger(endTime, holdEndTimes[i], 1))
                holdAddition = 1.0;

            // ... this addition only is valid if there is _no_ other note with the same ending. Releasing multiple notes at the same time is just as easy as releasing 1
            if (Precision.AlmostEquals(endTime, holdEndTimes[i], 1))
                holdAddition = 0;

            // We give a slight bonus to everything if something is held meanwhile
            if (Precision.DefinitelyBigger(holdEndTimes[i], endTime, 1))
                holdFactor = 1.25;

            // Decay individual strains
            individualStrains[i] = applyDecay(individualStrains[i], current.DeltaTime, individual_decay_base);
        }

        holdEndTimes[column] = endTime;

        // Increase individual strain in own column
        individualStrains[column] += 2.0 * holdFactor;
        individualStrain = individualStrains[column];

        overallStrain = applyDecay(overallStrain, current.DeltaTime, overall_decay_base) + (1 + holdAddition) * holdFactor;

        return individualStrain + overallStrain - CurrentStrain;

        // todo : implementation.
        static int getColumnIndex(Tone tone) => 0;
    }

    protected override double CalculateInitialStrain(double offset, DifficultyHitObject current)
        => applyDecay(individualStrain, offset - current.Previous(0).StartTime, individual_decay_base)
           + applyDecay(overallStrain, offset - current.Previous(0).StartTime, overall_decay_base);

    private double applyDecay(double value, double deltaTime, double decayBase)
        => value * Math.Pow(decayBase, deltaTime / 1000);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/KaraokeSelectionBlueprint.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Edit.Blueprints;

public partial class KaraokeSelectionBlueprint<T> : HitObjectSelectionBlueprint<T>
    where T : KaraokeHitObject
{
    protected KaraokeSelectionBlueprint(T hitObject)
        : base(hitObject)
    {
        RelativeSizeAxes = Axes.None;
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Lyrics/LyricSelectionBlueprint.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Game.Rulesets.Karaoke.Objects;

namespace osu.Game.Rulesets.Karaoke.Edit.Blueprints.Lyrics;

public partial class LyricSelectionBlueprint : KaraokeSelectionBlueprint<Lyric>
{
    public LyricSelectionBlueprint(Lyric lyric)
        : base(lyric)
    {
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/Components/EditBodyPiece.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Karaoke.Skinning.Default;

namespace osu.Game.Rulesets.Karaoke.Edit.Blueprints.Notes.Components;

public partial class EditBodyPiece : Container
{
    [BackgroundDependencyLoader]
    private void load(OsuColour colours)
    {
        Masking = true;
        BorderColour = colours.Yellow;
        BorderThickness = 2;
        CornerRadius = DefaultBodyPiece.CORNER_RADIUS;
        Child = new Box
        {
            RelativeSizeAxes = Axes.Both,
            AlwaysPresent = true,
            Alpha = 0,
        };
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/NoteSelectionBlueprint.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets.Karaoke.Edit.Blueprints.Notes.Components;
using osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Notes;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.UI;
using osu.Game.Rulesets.Karaoke.UI.Position;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Edit.Blueprints.Notes;

public partial class NoteSelectionBlueprint : KaraokeSelectionBlueprint<Note>
{
    [Resolved]
    private INotesChangeHandler notesChangeHandler { get; set; } = null!;

    [Resolved]
    private INotePropertyChangeHandler notePropertyChangeHandler { get; set; } = null!;

    [Resolved]
    private Playfield playfield { get; set; } = null!;

    [Resolved]
    private IScrollingInfo scrollingInfo { get; set; } = null!;

    [Resolved]
    private INotePositionInfo notePositionInfo { get; set; } = null!;

    [Resolved]
    private EditorBeatmap beatmap { get; set; } = null!;

    protected ScrollingHitObjectContainer HitObjectContainer => ((KaraokePlayfield)playfield).NotePlayfield.HitObjectContainer;

    public NoteSelectionBlueprint(Note note)
        : base(note)
    {
        AddInternal(new EditBodyPiece
        {
            RelativeSizeAxes = Axes.Both,
        });
    }

    protected override void Update()
    {
        base.Update();

        var anchor = scrollingInfo.Direction.Value == ScrollingDirection.Left ? Anchor.CentreLeft : Anchor.CentreRight;
        Anchor = Origin = anchor;

        Position = Parent.ToLocalSpace(HitObjectContainer.ScreenSpacePositionAtTime(HitObject.StartTime)) - AnchorPosition;
        Y += notePositionInfo.Calculator.YPositionAt(HitObject.Tone);

        Width = HitObjectContainer.LengthAtTime(HitObject.StartTime, HitObject.EndTime);
        Height = notePositionInfo.Calculator.ColumnHeight;
    }

    public override MenuItem[] ContextMenuItems => new MenuItem[]
    {
        new OsuMenuItem(HitObject.Display ? "Hide" : "Show", HitObject.Display ? MenuItemType.Destructive : MenuItemType.Standard,
            () => notePropertyChangeHandler.ChangeDisplayState(!HitObject.Display)),
        new OsuMenuItem("Split", MenuItemType.Destructive, () => notesChangeHandler.Split()),
    };

    protected override bool OnClick(ClickEvent e)
    {
        // should only select current note before open the popover because note change handler will change property in all selected notes.
        beatmap.SelectedHitObjects.Clear();
        beatmap.SelectedHitObjects.Add(HitObject);

        return base.OnClick(e);
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapListPropertyChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Edit.Utils;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers;

// todo: not a good design because eventually karaoke beatmap will not have the the field with list type.
// it should be wrap into class (e.g. localizationInfo) with list of translation inside.
// so guess this class will be removed eventually.
public abstract partial class BeatmapListPropertyChangeHandler<TItem> : Component
{
    [Resolved]
    private EditorBeatmap beatmap { get; set; } = null!;

    private KaraokeBeatmap karaokeBeatmap => EditorBeatmapUtils.GetPlayableBeatmap(beatmap);

    protected IEnumerable<Lyric> Lyrics => karaokeBeatmap.HitObjects.OfType<Lyric>();

    // todo: should be interface.
    protected BindableList<TItem> Items = new();

    [BackgroundDependencyLoader]
    private void load()
    {
        Items.AddRange(GetItemsFromBeatmap(karaokeBeatmap));

        // todo: find a better way to handle only beatmap property changed.
        beatmap.TransactionEnded += syncItemsFromBeatmap;

        syncItemsFromBeatmap();

        void syncItemsFromBeatmap()
        {
            var items = GetItemsFromBeatmap(karaokeBeatmap);

            if (Items.SequenceEqual(items))
                return;

            Items.AddRange(items.Except(Items));
            Items.RemoveAll(x => !items.Contains(x));
        }
    }

    protected void PerformObjectChanged(TItem item, Action<TItem>? action)
    {
        // should call change from editor beatmap because there's only way to trigger transaction ended.
        beatmap.BeginChange();
        action?.Invoke(item);
        beatmap.EndChange();
    }

    protected abstract IList<TItem> GetItemsFromBeatmap(KaraokeBeatmap beatmap);

    public void Add(TItem item)
    {
        var items = GetItemsFromBeatmap(karaokeBeatmap);
        if (items.Contains(item))
            throw new InvalidOperationException(nameof(item));

        PerformObjectChanged(item, i =>
        {
            items.Add(i);
            OnItemAdded(i);
        });
    }

    public void Remove(TItem item)
    {
        var items = GetItemsFromBeatmap(karaokeBeatmap);
        if (!items.Contains(item))
            throw new InvalidOperationException($"{nameof(item)} is not in the list");

        PerformObjectChanged(item, i =>
        {
            items.Remove(i);
            OnItemRemoved(i);
        });
    }

    protected abstract void OnItemAdded(TItem item);

    protected abstract void OnItemRemoved(TItem item);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Caching;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Karaoke.Beatmaps;
using osu.Game.Rulesets.Karaoke.Edit.Utils;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Karaoke.Objects.Types;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers;

public partial class BeatmapPropertyChangeHandler : Component
{
    private readonly Cached changingCache = new();

    [Resolved]
    private EditorBeatmap beatmap { get; set; } = null!;

    protected KaraokeBeatmap KaraokeBeatmap => EditorBeatmapUtils.GetPlayableBeatmap(beatmap);

    protected IEnumerable<Lyric> Lyrics => KaraokeBeatmap.HitObjects.OfType<Lyric>();

    protected BeatmapPropertyChangeHandler()
    {
        changingCache.Validate();
    }

    protected void PerformBeatmapChanged(Action<KaraokeBeatmap> action)
    {
        try
        {
            beatmap.BeginChange();
            action(KaraokeBeatmap);
            beatmap.EndChange();
        }
        catch
        {
            // We should make sure that editor beatmap will end the change if still changing.
            // will goes to here if have exception in the change handler.
            if (beatmap.TransactionActive)
                beatmap.EndChange();

            throw;
        }
    }

    protected void PerformOnSelection<T>(Action<T> action) where T : HitObject
    {
        if (!changingCache.IsValid)
            throw new NotSupportedException("Cannot trigger the change while applying another change.");

        if (beatmap.SelectedHitObjects.Count == 0)
            throw new NotSupportedException($"Should contain at least one selected {nameof(T)}");

        changingCache.Invalidate();

        try
        {
            // should trigger the UpdateState() in the editor beatmap only if there's no active state.
            beatmap.PerformOnSelection(h =>
            {
                if (h is T tHitObject)
                    action(tHitObject);
            });
        }
        catch
        {
            // We should make sure that editor beatmap will end the change if still changing.
            // will goes to here if have exception in the change handler.
            if (beatmap.TransactionActive)
                beatmap.EndChange();

            throw;
        }
        finally
        {
            changingCache.Validate();
        }
    }

    // todo: before having better solution to handle the undo/redo with better performance, we should use this to method to force invalidate all hit-object's working property.
    protected void InvalidateAllHitObjectWorkingProperty<TWorkingProperty>(TWorkingProperty property)
        where TWorkingProperty : struct, Enum
    {
        foreach (var hitObject in KaraokeBeatmap.HitObjects.OfType<IHasWorkingProperty<TWorkingProperty>>())
        {
            hitObject.InvalidateWorkingProperty(property);
        }

        beatmap.UpdateAllHitObjects();
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapPagesChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Localisation;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Configuration;
using osu.Game.Rulesets.Karaoke.Edit.Generator.Beatmaps.Pages;
using osu.Game.Rulesets.Karaoke.Objects.Workings;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public partial class BeatmapPagesChangeHandler : BeatmapPropertyChangeHandler, IBeatmapPagesChangeHandler
{
    #region Auto-Generate

    [Resolved]
    private KaraokeRulesetEditGeneratorConfigManager generatorConfigManager { get; set; } = null!;

    public bool CanGenerate()
    {
        var config = getGeneratorConfig();
        var generator = new PageGenerator(config);
        return generator.CanGenerate(KaraokeBeatmap);
    }

    public LocalisableString? GetGeneratorNotSupportedMessage()
    {
        var config = getGeneratorConfig();
        var generator = new PageGenerator(config);
        return generator.GetInvalidMessage(KaraokeBeatmap);
    }

    public void AutoGenerate()
    {
        var config = getGeneratorConfig();
        var generator = new PageGenerator(config);
        var pages = generator.Generate(KaraokeBeatmap);

        performPageInfoChanged(pageInfo =>
        {
            if (config.ClearExistPages.Value)
                pageInfo.Pages.Clear();

            pageInfo.Pages.AddRange(pages);
        });
    }

    private PageGeneratorConfig getGeneratorConfig()
        => generatorConfigManager.Get<PageGeneratorConfig>();

    #endregion

    public void Add(Page page)
    {
        performPageInfoChanged(pageInfo =>
        {
            if (checkPageExist(pageInfo, page))
                throw new InvalidOperationException($"Should not add duplicated {nameof(page)} into the {nameof(pageInfo)}.");

            pageInfo.Pages.Add(page);
        });
    }

    public void Remove(Page page)
    {
        performPageInfoChanged(pageInfo =>
        {
            if (!checkPageExist(pageInfo, page))
                throw new InvalidOperationException($"{nameof(page)} does ont in the {nameof(pageInfo)}.");

            pageInfo.Pages.Remove(page);
        });
    }

    public void RemoveRange(IEnumerable<Page> pages)
    {
        performPageInfoChanged(pageInfo =>
        {
            foreach (var page in pages.ToArray())
            {
                if (!checkPageExist(pageInfo, page))
                    throw new InvalidOperationException($"{nameof(page)} does ont in the {nameof(pageInfo)}.");

                pageInfo.Pages.Remove(page);
            }
        });
    }

    public void ShiftingPageTime(IEnumerable<Page> pages, double offset)
    {
        performPageInfoChanged(pageInfo =>
        {
            foreach (var page in pages)
            {
                if (!checkPageExist(pageInfo, page))
                    throw new InvalidOperationException($"{nameof(page)} does ont in the {nameof(pageInfo)}.");

                page.Time += offset;
            }
        });
    }

    private static bool checkPageExist(PageInfo pageInfo, Page page)
    {
        return pageInfo.Pages.Contains(page);
    }

    private void performPageInfoChanged(Action<PageInfo> action)
    {
        PerformBeatmapChanged(beatmap =>
        {
            action(beatmap.PageInfo);

            InvalidateAllHitObjectWorkingProperty(LyricWorkingProperty.Page);
            InvalidateAllHitObjectWorkingProperty(NoteWorkingProperty.Page);
        });
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapSingersChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.IO;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;
using osu.Game.Rulesets.Karaoke.Objects.Utils;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public partial class BeatmapSingersChangeHandler : BeatmapPropertyChangeHandler, IBeatmapSingersChangeHandler
{
    [Resolved]
    private BeatmapManager? beatmapManager { get; set; }

    [Resolved]
    private IBindable<WorkingBeatmap>? working { get; set; }

    private SingerInfo singerInfo => KaraokeBeatmap.SingerInfo;

    public BindableList<Singer> Singers => singerInfo.Singers;

    public void ChangeOrder(ISinger singer, int newIndex)
    {
        performSingerChanged(singer, s =>
        {
            int oldOrder = s.Order;
            int newOrder = newIndex + 1; // order is start from 1
            OrderUtils.ChangeOrder(Singers.ToArray(), oldOrder, newOrder, (switchSinger, oldOrder, newOrder) =>
            {
                // todo : not really sure should call update?
            });
        });
    }

    public bool ChangeSingerAvatar(Singer singer, FileInfo fileInfo)
    {
        if (beatmapManager == null || working == null)
            return false;

        if (!fileInfo.Exists)
            throw new FileNotFoundException();

        // note: follow the same logic in the ResourcesSection.ChangeBackgroundImage
        var set = working.Value.BeatmapSetInfo;

        // todo: we might re-format the new file name, like give it a hash name for prevent duplicated file name with other singer.
        string newFileName = fileInfo.Name;

        using (var stream = fileInfo.OpenRead())
        {
            // in the future we probably want to check if this is being used elsewhere (other difficulties?)
            var oldFile = set.Files.FirstOrDefault(f => f.Filename == singer.AvatarFile);
            if (oldFile != null)
                beatmapManager.DeleteFile(set, oldFile);

            beatmapManager.AddFile(set, stream, $"assets/singers/{newFileName}");
        }

        performSingerChanged(singer, s =>
        {
            // Write-back the file name.
            s.AvatarFile = newFileName;
        });

        return true;
    }

    public Singer Add()
    {
        var newSinger = singerInfo.AddSinger(s =>
        {
            s.Order = getMaxSingerOrder() + 1;
            s.Name = "New singer";
        });
        return newSinger;

        int getMaxSingerOrder()
            => OrderUtils.GetMaxOrderNumber(singerInfo.GetAllSingers());
    }

    public void Remove(Singer singer)
    {
        singerInfo.RemoveSinger(singer);

        // Should re-sort the order
        OrderUtils.ShiftingOrder(singerInfo.GetAllSingers().Where(x => x.Order > singer.Order), -1);

        // should clear removed singer ids in singer editor.
        Lyrics.ForEach(x =>
        {
            x.SingerIds.Remove(singer.ID);
        });
    }

    private void performSingerInfoChanged(Action<SingerInfo> action)
    {
        PerformBeatmapChanged(beatmap =>
        {
            action(beatmap.SingerInfo);
        });
    }

    private void performSingerChanged<TSinger>(TSinger singer, Action<TSinger> action) where TSinger : ISinger
    {
        performSingerInfoChanged(singerInfo =>
        {
            if (!singerInfo.HasSinger(singer))
                throw new InvalidOperationException("Singer should be in the beatmap");

            action(singer);
        });
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapTranslationsChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Beatmaps;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public partial class BeatmapTranslationsChangeHandler : BeatmapListPropertyChangeHandler<CultureInfo>, IBeatmapTranslationsChangeHandler
{
    public IBindableList<CultureInfo> Languages => Items;

    protected override IList<CultureInfo> GetItemsFromBeatmap(KaraokeBeatmap beatmap)
        => beatmap.AvailableTranslationLanguages;

    protected override void OnItemAdded(CultureInfo item)
    {
        // there's no need to do anything.
    }

    protected override void OnItemRemoved(CultureInfo item)
    {
        // Delete from lyric also.
        foreach (var lyric in Lyrics.Where(lyric => lyric.Translations.ContainsKey(item)))
        {
            lyric.Translations.Remove(item);
        }
    }

    public bool IsLanguageContainsTranslation(CultureInfo cultureInfo)
        => Lyrics.Any(x => x.Translations.ContainsKey(cultureInfo));
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapPagesChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using osu.Framework.Localisation;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public interface IBeatmapPagesChangeHandler : IAutoGenerateChangeHandler
{
    LocalisableString? GetGeneratorNotSupportedMessage();

    void Add(Page page);

    void Remove(Page page);

    void RemoveRange(IEnumerable<Page> pages);

    void ShiftingPageTime(IEnumerable<Page> pages, double offset);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapSingersChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.IO;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas;
using osu.Game.Rulesets.Karaoke.Beatmaps.Metadatas.Types;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public interface IBeatmapSingersChangeHandler
{
    // todo: should use IBindableList eventually, but cannot do that because it's bind to selection item.
    BindableList<Singer> Singers { get; }

    void ChangeOrder(ISinger singer, int newIndex);

    bool ChangeSingerAvatar(Singer singer, FileInfo fileInfo);

    Singer Add();

    void Remove(Singer singer);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapTranslationsChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Globalization;
using osu.Framework.Bindables;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers.Beatmaps;

public interface IBeatmapTranslationsChangeHandler
{
    IBindableList<CultureInfo> Languages { get; }

    void Add(CultureInfo culture);

    void Remove(CultureInfo culture);

    bool IsLanguageContainsTranslation(CultureInfo cultureInfo);
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ChangeForbiddenException.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers;

public class ChangeForbiddenException : InvalidOperationException
{
    public ChangeForbiddenException(string message)
        : base(message)
    {
    }
}


================================================
FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs
================================================
// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Caching;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Karaoke.Edit.Utils;
using osu.Game.Rulesets.Karaoke.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit;

namespace osu.Game.Rulesets.Karaoke.Edit.ChangeHandlers;

public abstract partial class HitObjectChangeHandler<THitObject> : Component where THitObject : HitObject
{
    private readonly Cached changingCache = new();

    private bool triggerBeatmapSave = true;

    [Resolved]
    private EditorBeatmap beatmap { get; set; } = null!;

    protected IEnumerable<THitObject> HitObjects => beatmap.HitObjects.OfType<THitObject>();

    protected HitObjectChangeHandler()
    {
        changingCache.Validate();
    }

    protected void CheckExactlySelectedOneHitObject()
    {
        if (beatmap.SelectedHitObjects.OfType<THitObject>().Count() != 1)
            throw new InvalidOperationException($"Should be exactly one {nameof(THitObject)} being selected.");
    }

    // Can remove this method after as TransactionalCommitComponent injection for all rulesets(means customized ruleset is able to save/load beatmap).
    // we can use changeHandler.TransactionActive to check if there's any active transaction.
    // e.g. : changeHandler is TransactionalCommitComponent transactionalCommitComponent && !transactionalCommitComponent.TransactionActive
    protected void NotTriggerSaveStateOnThisChange()
    {
        triggerBeatmapSave = false;
    }

    protected virtual void PerformOnSelection(Action<THitObject> action)
        => PerformOnSelection<THitObject>(action);

    protected void PerformOnSelection<T>(Action<T> action) where T : HitObject
    {
        if (!changingCache.IsValid)
            throw new NotSupportedException("Cannot trigger the change while applying another change.");

        if (beatmap.SelectedHitObjects.Count == 0)
            throw new NotSupportedException($"Should contain at least one selected {nameof(THitObject)}");

        changingCache.Invalidate();

        try
        {
            // todo: follow-up the discussion in the https://github.com/karaoke-dev/karaoke/pull/1669 after support the change handler for customized ruleset.
            if (triggerBeatmapSave)
            {
                // should trigger the UpdateState() in the editor beatmap only if there's no active state.
                beatmap.PerformOnSelection(h =>
                {
                    if (h is T tHitObject)
                        action(tHitObject);
                });
            }
            else
            {
                // Just update the object property if already in the changing state.
                // e.g. dragging.
                beatmap.SelectedHitObjects.ForEach(h =>
                {
                    if (h is T tHitObject)
                        action(tHitObject);
                });
            }
        }
        catch
        {
            // We should make sure that editor beatmap will end the change if still changing.
            // will goes to here if have exception in the change handler.
            if (beatmap.TransactionActive)
                beatmap.EndChange();

            throw;
        }
        finally
        {
            changingCache.Validate();
            triggerBeatmapSave = true;
        }
    }

    protected void AddRange<T>(IEnumerable<T> hitObjects) where T : HitObject => hitObjects.ForEach(Add);

    protected virtual void Add<T>(T hitObject) where T : HitObject
    {
        bool containsInBeatmap = HitObjects.Any(x => x == hitObject);
        if (containsInBeatmap)
            throw new InvalidOperationException("Seems this hit object is already in the beatmap.");

        if (isCreateObjectLocked(hitObject))
            throw new AddOrRemoveForbiddenException();

        beatmap.Add(hitObject);
    }

    protected virtual void Insert<T>(int index, T hitObject) where T : HitObject
    {
        bool containsInBeatmap = HitObjects.Any(x => x == hitObject);
        if (containsInBeatmap)
            throw new InvalidOperationException("Seems this hit object is already in the beatmap.");

        if (isCreateObjectLocked(hitObject))
            throw new AddOrRemoveForbiddenException();

        beatmap.Insert(index, hitObject);
    }

    protected void RemoveRange<T>(IEnumerable<T> hitObjects) where T : HitObject => hitObjects.ForEach(Remove);

    protected void Remove<T>(T hitObject) where T : HitObject
    {
        if (isRemoveObjectLocked(hitObject))
            throw new AddOrRemoveForbiddenException();

        beatmap.Remove(hitObject);
    }

    private bool isCreateObjectLocked<T>(T hitObject)
    {
        return hitObject switch
        {
            Lyric => false,
            Note note => note.ReferenceLyric != null && HitObjectWritableUtils.IsCreateOrRemoveNoteLocked(note.ReferenceLyric),
            _ => throw new InvalidCastException(),
        };
    }

    private bool isRemoveObjectLocked<T>(T hitObject)
    {
        switch (hitObject)
        {
            case Lyric lyric:
                bool hasReferenceLyric = EditorBeatmapUtils.GetAllReferenceLyrics(beatmap, lyric).Any();
                return hasReferenceLyric || HitObjectWritableUtils.IsRemoveLyricLocked(lyric);

            case Note note:
                return note.ReferenceLyric != null && HitObjectWritableUtils.IsCreateOrRemoveNoteLocked(note.ReferenceLyric);

            default:
                throw new InvalidCastException();
        }
    }

    protected void TriggerHitObjectUpdate<T>(T hitObject) where T : HitObject
    {
        beatmap.Update(hitObject);
    }

    public class AddOrRemoveForbiddenException : Exception
    {
        public AddOrRemoveForbiddenException()
            : base("Should not add or remove the hit-object.")
        
Download .txt
gitextract_yy2emyho/

├── .config/
│   └── dotnet-tools.json
├── .editorconfig
├── .git-blame-ignore-revs
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── labeler.yml
│   └── workflows/
│       ├── ci.yml
│       ├── crowdin.yml
│       ├── dotnet-format.yml
│       ├── labeler.yml
│       └── release.yml
├── .gitignore
├── .globalconfig
├── CONTRIBUTING.md
├── CodeAnalysis/
│   ├── BannedSymbols.txt
│   └── osu.ruleset
├── Directory.Build.props
├── LICENSE
├── README.md
├── appveyor.yml
├── cake.config
├── osu.Game.Rulesets.Karaoke/
│   ├── Beatmaps/
│   │   ├── ElementId.cs
│   │   ├── Formats/
│   │   │   ├── KaraokeJsonBeatmapDecoder.cs
│   │   │   ├── KaraokeJsonBeatmapEncoder.cs
│   │   │   ├── KaraokeLegacyBeatmapDecoder.cs
│   │   │   └── KaraokeLegacyBeatmapEncoder.cs
│   │   ├── IHasPrimaryKey.cs
│   │   ├── IKaraokeBeatmapResourcesProvider.cs
│   │   ├── KaraokeBeatmap.cs
│   │   ├── KaraokeBeatmapConverter.cs
│   │   ├── KaraokeBeatmapExtension.cs
│   │   ├── KaraokeBeatmapProcessor.cs
│   │   ├── KaraokeBeatmapResourcesProvider.cs
│   │   ├── Metadatas/
│   │   │   ├── NoteInfo.cs
│   │   │   ├── Page.cs
│   │   │   ├── PageInfo.cs
│   │   │   ├── Singer.cs
│   │   │   ├── SingerInfo.cs
│   │   │   ├── SingerState.cs
│   │   │   └── Types/
│   │   │       └── ISinger.cs
│   │   └── Utils/
│   │       └── SingerUtils.cs
│   ├── Bindables/
│   │   ├── BindableCultureInfo.cs
│   │   └── BindableFontUsage.cs
│   ├── Configuration/
│   │   ├── KaraokeRulesetConfigManager.cs
│   │   ├── KaraokeRulesetEditCheckerConfigManager.cs
│   │   ├── KaraokeRulesetEditConfigManager.cs
│   │   ├── KaraokeRulesetEditGeneratorConfigManager.cs
│   │   ├── KaraokeRulesetLyricEditorConfigManager.cs
│   │   └── KaraokeSessionStatics.cs
│   ├── Difficulty/
│   │   ├── KaraokeDifficultyAttributes.cs
│   │   ├── KaraokeDifficultyCalculator.cs
│   │   ├── KaraokePerformanceAttributes.cs
│   │   ├── KaraokePerformanceCalculator.cs
│   │   ├── Preprocessing/
│   │   │   └── KaraokeDifficultyHitObject.cs
│   │   └── Skills/
│   │       └── Strain.cs
│   ├── Edit/
│   │   ├── Blueprints/
│   │   │   ├── KaraokeSelectionBlueprint.cs
│   │   │   ├── Lyrics/
│   │   │   │   └── LyricSelectionBlueprint.cs
│   │   │   └── Notes/
│   │   │       ├── Components/
│   │   │       │   └── EditBodyPiece.cs
│   │   │       └── NoteSelectionBlueprint.cs
│   │   ├── ChangeHandlers/
│   │   │   ├── BeatmapListPropertyChangeHandler.cs
│   │   │   ├── BeatmapPropertyChangeHandler.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPagesChangeHandler.cs
│   │   │   │   ├── BeatmapSingersChangeHandler.cs
│   │   │   │   ├── BeatmapTranslationsChangeHandler.cs
│   │   │   │   ├── IBeatmapPagesChangeHandler.cs
│   │   │   │   ├── IBeatmapSingersChangeHandler.cs
│   │   │   │   └── IBeatmapTranslationsChangeHandler.cs
│   │   │   ├── ChangeForbiddenException.cs
│   │   │   ├── HitObjectChangeHandler.cs
│   │   │   ├── HitObjectPropertyChangeHandler.cs
│   │   │   ├── HitObjectsChangeHandler.cs
│   │   │   ├── IAutoGenerateChangeHandler.cs
│   │   │   ├── IHitObjectPropertyChangeHandler.cs
│   │   │   ├── IImportBeatmapChangeHandler.cs
│   │   │   ├── ILockChangeHandler.cs
│   │   │   ├── ImportBeatmapChangeHandler.cs
│   │   │   ├── LockChangeHandler.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── ILyricLanguageChangeHandler.cs
│   │   │   │   ├── ILyricListPropertyChangeHandler.cs
│   │   │   │   ├── ILyricPropertyAutoGenerateChangeHandler.cs
│   │   │   │   ├── ILyricPropertyChangeHandler.cs
│   │   │   │   ├── ILyricReferenceChangeHandler.cs
│   │   │   │   ├── ILyricRubyTagsChangeHandler.cs
│   │   │   │   ├── ILyricSingerChangeHandler.cs
│   │   │   │   ├── ILyricTextChangeHandler.cs
│   │   │   │   ├── ILyricTimeTagsChangeHandler.cs
│   │   │   │   ├── ILyricTranslationChangeHandler.cs
│   │   │   │   ├── ILyricsChangeHandler.cs
│   │   │   │   ├── LyricLanguageChangeHandler.cs
│   │   │   │   ├── LyricPropertyAutoGenerateChangeHandler.cs
│   │   │   │   ├── LyricPropertyChangeHandler.cs
│   │   │   │   ├── LyricReferenceChangeHandler.cs
│   │   │   │   ├── LyricRubyTagsChangeHandler.cs
│   │   │   │   ├── LyricSingerChangeHandler.cs
│   │   │   │   ├── LyricTextChangeHandler.cs
│   │   │   │   ├── LyricTimeTagsChangeHandler.cs
│   │   │   │   ├── LyricTranslationChangeHandler.cs
│   │   │   │   └── LyricsChangeHandler.cs
│   │   │   ├── Notes/
│   │   │   │   ├── INotePropertyChangeHandler.cs
│   │   │   │   ├── INotesChangeHandler.cs
│   │   │   │   ├── NotePropertyChangeHandler.cs
│   │   │   │   └── NotesChangeHandler.cs
│   │   │   └── Stages/
│   │   │       ├── ClassicStageChangeHandler.cs
│   │   │       ├── IClassicStageChangeHandler.cs
│   │   │       ├── IStageElementCategoryChangeHandler.cs
│   │   │       ├── IStagesChangeHandler.cs
│   │   │       ├── StageElementCategoryChangeHandler.cs
│   │   │       ├── StagePropertyChangeHandler.cs
│   │   │       └── StagesChangeHandler.cs
│   │   ├── Checks/
│   │   │   ├── CheckBeatmapAvailableTranslations.cs
│   │   │   ├── CheckBeatmapNoteInfo.cs
│   │   │   ├── CheckBeatmapPageInfo.cs
│   │   │   ├── CheckBeatmapProperty.cs
│   │   │   ├── CheckClassicStageInfo.cs
│   │   │   ├── CheckHitObjectProperty.cs
│   │   │   ├── CheckHitObjectReferenceProperty.cs
│   │   │   ├── CheckLyricLanguage.cs
│   │   │   ├── CheckLyricReferenceLyric.cs
│   │   │   ├── CheckLyricRubyTag.cs
│   │   │   ├── CheckLyricSinger.cs
│   │   │   ├── CheckLyricText.cs
│   │   │   ├── CheckLyricTimeTag.cs
│   │   │   ├── CheckLyricTranslations.cs
│   │   │   ├── CheckNoteReferenceLyric.cs
│   │   │   ├── CheckNoteText.cs
│   │   │   ├── CheckNoteTime.cs
│   │   │   ├── CheckStageInfo.cs
│   │   │   └── Issues/
│   │   │       ├── BeatmapClassicLyricTimingPointIssue.cs
│   │   │       ├── BeatmapPageIssue.cs
│   │   │       ├── LyricIssue.cs
│   │   │       ├── LyricRubyTagIssue.cs
│   │   │       ├── LyricTimeTagIssue.cs
│   │   │       └── NoteIssue.cs
│   │   ├── Components/
│   │   │   ├── ContextMenu/
│   │   │   │   ├── LyricLockContextMenu.cs
│   │   │   │   └── SingerContextMenu.cs
│   │   │   ├── Cursor/
│   │   │   │   └── TimeTagTooltip.cs
│   │   │   ├── Menus/
│   │   │   │   ├── KaraokeEditorMenu.cs
│   │   │   │   └── KaraokeSkinEditorMenu.cs
│   │   │   └── Sprites/
│   │   │       ├── DrawableTextIndex.cs
│   │   │       └── DrawableTimeTag.cs
│   │   ├── Debugging/
│   │   │   └── DebugBeatmapManager.cs
│   │   ├── DrawableKaraokeEditorRuleset.cs
│   │   ├── EditorNotePlayfield.cs
│   │   ├── Export/
│   │   │   └── ExportLyricManager.cs
│   │   ├── Generator/
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPropertyDetector.cs
│   │   │   │   ├── BeatmapPropertyGenerator.cs
│   │   │   │   └── Pages/
│   │   │   │       ├── PageGenerator.cs
│   │   │   │       └── PageGeneratorConfig.cs
│   │   │   ├── ConfigCategoryAttribute.cs
│   │   │   ├── ConfigSourceAttribute.cs
│   │   │   ├── DetectorNotSupportedException.cs
│   │   │   ├── GeneratorConfig.cs
│   │   │   ├── GeneratorConfigExtension.cs
│   │   │   ├── GeneratorNotSupportedException.cs
│   │   │   ├── GeneratorSelector.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── Language/
│   │   │   │   │   ├── LanguageDetector.cs
│   │   │   │   │   └── LanguageDetectorConfig.cs
│   │   │   │   ├── LyricGeneratorSelector.cs
│   │   │   │   ├── LyricPropertyDetector.cs
│   │   │   │   ├── LyricPropertyGenerator.cs
│   │   │   │   ├── Notes/
│   │   │   │   │   ├── NoteGenerator.cs
│   │   │   │   │   └── NoteGeneratorConfig.cs
│   │   │   │   ├── ReferenceLyric/
│   │   │   │   │   ├── ReferenceLyricDetector.cs
│   │   │   │   │   └── ReferenceLyricDetectorConfig.cs
│   │   │   │   ├── Romanisation/
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   ├── JaRomanisationGenerator.cs
│   │   │   │   │   │   └── JaRomanisationGeneratorConfig.cs
│   │   │   │   │   ├── RomanisationGenerateResult.cs
│   │   │   │   │   ├── RomanisationGenerator.cs
│   │   │   │   │   ├── RomanisationGeneratorConfig.cs
│   │   │   │   │   └── RomanisationGeneratorSelector.cs
│   │   │   │   ├── RubyTags/
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   ├── JaRubyTagGenerator.cs
│   │   │   │   │   │   └── JaRubyTagGeneratorConfig.cs
│   │   │   │   │   ├── RubyTagGenerator.cs
│   │   │   │   │   ├── RubyTagGeneratorConfig.cs
│   │   │   │   │   └── RubyTagGeneratorSelector.cs
│   │   │   │   └── TimeTags/
│   │   │   │       ├── Ja/
│   │   │   │       │   ├── JaTimeTagGenerator.cs
│   │   │   │       │   └── JaTimeTagGeneratorConfig.cs
│   │   │   │       ├── TimeTagGenerator.cs
│   │   │   │       ├── TimeTagGeneratorConfig.cs
│   │   │   │       ├── TimeTagGeneratorSelector.cs
│   │   │   │       └── Zh/
│   │   │   │           ├── ZhTimeTagGenerator.cs
│   │   │   │           └── ZhTimeTagGeneratorConfig.cs
│   │   │   ├── PropertyDetector.cs
│   │   │   ├── PropertyGenerator.cs
│   │   │   └── Stages/
│   │   │       ├── Classic/
│   │   │       │   ├── ClassicLyricLayoutCategoryGenerator.cs
│   │   │       │   ├── ClassicLyricLayoutCategoryGeneratorConfig.cs
│   │   │       │   ├── ClassicLyricTimingInfoGenerator.cs
│   │   │       │   ├── ClassicLyricTimingInfoGeneratorConfig.cs
│   │   │       │   ├── ClassicStageInfoGenerator.cs
│   │   │       │   └── ClassicStageInfoGeneratorConfig.cs
│   │   │       ├── Preview/
│   │   │       │   ├── PreviewStageInfoGenerator.cs
│   │   │       │   └── PreviewStageInfoGeneratorConfig.cs
│   │   │       ├── StageInfoGenerator.cs
│   │   │       ├── StageInfoGeneratorConfig.cs
│   │   │       ├── StageInfoGeneratorSelector.cs
│   │   │       └── StageInfoPropertyGenerator.cs
│   │   ├── KaraokeBeatmapVerifier.cs
│   │   ├── KaraokeBlueprintContainer.cs
│   │   ├── KaraokeEditorPlayfield.cs
│   │   ├── KaraokeHitObjectComposer.cs
│   │   ├── KaraokeSelectionHandler.cs
│   │   ├── Setup/
│   │   │   ├── Components/
│   │   │   │   ├── FormLanguageList.cs
│   │   │   │   └── FormSingerList.cs
│   │   │   ├── KaraokeNoteSection.cs
│   │   │   ├── KaraokeSingerSection.cs
│   │   │   └── KaraokeTranslationSection.cs
│   │   └── Utils/
│   │       ├── EditorBeatmapUtils.cs
│   │       ├── HitObjectWritableUtils.cs
│   │       ├── LockStateUtils.cs
│   │       ├── ValueChangedEventUtils.cs
│   │       └── ZoomableScrollContainerUtils.cs
│   ├── Extensions/
│   │   ├── EnumerableExtensions.cs
│   │   ├── OsuGameExtensions.cs
│   │   ├── RegexExtensions.cs
│   │   ├── ScrollContainerExtensions.cs
│   │   ├── TrickyCompositeDrawableExtension.cs
│   │   └── TypeExtensions.cs
│   ├── Flags/
│   │   └── FlagState.cs
│   ├── Graphics/
│   │   ├── Containers/
│   │   │   ├── OrderRearrangeableListContainer.cs
│   │   │   └── RearrangeableTextFlowListContainer.cs
│   │   ├── Cursor/
│   │   │   ├── BackgroundToolTip.cs
│   │   │   ├── LyricToolTip.cs
│   │   │   └── SingerToolTip.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableCircleSingerAvatar.cs
│   │   │   ├── DrawableSingerAvatar.cs
│   │   │   └── SingerDisplay.cs
│   │   ├── KaraokeIcon.cs
│   │   ├── Shapes/
│   │   │   ├── CornerBackground.cs
│   │   │   └── RightTriangle.cs
│   │   ├── Sprites/
│   │   │   ├── DisplayLyricProcessor.cs
│   │   │   ├── DrawableKaraokeSpriteText.cs
│   │   │   ├── DrawableLyricSpriteText.cs
│   │   │   ├── LyricDisplayProperty.cs
│   │   │   ├── LyricDisplayType.cs
│   │   │   ├── LyricStyle.cs
│   │   │   └── Processor/
│   │   │       ├── BaseDisplayProcessor.cs
│   │   │       ├── LyricFirstDisplayProcessor.cs
│   │   │       └── RomanisedSyllableFirstDisplayProcessor.cs
│   │   ├── UserInterface/
│   │   │   ├── BindableBoolMenuItem.cs
│   │   │   └── BindableEnumMenuItem.cs
│   │   └── UserInterfaceV2/
│   │       ├── FontSelector.cs
│   │       ├── LabelledColourSelector.cs
│   │       ├── LabelledHueSelector.cs
│   │       ├── LabelledImageSelector.cs
│   │       ├── LabelledRealTimeSliderBar.cs
│   │       ├── LanguageSelector.cs
│   │       └── LanguageSelectorPopover.cs
│   ├── IO/
│   │   ├── Archives/
│   │   │   └── CachedFontArchiveReader.cs
│   │   ├── Serialization/
│   │   │   ├── Converters/
│   │   │   │   ├── ColourConverter.cs
│   │   │   │   ├── CultureInfoConverter.cs
│   │   │   │   ├── DictionaryConverter.cs
│   │   │   │   ├── ElementIdConverter.cs
│   │   │   │   ├── FontUsageConverter.cs
│   │   │   │   ├── GenericTypeConverter.cs
│   │   │   │   ├── KaraokeSkinElementConverter.cs
│   │   │   │   ├── LyricConverter.cs
│   │   │   │   ├── ReferenceLyricPropertyConfigConverter.cs
│   │   │   │   ├── RubyTagConverter.cs
│   │   │   │   ├── RubyTagsConverter.cs
│   │   │   │   ├── ShaderConverter.cs
│   │   │   │   ├── SortableJsonConverter.cs
│   │   │   │   ├── StageInfoConverter.cs
│   │   │   │   ├── TimeTagConverter.cs
│   │   │   │   ├── TimeTagsConverter.cs
│   │   │   │   ├── ToneConverter.cs
│   │   │   │   └── TranslationConverter.cs
│   │   │   ├── KaraokeJsonSerializableExtensions.cs
│   │   │   ├── SkinJsonSerializableExtensions.cs
│   │   │   └── WritablePropertiesOnlyResolver.cs
│   │   └── Stores/
│   │       ├── FntGlyphStore.cs
│   │       ├── KaraokeLocalFontStore.cs
│   │       └── TtfGlyphStore.cs
│   ├── Integration/
│   │   └── Formats/
│   │       ├── IDecoder.cs
│   │       ├── IEncoder.cs
│   │       ├── KarDecoder.cs
│   │       ├── KarEncoder.cs
│   │       ├── LrcDecoder.cs
│   │       ├── LrcEncoder.cs
│   │       ├── LrcParserUtils.cs
│   │       ├── LyricTextDecoder.cs
│   │       └── LyricTextEncoder.cs
│   ├── Judgements/
│   │   ├── KaraokeJudgement.cs
│   │   ├── KaraokeJudgementResult.cs
│   │   ├── KaraokeLyricJudgement.cs
│   │   └── KaraokeNoteJudgement.cs
│   ├── KaraokeControlInputManager.cs
│   ├── KaraokeEditInputManager.cs
│   ├── KaraokeInputManager.cs
│   ├── KaraokeRuleset.cs
│   ├── KaraokeSkinComponentLookup.cs
│   ├── KaraokeSkinComponents.cs
│   ├── Localisation/
│   │   ├── ChangelogStrings.cs
│   │   ├── CommonStrings.cs
│   │   └── KaraokeSettingsSubsectionStrings.cs
│   ├── Mods/
│   │   ├── IApplicableToMicrophone.cs
│   │   ├── IApplicableToSettingHUDOverlay.cs
│   │   ├── IApplicableToStage.cs
│   │   ├── IApplicableToStageElement.cs
│   │   ├── IApplicableToStageHitObjectCommand.cs
│   │   ├── IApplicableToStageInfo.cs
│   │   ├── IApplicableToStagePlayfieldCommand.cs
│   │   ├── KaraokeModAutoplay.cs
│   │   ├── KaraokeModAutoplayBySinger.cs
│   │   ├── KaraokeModClassicStage.cs
│   │   ├── KaraokeModDisableNote.cs
│   │   ├── KaraokeModFlashlight.cs
│   │   ├── KaraokeModHiddenNote.cs
│   │   ├── KaraokeModLyricConfiguration.cs
│   │   ├── KaraokeModNoFail.cs
│   │   ├── KaraokeModPerfect.cs
│   │   ├── KaraokeModPractice.cs
│   │   ├── KaraokeModPreviewStage.cs
│   │   ├── KaraokeModSnow.cs
│   │   ├── KaraokeModSuddenDeath.cs
│   │   ├── KaraokeModTranslation.cs
│   │   ├── KaraokeModWindowsUpdate.cs
│   │   ├── LanguageSettingsControl.cs
│   │   └── ModStage.cs
│   ├── Objects/
│   │   ├── BarLine.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableBarLine.cs
│   │   │   ├── DrawableKaraokeHitObject.cs
│   │   │   ├── DrawableKaraokeScrollingHitObject.cs
│   │   │   ├── DrawableLyric.cs
│   │   │   └── DrawableNote.cs
│   │   ├── KaraokeHitObject.cs
│   │   ├── LegacyProperties.cs
│   │   ├── Lyric.cs
│   │   ├── Lyric_Binding.cs
│   │   ├── Lyric_Working.cs
│   │   ├── Note.cs
│   │   ├── Note_Binding.cs
│   │   ├── Note_Working.cs
│   │   ├── Properties/
│   │   │   ├── IReferenceLyricPropertyConfig.cs
│   │   │   ├── ReferenceLyricConfig.cs
│   │   │   └── SyncLyricConfig.cs
│   │   ├── RubyTag.cs
│   │   ├── TimeTag.cs
│   │   ├── Title.cs
│   │   ├── TitlePart.cs
│   │   ├── Tone.cs
│   │   ├── Types/
│   │   │   ├── IHasLock.cs
│   │   │   ├── IHasOrder.cs
│   │   │   ├── IHasPage.cs
│   │   │   ├── IHasSingers.cs
│   │   │   ├── IHasText.cs
│   │   │   └── IHasWorkingProperty.cs
│   │   ├── Utils/
│   │   │   ├── LyricUtils.cs
│   │   │   ├── LyricsUtils.cs
│   │   │   ├── NoteUtils.cs
│   │   │   ├── NotesUtils.cs
│   │   │   ├── OrderUtils.cs
│   │   │   ├── RubyTagUtils.cs
│   │   │   ├── RubyTagsUtils.cs
│   │   │   ├── TimeTagUtils.cs
│   │   │   └── TimeTagsUtils.cs
│   │   └── Workings/
│   │       ├── HitObjectWorkingPropertyValidator.cs
│   │       ├── InvalidWorkingPropertyAssignException.cs
│   │       ├── LyricWorkingProperty.cs
│   │       ├── LyricWorkingPropertyValidator.cs
│   │       ├── NoteWorkingProperty.cs
│   │       └── NoteWorkingPropertyValidator.cs
│   ├── Online/
│   │   └── API/
│   │       └── Requests/
│   │           ├── ChangelogRequestUtils.cs
│   │           ├── GetChangelogBuildRequest.cs
│   │           ├── GetChangelogRequest.cs
│   │           ├── GithubAPIRequest.cs
│   │           └── Responses/
│   │               ├── APIChangelogBuild.cs
│   │               └── APIChangelogIndex.cs
│   ├── Overlays/
│   │   ├── Changelog/
│   │   │   ├── ChangeLogMarkdownContainer.cs
│   │   │   ├── ChangelogBadgeInfo.cs
│   │   │   ├── ChangelogBuild.cs
│   │   │   ├── ChangelogContent.cs
│   │   │   ├── ChangelogHeader.cs
│   │   │   ├── ChangelogListing.cs
│   │   │   ├── ChangelogPullRequestInfo.cs
│   │   │   ├── ChangelogSingleBuild.cs
│   │   │   └── Sidebar/
│   │   │       ├── ChangelogSection.cs
│   │   │       ├── ChangelogSidebar.cs
│   │   │       └── YearsPanel.cs
│   │   ├── Dialog/
│   │   │   └── OkPopupDialog.cs
│   │   └── KaraokeChangelogOverlay.cs
│   ├── Replays/
│   │   ├── KaraokeAutoGenerator.cs
│   │   ├── KaraokeAutoGeneratorBySinger.cs
│   │   ├── KaraokeFramedReplayInputHandler.cs
│   │   └── KaraokeReplayFrame.cs
│   ├── Resources/
│   │   └── Skin/
│   │       └── Default/
│   │           ├── default.json
│   │           ├── lyric-font-infos.json
│   │           └── note-styles.json
│   ├── Scoring/
│   │   ├── KaraokeHitWindows.cs
│   │   ├── KaraokeLyricHitWindows.cs
│   │   ├── KaraokeNoteHitWindows.cs
│   │   └── KaraokeScoreProcessor.cs
│   ├── Screens/
│   │   ├── Edit/
│   │   │   ├── AutoGenerateSection.cs
│   │   │   ├── AutoGenerateSubsection.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapEditorRoundedScreen.cs
│   │   │   │   ├── BeatmapEditorScreen.cs
│   │   │   │   ├── Components/
│   │   │   │   │   ├── Menus/
│   │   │   │   │   │   ├── AutoFocusToEditLyricMenu.cs
│   │   │   │   │   │   ├── GeneratorConfigMenu.cs
│   │   │   │   │   │   ├── ImportLyricMenu.cs
│   │   │   │   │   │   ├── LockStateMenu.cs
│   │   │   │   │   │   ├── LyricEditorModeMenu.cs
│   │   │   │   │   │   ├── LyricEditorPreferLayoutMenu.cs
│   │   │   │   │   │   └── LyricEditorTextSizeMenu.cs
│   │   │   │   │   └── UserInterfaceV2/
│   │   │   │   │       └── LyricSelector.cs
│   │   │   │   ├── ILyricsProvider.cs
│   │   │   │   ├── KaraokeBeatmapEditor.cs
│   │   │   │   ├── KaraokeBeatmapEditorScreenMode.cs
│   │   │   │   ├── Lyrics/
│   │   │   │   │   ├── BindableBlueprintContainer.cs
│   │   │   │   │   ├── CaretPosition/
│   │   │   │   │   │   ├── Algorithms/
│   │   │   │   │   │   │   ├── CaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CharGapCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CharIndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── ClickingCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CreateRubyTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── CuttingCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── ICaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── IIndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── IndexCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── NavigateCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretMoveMode.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretPositionAlgorithm.cs
│   │   │   │   │   │   │   └── TypingCaretPositionAlgorithm.cs
│   │   │   │   │   │   ├── ClickingCaretPosition.cs
│   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPosition.cs
│   │   │   │   │   │   ├── CreateRubyTagCaretPosition.cs
│   │   │   │   │   │   ├── CuttingCaretPosition.cs
│   │   │   │   │   │   ├── ICaretPosition.cs
│   │   │   │   │   │   ├── ICharGapCaretPosition.cs
│   │   │   │   │   │   ├── ICharIndexCaretPosition.cs
│   │   │   │   │   │   ├── IIndexCaretPosition.cs
│   │   │   │   │   │   ├── NavigateCaretPosition.cs
│   │   │   │   │   │   ├── RecordingTimeTagCaretPosition.cs
│   │   │   │   │   │   └── TypingCaretPosition.cs
│   │   │   │   │   ├── ClipboardToast.cs
│   │   │   │   │   ├── Content/
│   │   │   │   │   │   ├── ApplySelectingArea.cs
│   │   │   │   │   │   ├── CircleCheckbox.cs
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── Badges/
│   │   │   │   │   │   │   │   ├── Badge.cs
│   │   │   │   │   │   │   │   ├── LanguageBadge.cs
│   │   │   │   │   │   │   │   ├── ReferenceLyricBadge.cs
│   │   │   │   │   │   │   │   ├── SingerBadge.cs
│   │   │   │   │   │   │   │   └── TimeTagBadge.cs
│   │   │   │   │   │   │   ├── FixedInfo/
│   │   │   │   │   │   │   │   ├── InvalidInfo.cs
│   │   │   │   │   │   │   │   ├── LockInfo.cs
│   │   │   │   │   │   │   │   └── OrderInfo.cs
│   │   │   │   │   │   │   └── Lyrics/
│   │   │   │   │   │   │       ├── BlueprintLayer.cs
│   │   │   │   │   │   │       ├── Blueprints/
│   │   │   │   │   │   │       │   ├── LyricPropertyBlueprintContainer.cs
│   │   │   │   │   │   │       │   ├── RubyBlueprintContainer.cs
│   │   │   │   │   │   │       │   ├── RubyTagSelectionBlueprint.cs
│   │   │   │   │   │   │       │   ├── TimeTagBlueprintContainer.cs
│   │   │   │   │   │   │       │   └── TimeTagSelectionBlueprint.cs
│   │   │   │   │   │   │       ├── CaretLayer.cs
│   │   │   │   │   │   │       ├── Carets/
│   │   │   │   │   │   │       │   ├── DrawableCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCaretState.cs
│   │   │   │   │   │   │       │   ├── DrawableCreateRemoveTimeTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCreateRubyTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableCuttingCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableRangeCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableRecordingTimeTagCaret.cs
│   │   │   │   │   │   │       │   ├── DrawableTypingCaret.cs
│   │   │   │   │   │   │       │   └── ICanAcceptRangeIndex.cs
│   │   │   │   │   │   │       ├── EditLyricLayer.cs
│   │   │   │   │   │   │       ├── GridLayer.cs
│   │   │   │   │   │   │       ├── IInteractableLyricState.cs
│   │   │   │   │   │   │       ├── IPreviewLyricPositionProvider.cs
│   │   │   │   │   │   │       ├── InteractLyricLayer.cs
│   │   │   │   │   │   │       ├── InteractableLyric.cs
│   │   │   │   │   │   │       ├── Layer.cs
│   │   │   │   │   │   │       ├── LayerLoader.cs
│   │   │   │   │   │   │       ├── LyricLayer.cs
│   │   │   │   │   │   │       ├── PreviewKaraokeSpriteText.cs
│   │   │   │   │   │   │       ├── TimeTagLayer.cs
│   │   │   │   │   │   │       └── UIEventLayer.cs
│   │   │   │   │   │   ├── Compose/
│   │   │   │   │   │   │   ├── BottomEditor/
│   │   │   │   │   │   │   │   ├── AdjustTimeTagBottomEditor.cs
│   │   │   │   │   │   │   │   ├── AdjustTimeTags/
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagBlueprintContainer.cs
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagScrollContainer.cs
│   │   │   │   │   │   │   │   │   ├── AdjustTimeTagSelectionBlueprint.cs
│   │   │   │   │   │   │   │   │   ├── CurrentTimeMarker.cs
│   │   │   │   │   │   │   │   │   └── TimeTagOrderedSelectionContainer.cs
│   │   │   │   │   │   │   │   ├── BaseBottomEditor.cs
│   │   │   │   │   │   │   │   ├── NoteBottomEditor.cs
│   │   │   │   │   │   │   │   ├── Notes/
│   │   │   │   │   │   │   │   │   ├── NoteEditPopover.cs
│   │   │   │   │   │   │   │   │   ├── NoteEditor.cs
│   │   │   │   │   │   │   │   │   ├── NoteEditorBlueprintContainer.cs
│   │   │   │   │   │   │   │   │   └── NoteEditorSelectionBlueprint.cs
│   │   │   │   │   │   │   │   ├── RecordingTimeTagBottomEditor.cs
│   │   │   │   │   │   │   │   ├── RecordingTimeTags/
│   │   │   │   │   │   │   │   │   ├── CentreMarker.cs
│   │   │   │   │   │   │   │   │   ├── RecordingTimeTagPart.cs
│   │   │   │   │   │   │   │   │   ├── RecordingTimeTagScrollContainer.cs
│   │   │   │   │   │   │   │   │   └── TimeTagsVisualisation.cs
│   │   │   │   │   │   │   │   └── TimeTagScrollContainer.cs
│   │   │   │   │   │   │   ├── ComposeContent.cs
│   │   │   │   │   │   │   ├── CreateNewLyricDetailRow.cs
│   │   │   │   │   │   │   ├── DetailLyricList.cs
│   │   │   │   │   │   │   ├── DetailRow.cs
│   │   │   │   │   │   │   ├── EditLyricDetailRow.cs
│   │   │   │   │   │   │   ├── LyricComposer.cs
│   │   │   │   │   │   │   ├── LyricEditor.cs
│   │   │   │   │   │   │   ├── Panel.cs
│   │   │   │   │   │   │   ├── PanelDirection.cs
│   │   │   │   │   │   │   ├── Panels/
│   │   │   │   │   │   │   │   ├── InvalidPanel.cs
│   │   │   │   │   │   │   │   ├── IssueSection.cs
│   │   │   │   │   │   │   │   ├── PanelSection.cs
│   │   │   │   │   │   │   │   └── PropertyPanel.cs
│   │   │   │   │   │   │   ├── SpecialActionToolbar.cs
│   │   │   │   │   │   │   └── Toolbar/
│   │   │   │   │   │   │       ├── Carets/
│   │   │   │   │   │   │       │   ├── MoveToCaretPositionButton.cs
│   │   │   │   │   │   │       │   ├── MoveToFirstIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToLastIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToNextIndexButton.cs
│   │   │   │   │   │   │       │   ├── MoveToNextLyricButton.cs
│   │   │   │   │   │   │       │   ├── MoveToPreviousIndexButton.cs
│   │   │   │   │   │   │       │   └── MoveToPreviousLyricButton.cs
│   │   │   │   │   │   │       ├── Panels/
│   │   │   │   │   │   │       │   ├── ToggleInvalidInfoPanelButton.cs
│   │   │   │   │   │   │       │   └── TogglePropertyPanelButton.cs
│   │   │   │   │   │   │       ├── Playback/
│   │   │   │   │   │   │       │   └── PlaybackSwitchButton.cs
│   │   │   │   │   │   │       ├── Separator.cs
│   │   │   │   │   │   │       ├── ToolbarButton.cs
│   │   │   │   │   │   │       ├── ToolbarEditActionButton.cs
│   │   │   │   │   │   │       ├── ToolbarToggleButton.cs
│   │   │   │   │   │   │       └── View/
│   │   │   │   │   │   │           └── AdjustFontSizeButton.cs
│   │   │   │   │   │   ├── ContentWrapper.cs
│   │   │   │   │   │   ├── List/
│   │   │   │   │   │   │   ├── CreateNewLyricPreviewRow.cs
│   │   │   │   │   │   │   ├── EditLyricPreviewRow.cs
│   │   │   │   │   │   │   ├── InfoControl.cs
│   │   │   │   │   │   │   ├── ListContent.cs
│   │   │   │   │   │   │   ├── PreviewLyricList.cs
│   │   │   │   │   │   │   └── PreviewRow.cs
│   │   │   │   │   │   ├── LyricList.cs
│   │   │   │   │   │   ├── MainContent.cs
│   │   │   │   │   │   └── Row.cs
│   │   │   │   │   ├── DeleteLyricDialog.cs
│   │   │   │   │   ├── IIssueNavigator.cs
│   │   │   │   │   ├── ILyricEditorClipboard.cs
│   │   │   │   │   ├── ILyricEditorState.cs
│   │   │   │   │   ├── ILyricEditorVerifier.cs
│   │   │   │   │   ├── IssueNavigator.cs
│   │   │   │   │   ├── LyricEditor.cs
│   │   │   │   │   ├── LyricEditorClipboard.cs
│   │   │   │   │   ├── LyricEditorColourProvider.cs
│   │   │   │   │   ├── LyricEditorIssueTable.cs
│   │   │   │   │   ├── LyricEditorLayout.cs
│   │   │   │   │   ├── LyricEditorMode.cs
│   │   │   │   │   ├── LyricEditorScreen.cs
│   │   │   │   │   ├── LyricEditorSkin.cs
│   │   │   │   │   ├── LyricEditorVerifier.cs
│   │   │   │   │   ├── OsuColourExtensions.cs
│   │   │   │   │   ├── Settings/
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── BlockSectionWrapper.cs
│   │   │   │   │   │   │   └── Markdown/
│   │   │   │   │   │   │       ├── LyricEditorDescriptionTextFlowContainer.cs
│   │   │   │   │   │   │       ├── SwitchModeDescriptionAction.cs
│   │   │   │   │   │   │       └── SwitchMoteText.cs
│   │   │   │   │   │   ├── LabelledObjectFieldSwitchButton.cs
│   │   │   │   │   │   ├── LabelledObjectFieldTextBox.cs
│   │   │   │   │   │   ├── Language/
│   │   │   │   │   │   │   ├── AssignLanguageSubsection.cs
│   │   │   │   │   │   │   ├── LanguageAutoGenerateSubsection.cs
│   │   │   │   │   │   │   ├── LanguageEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── LanguageIssueSection.cs
│   │   │   │   │   │   │   ├── LanguageSettingsHeader.cs
│   │   │   │   │   │   │   └── LanguageSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── LanguageSettings.cs
│   │   │   │   │   │   ├── LyricEditorAutoGenerateSubsection.cs
│   │   │   │   │   │   ├── LyricEditorIssueSection.cs
│   │   │   │   │   │   ├── LyricEditorSettings.cs
│   │   │   │   │   │   ├── LyricEditorSettingsHeader.cs
│   │   │   │   │   │   ├── LyricPropertiesSection.cs
│   │   │   │   │   │   ├── LyricPropertySection.cs
│   │   │   │   │   │   ├── NoteSettings.cs
│   │   │   │   │   │   ├── Notes/
│   │   │   │   │   │   │   ├── NoteAutoGenerateSubsection.cs
│   │   │   │   │   │   │   ├── NoteClearSubsection.cs
│   │   │   │   │   │   │   ├── NoteConfigSection.cs
│   │   │   │   │   │   │   ├── NoteEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── NoteEditPropertyMode.cs
│   │   │   │   │   │   │   ├── NoteEditPropertyModeSection.cs
│   │   │   │   │   │   │   ├── NoteEditPropertySection.cs
│   │   │   │   │   │   │   ├── NoteIssueSection.cs
│   │   │   │   │   │   │   ├── NoteSettingsHeader.cs
│   │   │   │   │   │   │   └── NoteSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── Reference/
│   │   │   │   │   │   │   ├── LabelledReferenceLyricSelector.cs
│   │   │   │   │   │   │   ├── ReferenceLyricAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricConfigSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricIssueSection.cs
│   │   │   │   │   │   │   ├── ReferenceLyricSection.cs
│   │   │   │   │   │   │   └── ReferenceLyricSettingsHeader.cs
│   │   │   │   │   │   ├── ReferenceSettings.cs
│   │   │   │   │   │   ├── Romanisation/
│   │   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   │   └── LabelledRomanisedTextBox.cs
│   │   │   │   │   │   │   ├── RomanisationAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── RomanisationEditSection.cs
│   │   │   │   │   │   │   ├── RomanisationIssueSection.cs
│   │   │   │   │   │   │   └── RomanisationSettingsHeader.cs
│   │   │   │   │   │   ├── RomanisationSettings.cs
│   │   │   │   │   │   ├── Ruby/
│   │   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   │   └── LabelledRubyTagTextBox.cs
│   │   │   │   │   │   │   ├── RubyTagAutoGenerateSection.cs
│   │   │   │   │   │   │   ├── RubyTagConfigToolSection.cs
│   │   │   │   │   │   │   ├── RubyTagEditModeSubsection.cs
│   │   │   │   │   │   │   ├── RubyTagEditSection.cs
│   │   │   │   │   │   │   ├── RubyTagIssueSection.cs
│   │   │   │   │   │   │   └── RubyTagSettingsHeader.cs
│   │   │   │   │   │   ├── RubyTagSettings.cs
│   │   │   │   │   │   ├── SelectLyricButton.cs
│   │   │   │   │   │   ├── SettingsDirection.cs
│   │   │   │   │   │   ├── SingerSettings.cs
│   │   │   │   │   │   ├── Singers/
│   │   │   │   │   │   │   └── SingerEditSection.cs
│   │   │   │   │   │   ├── SpecialActionSection.cs
│   │   │   │   │   │   ├── SwitchSubsection.cs
│   │   │   │   │   │   ├── Text/
│   │   │   │   │   │   │   ├── TextDeleteSubsection.cs
│   │   │   │   │   │   │   ├── TextEditModeSpecialAction.cs
│   │   │   │   │   │   │   ├── TextIssueSection.cs
│   │   │   │   │   │   │   ├── TextSettingsHeader.cs
│   │   │   │   │   │   │   └── TextSwitchSpecialActionSection.cs
│   │   │   │   │   │   ├── TextSettings.cs
│   │   │   │   │   │   ├── TimeTagSettings.cs
│   │   │   │   │   │   └── TimeTags/
│   │   │   │   │   │       ├── Components/
│   │   │   │   │   │       │   └── LabelledOpacityAdjustment.cs
│   │   │   │   │   │       ├── CreateTimeTagActionSection.cs
│   │   │   │   │   │       ├── CreateTimeTagTypeSubsection.cs
│   │   │   │   │   │       ├── RecordingTapControl.cs
│   │   │   │   │   │       ├── TapButton.cs
│   │   │   │   │   │       ├── TimeTagAdjustConfigSection.cs
│   │   │   │   │   │       ├── TimeTagAutoGenerateSection.cs
│   │   │   │   │   │       ├── TimeTagIssueSection.cs
│   │   │   │   │   │       ├── TimeTagRecordingConfigSection.cs
│   │   │   │   │   │       ├── TimeTagRecordingToolSection.cs
│   │   │   │   │   │       └── TimeTagSettingsHeader.cs
│   │   │   │   │   └── States/
│   │   │   │   │       ├── ILyricCaretState.cs
│   │   │   │   │       ├── ILyricSelectionState.cs
│   │   │   │   │       ├── LyricCaretState.cs
│   │   │   │   │       ├── LyricEditorSelectingAction.cs
│   │   │   │   │       ├── LyricSelectionState.cs
│   │   │   │   │       ├── Modes/
│   │   │   │   │       │   ├── CreateTimeTagType.cs
│   │   │   │   │       │   ├── EditLanguageModeState.cs
│   │   │   │   │       │   ├── EditNoteModeState.cs
│   │   │   │   │       │   ├── EditReferenceLyricModeState.cs
│   │   │   │   │       │   ├── EditRomanisationModeState.cs
│   │   │   │   │       │   ├── EditRubyModeState.cs
│   │   │   │   │       │   ├── EditTextModeState.cs
│   │   │   │   │       │   ├── EditTimeTagModeState.cs
│   │   │   │   │       │   ├── IEditLanguageModeState.cs
│   │   │   │   │       │   ├── IEditNoteModeState.cs
│   │   │   │   │       │   ├── IEditReferenceLyricModeState.cs
│   │   │   │   │       │   ├── IEditRomanisationModeState.cs
│   │   │   │   │       │   ├── IEditRubyModeState.cs
│   │   │   │   │       │   ├── IEditTextModeState.cs
│   │   │   │   │       │   ├── IEditTimeTagModeState.cs
│   │   │   │   │       │   ├── IHasBlueprintSelection.cs
│   │   │   │   │       │   ├── IHasEditStep.cs
│   │   │   │   │       │   ├── IHasSpecialAction.cs
│   │   │   │   │       │   ├── LanguageEditStep.cs
│   │   │   │   │       │   ├── ModeStateWithBlueprintContainer.cs
│   │   │   │   │       │   ├── NoteEditStep.cs
│   │   │   │   │       │   ├── ReferenceLyricEditStep.cs
│   │   │   │   │       │   ├── RomanisationTagEditStep.cs
│   │   │   │   │       │   ├── RubyTagEditMode.cs
│   │   │   │   │       │   ├── RubyTagEditStep.cs
│   │   │   │   │       │   ├── TextEditStep.cs
│   │   │   │   │       │   └── TimeTagEditStep.cs
│   │   │   │   │       ├── MovingCaretAction.cs
│   │   │   │   │       └── RangeCaretPosition.cs
│   │   │   │   ├── LyricsProvider.cs
│   │   │   │   ├── Pages/
│   │   │   │   │   ├── Components/
│   │   │   │   │   │   └── Timeline/
│   │   │   │   │   │       ├── LyricBlueprintContainer.cs
│   │   │   │   │   │       ├── PageBlueprintContainer.cs
│   │   │   │   │   │       ├── PageSelectionBlueprint.cs
│   │   │   │   │   │       ├── PagesTimeLine.cs
│   │   │   │   │   │       └── PreviewLyricSelectionBlueprint.cs
│   │   │   │   │   ├── IPageEditorVerifier.cs
│   │   │   │   │   ├── IPageStateProvider.cs
│   │   │   │   │   ├── PageEditor.cs
│   │   │   │   │   ├── PageEditorEditMode.cs
│   │   │   │   │   ├── PageEditorVerifier.cs
│   │   │   │   │   ├── PageScreen.cs
│   │   │   │   │   └── Settings/
│   │   │   │   │       ├── ConfirmReGeneratePageDialog.cs
│   │   │   │   │       ├── PageAutoGenerateSection.cs
│   │   │   │   │       ├── PageEditorIssueSection.cs
│   │   │   │   │       ├── PageEditorSettingsHeader.cs
│   │   │   │   │       ├── PageSettings.cs
│   │   │   │   │       └── PagesSection.cs
│   │   │   │   ├── Singers/
│   │   │   │   │   ├── DeleteSingerDialog.cs
│   │   │   │   │   ├── Detail/
│   │   │   │   │   │   ├── AvatarSection.cs
│   │   │   │   │   │   ├── EditSingerSection.cs
│   │   │   │   │   │   ├── MetadataSection.cs
│   │   │   │   │   │   └── SingerEditPopover.cs
│   │   │   │   │   ├── ISingerScreenScrollingInfoProvider.cs
│   │   │   │   │   ├── Rows/
│   │   │   │   │   │   ├── Components/
│   │   │   │   │   │   │   ├── SingerAvatar.cs
│   │   │   │   │   │   │   └── Timeline/
│   │   │   │   │   │   │       ├── LyricTimelineSelectionBlueprint.cs
│   │   │   │   │   │   │       ├── SingerLyricEditorBlueprintContainer.cs
│   │   │   │   │   │   │       └── SingerLyricTimeline.cs
│   │   │   │   │   │   ├── CreateNewLyricPlacementRow.cs
│   │   │   │   │   │   ├── DefaultLyricPlacementRow.cs
│   │   │   │   │   │   ├── LyricPlacementRow.cs
│   │   │   │   │   │   └── SingerLyricPlacementRow.cs
│   │   │   │   │   ├── SingerEditSection.cs
│   │   │   │   │   ├── SingerRearrangeableList.cs
│   │   │   │   │   ├── SingerRearrangeableListItem.cs
│   │   │   │   │   └── SingerScreen.cs
│   │   │   │   └── Translations/
│   │   │   │       ├── Components/
│   │   │   │       │   ├── CreateNewTranslationButton.cs
│   │   │   │       │   ├── LanguageDropdown.cs
│   │   │   │       │   ├── LyricTranslationTextBox.cs
│   │   │   │       │   ├── PreviewLyricSpriteText.cs
│   │   │   │       │   └── RemoveTranslationButton.cs
│   │   │   │       ├── DeleteLanguagePopupDialog.cs
│   │   │   │       ├── ITranslationInfoProvider.cs
│   │   │   │       ├── TranslationEditSection.cs
│   │   │   │       └── TranslationScreen.cs
│   │   │   ├── BottomBar.cs
│   │   │   ├── Components/
│   │   │   │   ├── Containers/
│   │   │   │   │   └── BindableScrollContainer.cs
│   │   │   │   ├── Issues/
│   │   │   │   │   ├── IssueIcon.cs
│   │   │   │   │   └── IssuesToolTip.cs
│   │   │   │   ├── Markdown/
│   │   │   │   │   ├── DescriptionFormat.cs
│   │   │   │   │   ├── DescriptionTextFlowContainer.cs
│   │   │   │   │   ├── IDescriptionAction.cs
│   │   │   │   │   ├── InputKeyDescriptionAction.cs
│   │   │   │   │   └── InputKeyText.cs
│   │   │   │   ├── Menus/
│   │   │   │   │   └── GenericScreenSelectionTabControl.cs
│   │   │   │   ├── Timeline/
│   │   │   │   │   ├── EditableLyricTimelineSelectionBlueprint.cs
│   │   │   │   │   ├── EditableTimeline.cs
│   │   │   │   │   ├── EditableTimelineBlueprintContainer.cs
│   │   │   │   │   └── EditableTimelineSelectionBlueprint.cs
│   │   │   │   └── UserInterface/
│   │   │   │       ├── DeleteIconButton.cs
│   │   │   │       └── LanguagesSelector.cs
│   │   │   ├── EditorSection.cs
│   │   │   ├── EditorSectionButton.cs
│   │   │   ├── EditorSettings.cs
│   │   │   ├── EditorSettingsHeader.cs
│   │   │   ├── EditorTable.cs
│   │   │   ├── EditorVerifier.cs
│   │   │   ├── GeneratorConfigPopover.cs
│   │   │   ├── GenericEditor.cs
│   │   │   ├── GenericEditorScreen.cs
│   │   │   ├── IEditorVerifier.cs
│   │   │   ├── ISectionItemsEditorProvider.cs
│   │   │   ├── Import/
│   │   │   │   └── Lyrics/
│   │   │   │       ├── AssignLanguage/
│   │   │   │       │   ├── AssignLanguageNavigation.cs
│   │   │   │       │   ├── AssignLanguageStepScreen.cs
│   │   │   │       │   └── UseLanguageDetectorPopupDialog.cs
│   │   │   │       ├── DragFile/
│   │   │   │       │   ├── Components/
│   │   │   │       │   │   └── DrawableDragFile.cs
│   │   │   │       │   ├── DragFileStepScreen.cs
│   │   │   │       │   └── ImportLyricDialog.cs
│   │   │   │       ├── EditLyric/
│   │   │   │       │   ├── EditLyricNavigation.cs
│   │   │   │       │   └── EditLyricStepScreen.cs
│   │   │   │       ├── GenerateRuby/
│   │   │   │       │   ├── GenerateRubyNavigation.cs
│   │   │   │       │   ├── GenerateRubyStepScreen.cs
│   │   │   │       │   └── UseAutoGenerateRubyPopupDialog.cs
│   │   │   │       ├── GenerateTimeTag/
│   │   │   │       │   ├── AlreadyContainTimeTagPopupDialog.cs
│   │   │   │       │   ├── GenerateTimeTagNavigation.cs
│   │   │   │       │   ├── GenerateTimeTagStepScreen.cs
│   │   │   │       │   ├── UseAutoGenerateRomanisationPopupDialog.cs
│   │   │   │       │   └── UseAutoGenerateTimeTagPopupDialog.cs
│   │   │   │       ├── IHasTopNavigation.cs
│   │   │   │       ├── IImportStateResolver.cs
│   │   │   │       ├── ILyricImporterStepScreen.cs
│   │   │   │       ├── ImportLyricHeader.cs
│   │   │   │       ├── ImportLyricManager.cs
│   │   │   │       ├── ImportLyricOverlay.cs
│   │   │   │       ├── LyricImporter.cs
│   │   │   │       ├── LyricImporterStep.cs
│   │   │   │       ├── LyricImporterStepScreen.cs
│   │   │   │       ├── LyricImporterStepScreenWithLyricEditor.cs
│   │   │   │       ├── LyricImporterSubScreenStack.cs
│   │   │   │       ├── NotImportStepScreenException.cs
│   │   │   │       ├── RollBackPopupDialog.cs
│   │   │   │       ├── RollBackResetPopupDialog.cs
│   │   │   │       ├── Success/
│   │   │   │       │   └── SuccessStepScreen.cs
│   │   │   │       └── TopNavigation.cs
│   │   │   ├── IssueSection.cs
│   │   │   ├── IssueTable.cs
│   │   │   ├── SectionItemsEditor.cs
│   │   │   ├── SectionTimingInfoItemsEditor.cs
│   │   │   ├── Stages/
│   │   │   │   └── Classic/
│   │   │   │       ├── ClassicStageEditor.cs
│   │   │   │       ├── ClassicStageEditorScreenMode.cs
│   │   │   │       ├── ClassicStageScreen.cs
│   │   │   │       ├── Config/
│   │   │   │       │   └── ConfigScreen.cs
│   │   │   │       └── Stage/
│   │   │   │           ├── IStageEditorStateProvider.cs
│   │   │   │           ├── IStageEditorVerifier.cs
│   │   │   │           ├── Settings/
│   │   │   │           │   ├── StageEditorIssueSection.cs
│   │   │   │           │   ├── StageEditorSettingsHeader.cs
│   │   │   │           │   ├── StageSettings.cs
│   │   │   │           │   └── TimingPointsSection.cs
│   │   │   │           ├── StageCategoryScreenStack.cs
│   │   │   │           ├── StageEditor.cs
│   │   │   │           ├── StageEditorEditCategory.cs
│   │   │   │           ├── StageEditorEditMode.cs
│   │   │   │           ├── StageEditorVerifier.cs
│   │   │   │           └── StageScreen.cs
│   │   │   ├── WorkspaceScreen.cs
│   │   │   └── WorkspaceScreenStack.cs
│   │   ├── Section.cs
│   │   ├── Settings/
│   │   │   ├── Header.cs
│   │   │   ├── KaraokeSettings.cs
│   │   │   ├── KaraokeSettingsColourProvider.cs
│   │   │   ├── KaraokeSettingsPanel.cs
│   │   │   ├── KaraokeSettingsSection.cs
│   │   │   ├── KaraokeSettingsSubsection.cs
│   │   │   ├── KaraokeVersionManager.cs
│   │   │   ├── Previews/
│   │   │   │   ├── DefaultPreview.cs
│   │   │   │   ├── Gameplay/
│   │   │   │   │   ├── LyricPreview.cs
│   │   │   │   │   ├── NotePlayfieldPreview.cs
│   │   │   │   │   └── ShowCursorPreview.cs
│   │   │   │   ├── Graphics/
│   │   │   │   │   └── ManageFontPreview.cs
│   │   │   │   ├── Input/
│   │   │   │   │   ├── MicrophoneDevicePreview.cs
│   │   │   │   │   └── MicrophoneSoundVisualizer.cs
│   │   │   │   ├── SettingsSubsectionPreview.cs
│   │   │   │   └── UnderConstructionPreview.cs
│   │   │   ├── Sections/
│   │   │   │   ├── ConfigSection.cs
│   │   │   │   ├── Gameplay/
│   │   │   │   │   ├── GeneralSettings.cs
│   │   │   │   │   ├── NoteSettings.cs
│   │   │   │   │   └── ScoringSettings.cs
│   │   │   │   ├── Graphics/
│   │   │   │   │   ├── LyricFontSettings.cs
│   │   │   │   │   ├── ManageFontSettings.cs
│   │   │   │   │   ├── NoteFontSettings.cs
│   │   │   │   │   └── TransparentSettings.cs
│   │   │   │   ├── Input/
│   │   │   │   │   └── MicrophoneSettings.cs
│   │   │   │   ├── ScoringSection.cs
│   │   │   │   └── StyleSection.cs
│   │   │   ├── SettingsFont.cs
│   │   │   └── SettingsMicrophoneDeviceDropdown.cs
│   │   └── Skin/
│   │       ├── Config/
│   │       │   ├── ConfigScreen.cs
│   │       │   ├── IntervalSection.cs
│   │       │   ├── LyricConfigSection.cs
│   │       │   ├── LyricFontInfoManager.cs
│   │       │   ├── PositionSection.cs
│   │       │   └── RubyAndRomanisationSection.cs
│   │       ├── KaraokeSkinEditor.cs
│   │       ├── KaraokeSkinEditorScreen.cs
│   │       ├── KaraokeSkinEditorScreenMode.cs
│   │       └── Style/
│   │           ├── LyricColorSection.cs
│   │           ├── LyricFontSection.cs
│   │           ├── LyricShadowSection.cs
│   │           ├── LyricStylePreview.cs
│   │           ├── NoteColorSection.cs
│   │           ├── NoteFontSection.cs
│   │           ├── NoteStylePreview.cs
│   │           ├── StyleScreen.cs
│   │           └── StyleSection.cs
│   ├── Skinning/
│   │   ├── Argon/
│   │   │   └── KaraokeArgonSkinTransformer.cs
│   │   ├── Default/
│   │   │   ├── DefaultBodyPiece.cs
│   │   │   └── KaraokeDefaultSkinTransformer.cs
│   │   ├── Elements/
│   │   │   ├── ElementType.cs
│   │   │   ├── IKaraokeSkinElement.cs
│   │   │   ├── InvalidDrawableTypeException.cs
│   │   │   ├── LayoutGroup.cs
│   │   │   ├── LyricFontInfo.cs
│   │   │   └── NoteStyle.cs
│   │   ├── Fonts/
│   │   │   ├── BitmapFontCompressor.cs
│   │   │   ├── BitmapFontImageGenerator.cs
│   │   │   ├── FontInfo.cs
│   │   │   └── FontManager.cs
│   │   ├── InternalSkinStorageResourceProvider.cs
│   │   ├── KaraokeBeatmapSkin.cs
│   │   ├── KaraokeIndexLookup.cs
│   │   ├── KaraokeSkin.cs
│   │   ├── KaraokeSkinConfigurationLookup.cs
│   │   ├── KaraokeSkinLookup.cs
│   │   ├── Legacy/
│   │   │   ├── KaraokeClassicSkinTransformer.cs
│   │   │   ├── KaraokeLegacySkinTransformer.cs
│   │   │   ├── LegacyColumnBackground.cs
│   │   │   ├── LegacyHitExplosion.cs
│   │   │   ├── LegacyJudgementLine.cs
│   │   │   ├── LegacyKaraokeColumnElement.cs
│   │   │   ├── LegacyKaraokeElement.cs
│   │   │   ├── LegacyNotePiece.cs
│   │   │   └── LegacyStageBackground.cs
│   │   ├── Tools/
│   │   │   └── SkinConverterTool.cs
│   │   └── Triangles/
│   │       └── KaraokeTrianglesSkinTransformer.cs
│   ├── Stages/
│   │   ├── Commands/
│   │   │   ├── IStageCommand.cs
│   │   │   ├── Lyrics/
│   │   │   │   └── LyricStyleCommand.cs
│   │   │   ├── StageAlphaCommand.cs
│   │   │   ├── StageAnchorCommand.cs
│   │   │   ├── StageCommand.cs
│   │   │   ├── StageHeightCommand.cs
│   │   │   ├── StageOriginCommand.cs
│   │   │   ├── StagePaddingCommand.cs
│   │   │   ├── StageScaleCommand.cs
│   │   │   ├── StageWidthCommand.cs
│   │   │   ├── StageXCommand.cs
│   │   │   └── StageYCommand.cs
│   │   ├── Drawables/
│   │   │   ├── DrawableStage.cs
│   │   │   ├── DrawableStageBeatmapCoverInfo.cs
│   │   │   ├── IStageElementRunner.cs
│   │   │   ├── IStageHitObjectRunner.cs
│   │   │   ├── IStagePlayfieldRunner.cs
│   │   │   ├── StageElementRunner.cs
│   │   │   ├── StageHitObjectRunner.cs
│   │   │   ├── StagePlayfieldRunner.cs
│   │   │   └── StageRunner.cs
│   │   ├── HitObjectCommandProvider.cs
│   │   ├── IHitObjectCommandProvider.cs
│   │   ├── IPlayfieldCommandProvider.cs
│   │   ├── IStageElement.cs
│   │   ├── IStageElementProvider.cs
│   │   ├── IStageElementWithDuration.cs
│   │   ├── Infos/
│   │   │   ├── Classic/
│   │   │   │   ├── ClassicLyricCommandProvider.cs
│   │   │   │   ├── ClassicLyricLayout.cs
│   │   │   │   ├── ClassicLyricLayoutAlignment.cs
│   │   │   │   ├── ClassicLyricLayoutCategory.cs
│   │   │   │   ├── ClassicLyricTimingInfo.cs
│   │   │   │   ├── ClassicLyricTimingPoint.cs
│   │   │   │   ├── ClassicPlayfieldCommandProvider.cs
│   │   │   │   ├── ClassicStageDefinition.cs
│   │   │   │   ├── ClassicStageInfo.cs
│   │   │   │   ├── ClassicStyle.cs
│   │   │   │   └── ClassicStyleCategory.cs
│   │   │   ├── Preview/
│   │   │   │   ├── PreviewElementProvider.cs
│   │   │   │   ├── PreviewLyricCommandProvider.cs
│   │   │   │   ├── PreviewLyricLayout.cs
│   │   │   │   ├── PreviewLyricLayoutCategory.cs
│   │   │   │   ├── PreviewPlayfieldCommandProvider.cs
│   │   │   │   ├── PreviewStageDefinition.cs
│   │   │   │   ├── PreviewStageInfo.cs
│   │   │   │   ├── PreviewStageTimingCalculator.cs
│   │   │   │   ├── PreviewStyle.cs
│   │   │   │   └── PreviewStyleCategory.cs
│   │   │   ├── StageDefinition.cs
│   │   │   ├── StageElement.cs
│   │   │   ├── StageElementCategory.cs
│   │   │   ├── StageInfo.cs
│   │   │   └── Types/
│   │   │       └── IHasCalculatedProperty.cs
│   │   ├── PlayfieldCommandProvider.cs
│   │   ├── StageBeatmapCoverInfo.cs
│   │   ├── StageElementProvider.cs
│   │   └── StageSprite.cs
│   ├── Statistics/
│   │   ├── BeatmapMetadataGraph.cs
│   │   ├── NotScorableGraph.cs
│   │   └── ScoringResultGraph.cs
│   ├── Timing/
│   │   └── StopClock.cs
│   ├── UI/
│   │   ├── Components/
│   │   │   ├── CenterLine.cs
│   │   │   ├── DefaultColumnBackground.cs
│   │   │   ├── DefaultJudgementLine.cs
│   │   │   ├── RealTimeScoringVisualization.cs
│   │   │   ├── ReplayScoringVisualization.cs
│   │   │   ├── ScoringMarker.cs
│   │   │   ├── ScoringStatus.cs
│   │   │   └── VoiceVisualization.cs
│   │   ├── DefaultHitExplosion.cs
│   │   ├── DrawableKaraokeRuleset.cs
│   │   ├── DrawableNoteJudgement.cs
│   │   ├── HUD/
│   │   │   ├── BindableNumberExtension.cs
│   │   │   ├── GeneralSettingOverlay.cs
│   │   │   ├── ISettingHUDOverlay.cs
│   │   │   ├── PracticeOverlay.cs
│   │   │   ├── SettingButton.cs
│   │   │   ├── SettingButtonsDisplay.cs
│   │   │   ├── SettingOverlay.cs
│   │   │   └── SettingOverlayContainer.cs
│   │   ├── KaraokePlayfield.cs
│   │   ├── KaraokePlayfieldAdjustmentContainer.cs
│   │   ├── KaraokeReplayRecorder.cs
│   │   ├── KaraokeScrollingDirection.cs
│   │   ├── KaraokeSettingsSubsection.cs
│   │   ├── LyricPlayfield.cs
│   │   ├── NotePlayfield.cs
│   │   ├── PlayerSettings/
│   │   │   ├── ClickablePlayerSliderBar.cs
│   │   │   ├── ILyricNavigator.cs
│   │   │   ├── LyricsPreview.cs
│   │   │   ├── PitchSettings.cs
│   │   │   ├── PlaybackSettings.cs
│   │   │   ├── PlayerDropdown.cs
│   │   │   └── PracticeSettings.cs
│   │   ├── Position/
│   │   │   ├── INotePositionInfo.cs
│   │   │   ├── NotePositionCalculator.cs
│   │   │   └── NotePositionInfo.cs
│   │   └── Scrolling/
│   │       └── ScrollingNotePlayfield.cs
│   ├── Utils/
│   │   ├── ActivatorUtils.cs
│   │   ├── AssemblyUtils.cs
│   │   ├── BindablesUtils.cs
│   │   ├── CharUtils.cs
│   │   ├── ComparableUtils.cs
│   │   ├── CultureInfoUtils.cs
│   │   ├── EnumUtils.cs
│   │   ├── FontUsageUtils.cs
│   │   ├── FontUtils.cs
│   │   ├── JpStringUtils.cs
│   │   ├── RectangleFUtils.cs
│   │   ├── StackTraceUtils.cs
│   │   ├── TextIndexUtils.cs
│   │   ├── TypeUtils.cs
│   │   └── VersionUtils.cs
│   └── osu.Game.Rulesets.Karaoke.csproj
├── osu.Game.Rulesets.Karaoke.Architectures/
│   ├── BaseTest.cs
│   ├── Edit/
│   │   └── Checks/
│   │       ├── TestCheck.cs
│   │       └── TestCheckTest.cs
│   ├── Extensions.cs
│   ├── MethodUtils.cs
│   ├── Project.cs
│   ├── TestClass.cs
│   ├── TestTestClass.cs
│   └── osu.Game.Rulesets.Karaoke.Architectures.csproj
├── osu.Game.Rulesets.Karaoke.Tests/
│   ├── .vscode/
│   │   ├── launch.json
│   │   └── tasks.json
│   ├── Asserts/
│   │   ├── ObjectAssert.cs
│   │   ├── RubyTagAssert.cs
│   │   └── TimeTagAssert.cs
│   ├── Beatmaps/
│   │   ├── ElementIdTest.cs
│   │   ├── Formats/
│   │   │   ├── KaraokeLegacyBeatmapDecoderTest.cs
│   │   │   └── KaraokeLegacyBeatmapEncoderTest.cs
│   │   ├── KaraokeBeatmapConversionTest.cs
│   │   ├── Metadatas/
│   │   │   ├── PageInfoTest.cs
│   │   │   └── SingerInfoTest.cs
│   │   ├── TestKaraokeBeatmap.cs
│   │   └── Utils/
│   │       └── SingerUtilsTest.cs
│   ├── Bindables/
│   │   ├── BindableCultureInfoTest.cs
│   │   └── BindableFontUsageTest.cs
│   ├── Difficulty/
│   │   ├── DifficultyCalculatorTest.cs
│   │   └── KaraokeDifficultyCalculatorTest.cs
│   ├── Editor/
│   │   ├── ChangeHandlers/
│   │   │   ├── BaseChangeHandlerTest.cs
│   │   │   ├── BaseHitObjectChangeHandlerTest.cs
│   │   │   ├── BaseHitObjectPropertyChangeHandlerTest.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BeatmapPagesChangeHandlerTest.cs
│   │   │   │   ├── BeatmapSingersChangeHandlerTest.cs
│   │   │   │   └── BeatmapTranslationsChangeHandlerTest.cs
│   │   │   ├── ImportBeatmapChangeHandlerTest.cs
│   │   │   ├── LockChangeHandlerTest.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── LyricLanguageChangeHandlerTest.cs
│   │   │   │   ├── LyricPropertyAutoGenerateChangeHandlerTest.cs
│   │   │   │   ├── LyricPropertyChangeHandlerTest.cs
│   │   │   │   ├── LyricReferenceChangeHandlerTest.cs
│   │   │   │   ├── LyricRubyTagsChangeHandlerTest.cs
│   │   │   │   ├── LyricSingerChangeHandlerTest.cs
│   │   │   │   ├── LyricTextChangeHandlerTest.cs
│   │   │   │   ├── LyricTimeTagsChangeHandlerTest.cs
│   │   │   │   ├── LyricTranslationChangeHandlerTest.cs
│   │   │   │   └── LyricsChangeHandlerTest.cs
│   │   │   ├── Notes/
│   │   │   │   ├── NotePropertyChangeHandlerTest.cs
│   │   │   │   └── NotesChangeHandlerTest.cs
│   │   │   └── Stages/
│   │   │       ├── BaseStageInfoChangeHandlerTest.cs
│   │   │       ├── ClassicStageChangeHandlerTest.cs
│   │   │       ├── StageElementCategoryChangeHandlerTest.cs
│   │   │       └── StagesChangeHandlerTest.cs
│   │   ├── Checks/
│   │   │   ├── BaseCheckTest.cs
│   │   │   ├── BeatmapPropertyCheckTest.cs
│   │   │   ├── CheckBeatmapAvailableTranslationsTest.cs
│   │   │   ├── CheckBeatmapNoteInfoTest.cs
│   │   │   ├── CheckBeatmapPageInfoTest.cs
│   │   │   ├── CheckClassicStageInfoTest.cs
│   │   │   ├── CheckLyricLanguageTest.cs
│   │   │   ├── CheckLyricReferenceLyricTest.cs
│   │   │   ├── CheckLyricRubyTagTest.cs
│   │   │   ├── CheckLyricSingerTest.cs
│   │   │   ├── CheckLyricTextTest.cs
│   │   │   ├── CheckLyricTimeTagTest.cs
│   │   │   ├── CheckLyricTranslationsTest.cs
│   │   │   ├── CheckNoteReferenceLyricTest.cs
│   │   │   ├── CheckNoteTextTest.cs
│   │   │   ├── CheckNoteTimeTest.cs
│   │   │   ├── CheckStageInfoTest.cs
│   │   │   └── HitObjectCheckTest.cs
│   │   ├── Generator/
│   │   │   ├── BaseGeneratorSelectorTest.cs
│   │   │   ├── BasePropertyDetectorTest.cs
│   │   │   ├── BasePropertyGeneratorTest.cs
│   │   │   ├── Beatmaps/
│   │   │   │   ├── BaseBeatmapDetectorTest.cs
│   │   │   │   ├── BaseBeatmapGeneratorTest.cs
│   │   │   │   └── Pages/
│   │   │   │       └── PageGeneratorTest.cs
│   │   │   ├── GeneratorConfigExtensionTest.cs
│   │   │   ├── GeneratorConfigHelper.cs
│   │   │   ├── Lyrics/
│   │   │   │   ├── BaseLyricDetectorTest.cs
│   │   │   │   ├── BaseLyricGeneratorSelectorTest.cs
│   │   │   │   ├── BaseLyricGeneratorTest.cs
│   │   │   │   ├── Language/
│   │   │   │   │   └── LanguageDetectorTest.cs
│   │   │   │   ├── Notes/
│   │   │   │   │   └── NoteGeneratorTest.cs
│   │   │   │   ├── ReferenceLyric/
│   │   │   │   │   └── ReferenceLyricDetectorTest.cs
│   │   │   │   ├── Romanisation/
│   │   │   │   │   ├── BaseRomanisationGeneratorTest.cs
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   └── JaRomanisationGeneratorTest.cs
│   │   │   │   │   ├── RomanisationGenerateResultHelper.cs
│   │   │   │   │   └── RomanisationGeneratorSelectorTest.cs
│   │   │   │   ├── RubyTags/
│   │   │   │   │   ├── BaseRubyTagGeneratorTest.cs
│   │   │   │   │   ├── Ja/
│   │   │   │   │   │   └── JaRubyTagGeneratorTest.cs
│   │   │   │   │   └── RubyTagGeneratorSelectorTest.cs
│   │   │   │   └── TimeTags/
│   │   │   │       ├── BaseTimeTagGeneratorTest.cs
│   │   │   │       ├── Ja/
│   │   │   │       │   └── JaTimeTagGeneratorTest.cs
│   │   │   │       ├── TimeTagGeneratorSelectorTest.cs
│   │   │   │       └── Zh/
│   │   │   │           └── ZhTimeTagGeneratorTest.cs
│   │   │   └── Stages/
│   │   │       ├── BaseStageElementCategoryGeneratorTest.cs
│   │   │       ├── BaseStageInfoGeneratorTest.cs
│   │   │       ├── BaseStageInfoPropertyGeneratorTest.cs
│   │   │       ├── Classic/
│   │   │       │   ├── ClassicLyricLayoutCategoryGeneratorTest.cs
│   │   │       │   ├── ClassicLyricTimingInfoGeneratorTest.cs
│   │   │       │   └── ClassicStageInfoGeneratorTest.cs
│   │   │       ├── Preview/
│   │   │       │   └── PreviewStageInfoGeneratorTest.cs
│   │   │       └── StageInfoGeneratorSelectorTest.cs
│   │   ├── TestSceneEditor.cs
│   │   ├── TestSceneSetupScreen.cs
│   │   ├── TestSceneTimeTagTooltip.cs
│   │   └── Utils/
│   │       ├── HitObjectWritableUtilsTest.cs
│   │       ├── LockStateUtilsTest.cs
│   │       └── ValueChangedEventUtilsTest.cs
│   ├── Extensions/
│   │   ├── EnumerableExtensionsTest.cs
│   │   ├── PlayerTestSceneExtensions.cs
│   │   └── PrimaryKeyObjectExtension.cs
│   ├── Flags/
│   │   └── FlagStateTest.cs
│   ├── Graphics/
│   │   ├── Sprites/
│   │   │   ├── DisplayLyricProcessorTest.cs
│   │   │   └── Processor/
│   │   │       ├── DisplayProcessorTestScene.cs
│   │   │       ├── TestSceneLyricFirstDisplayProcessor.cs
│   │   │       └── TestSceneRomanisedSyllableFirstDisplayProcessor.cs
│   │   ├── TestSceneFontSelector.cs
│   │   ├── TestSceneLanguageSelector.cs
│   │   ├── TestSceneLyricTooltip.cs
│   │   ├── TestSceneRightTriangle.cs
│   │   └── TestSceneSingerToolTip.cs
│   ├── Helper/
│   │   ├── TestCaseCheckHelper.cs
│   │   ├── TestCaseElementIdHelper.cs
│   │   ├── TestCaseNoteHelper.cs
│   │   ├── TestCaseTagHelper.cs
│   │   └── TestCaseToneHelper.cs
│   ├── IO/
│   │   ├── Serialization/
│   │   │   ├── Converters/
│   │   │   │   ├── BaseSingleConverterTest.cs
│   │   │   │   ├── ColourConverterTest.cs
│   │   │   │   ├── CultureInfoConverterTest.cs
│   │   │   │   ├── ElementIdConverterTest.cs
│   │   │   │   ├── FontUsageConverterTest.cs
│   │   │   │   ├── KaraokeSkinElementConverterTest.cs
│   │   │   │   ├── LyricConverterTest.cs
│   │   │   │   ├── ReferenceLyricPropertyConfigConverterTest.cs
│   │   │   │   ├── RubyTagConverterTest.cs
│   │   │   │   ├── RubyTagsConverterTest.cs
│   │   │   │   ├── ShaderConverterTest.cs
│   │   │   │   ├── StageInfoConverterTest.cs
│   │   │   │   ├── TimeTagConverterTest.cs
│   │   │   │   ├── TimeTagsConverterTest.cs
│   │   │   │   ├── ToneConverterTest.cs
│   │   │   │   └── TranslationConverterTest.cs
│   │   │   ├── KaraokeJsonSerializableExtensionsTest.cs
│   │   │   └── SkinJsonSerializableExtensionsTest.cs
│   │   └── Stores/
│   │       ├── BaseGlyphStoreTest.cs
│   │       └── TtfGlyphStoreTest.cs
│   ├── Integration/
│   │   └── Formats/
│   │       ├── KarDecoderTest.cs
│   │       ├── KarEncoderTest.cs
│   │       ├── KarFileTest.cs
│   │       ├── LrcDecoderTest.cs
│   │       ├── LrcEncoderTest.cs
│   │       ├── LrcParserUtilsTest.cs
│   │       ├── LyricTextDecoderTest.cs
│   │       └── LyricTextEncoderTest.cs
│   ├── KaraokeTestBrowser.cs
│   ├── Mods/
│   │   ├── KaraokeModStageTestScene.cs
│   │   ├── KaraokeModTestScene.cs
│   │   ├── ModsTest.cs
│   │   ├── TestSceneKaraokeModAutoplay.cs
│   │   ├── TestSceneKaraokeModAutoplayBySinger.cs
│   │   ├── TestSceneKaraokeModClassicStage.cs
│   │   ├── TestSceneKaraokeModDisableNote.cs
│   │   ├── TestSceneKaraokeModFlashlight.cs
│   │   ├── TestSceneKaraokeModFun.cs
│   │   ├── TestSceneKaraokeModLyricConfiguration.cs
│   │   ├── TestSceneKaraokeModPerfect.cs
│   │   ├── TestSceneKaraokeModPractice.cs
│   │   ├── TestSceneKaraokeModPreviewStage.cs
│   │   ├── TestSceneKaraokeModSuddenDeath.cs
│   │   └── TestSceneKaraokeModTranslation.cs
│   ├── Objects/
│   │   ├── LyricTest.cs
│   │   ├── NoteTest.cs
│   │   ├── RubyTagTest.cs
│   │   ├── TimeTagTest.cs
│   │   ├── ToneCalculationTest.cs
│   │   ├── Utils/
│   │   │   ├── LyricUtilsTest.cs
│   │   │   ├── LyricsUtilsTest.cs
│   │   │   ├── NoteUtilsTest.cs
│   │   │   ├── NotesUtilsTest.cs
│   │   │   ├── OrderUtilsTest.cs
│   │   │   ├── RubyTagUtilsTest.cs
│   │   │   ├── RubyTagsUtilsTest.cs
│   │   │   ├── TimeTagUtilsTest.cs
│   │   │   └── TimeTagsUtilsTest.cs
│   │   └── Workings/
│   │       ├── HitObjectWorkingPropertyValidatorTest.cs
│   │       ├── LyricWorkingPropertyValidatorTest.cs
│   │       └── NoteWorkingPropertyValidatorTest.cs
│   ├── Overlays/
│   │   ├── Changelog/
│   │   │   ├── ChangelogPullRequestInfoTest.cs
│   │   │   ├── TestSceneKaraokeChangeLogMarkdownContainer.cs
│   │   │   └── TestSceneKaraokeChangeLogOverlay.cs
│   │   └── TestSceneOverlayColourProvider.cs
│   ├── Ranking/
│   │   ├── TestKaraokeScoreInfo.cs
│   │   ├── TestSceneBeatmapMetadataGraph.cs
│   │   ├── TestSceneHitEventTimingDistributionGraph.cs
│   │   ├── TestSceneNotScorableGraph.cs
│   │   ├── TestSceneScoringResultGraph.cs
│   │   └── TestSceneStatisticsPanel.cs
│   ├── Replays/
│   │   ├── TestSceneAutoGeneration.cs
│   │   └── TestSceneAutoGenerationBySinger.cs
│   ├── Resources/
│   │   ├── TestResources.cs
│   │   ├── Testing/
│   │   │   ├── Beatmaps/
│   │   │   │   ├── karaoke-file-samples-expected-conversion.json
│   │   │   │   ├── karaoke-file-samples-without-note.osu
│   │   │   │   ├── karaoke-file-samples.osu
│   │   │   │   ├── karaoke-note-samples.osu
│   │   │   │   └── karaoke-translation-samples.osu
│   │   │   ├── Fonts/
│   │   │   │   └── Fnt/
│   │   │   │       └── OpenSans/
│   │   │   │           └── LICENSE.txt
│   │   │   ├── Kar/
│   │   │   │   ├── default.kar
│   │   │   │   └── light.kar
│   │   │   └── Track/
│   │   │       └── demo.json
│   │   └── special-skin/
│   │       ├── default.json
│   │       ├── lyric-font-infos.json
│   │       └── note-styles.json
│   ├── Screens/
│   │   ├── Edit/
│   │   │   ├── Beatmap/
│   │   │   │   ├── BeatmapEditorScreenTestScene.cs
│   │   │   │   ├── Components/
│   │   │   │   │   └── TestSceneLyricSelector.cs
│   │   │   │   ├── Lyrics/
│   │   │   │   │   ├── CaretPosition/
│   │   │   │   │   │   ├── Algorithms/
│   │   │   │   │   │   │   ├── BaseCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── BaseCharIndexCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── BaseIndexCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── ClickingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CreateRemoveTimeTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CreateRubyTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── CuttingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── NavigateCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   ├── RecordingTimeTagCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   │   └── TypingCaretPositionAlgorithmTest.cs
│   │   │   │   │   │   └── IndexCaretPositionTest.cs
│   │   │   │   │   ├── Content/
│   │   │   │   │   │   ├── SingleLyricEditorTest.cs
│   │   │   │   │   │   ├── TestSceneInteractableLyric.cs
│   │   │   │   │   │   └── TestScenePreviewKaraokeSpriteText.cs
│   │   │   │   │   ├── LyricEditorTest.cs
│   │   │   │   │   ├── LyricEditorVerifierTest.cs
│   │   │   │   │   ├── Settings/
│   │   │   │   │   │   └── TestSceneLyricEditorDescriptionTextFlowContainer.cs
│   │   │   │   │   ├── States/
│   │   │   │   │   │   ├── BaseLyricCaretStateTest.cs
│   │   │   │   │   │   ├── LyricCaretStateActionTest.cs
│   │   │   │   │   │   ├── LyricCaretStateMoveCaretTest.cs
│   │   │   │   │   │   └── LyricCaretStateSwitchModeTest.cs
│   │   │   │   │   └── TestSceneLyricEditorColourProvider.cs
│   │   │   │   ├── TestSceneEditorMenuBar.cs
│   │   │   │   ├── TestSceneKaraokeBeatmapEditor.cs
│   │   │   │   ├── TestSceneLyricEditorScreen.cs
│   │   │   │   ├── TestScenePageScreen.cs
│   │   │   │   ├── TestSceneSingerScreen.cs
│   │   │   │   └── TestSceneTranslationsScreen.cs
│   │   │   ├── Components/
│   │   │   │   ├── Issues/
│   │   │   │   │   ├── TestSceneIssueIcon.cs
│   │   │   │   │   └── TestSceneIssuesToolTip.cs
│   │   │   │   └── Markdown/
│   │   │   │       └── TestSceneDescriptionTextFlowContainer.cs
│   │   │   ├── GenericEditorScreenTestScene.cs
│   │   │   ├── GenericEditorTestScene.cs
│   │   │   ├── Import/
│   │   │   │   └── TestSceneLyricImporter.cs
│   │   │   └── Stages/
│   │   │       └── Classic/
│   │   │           ├── ClassicStageScreenTestScene.cs
│   │   │           ├── TestSceneClassicStageEditor.cs
│   │   │           ├── TestSceneConfigScreen.cs
│   │   │           └── TestSceneStageScreen.cs
│   │   ├── ScreenTestScene.cs
│   │   ├── Settings/
│   │   │   ├── Previews/
│   │   │   │   └── TestSceneMicrophoneSoundVisualizer.cs
│   │   │   └── TestSceneKaraokeSettings.cs
│   │   ├── Skin/
│   │   │   ├── KaraokeSkinEditorScreenTestScene.cs
│   │   │   ├── TestSceneConfigScreen.cs
│   │   │   ├── TestSceneKaraokeSkinEditor.cs
│   │   │   └── TestSceneStyleScreen.cs
│   │   ├── TestManageFontPreview.cs
│   │   └── TestSceneGeneratorConfigPopover.cs
│   ├── Skinning/
│   │   ├── Fonts/
│   │   │   ├── BitmapFontCompressorTest.cs
│   │   │   └── BitmapFontImageGeneratorTest.cs
│   │   ├── KaraokeBeatmapSkinDecodingTest.cs
│   │   ├── KaraokeHitObjectTestScene.cs
│   │   ├── KaraokeSkinDecodingTest.cs
│   │   ├── KaraokeSkinnableColumnTestScene.cs
│   │   ├── KaraokeSkinnableTestScene.cs
│   │   ├── NotePlayfieldTestContainer.cs
│   │   ├── TestSceneColumnBackground.cs
│   │   ├── TestSceneDrawableJudgement.cs
│   │   ├── TestSceneHitExplosion.cs
│   │   ├── TestSceneLyric.cs
│   │   ├── TestSceneNote.cs
│   │   └── TestSceneNotePlayfield.cs
│   ├── Stages/
│   │   ├── Drawables/
│   │   │   └── TestSceneDrawableStageBeatmapCoverInfo.cs
│   │   └── Infos/
│   │       ├── Classic/
│   │       │   └── ClassicLyricTimingInfoTest.cs
│   │       ├── Preview/
│   │       │   └── PreviewStageTimingCalculatorTest.cs
│   │       └── StageElementCategoryTest.cs
│   ├── TestSceneOsuGame.cs
│   ├── UI/
│   │   ├── Position/
│   │   │   └── NotePositionCalculatorTest.cs
│   │   ├── TestSceneControlLayer.cs
│   │   ├── TestSceneKaraokePlayer.cs
│   │   ├── TestSceneNotePlayfield.cs
│   │   ├── TestSceneRulesetIcon.cs
│   │   └── TestSceneScoringStatus.cs
│   ├── Utils/
│   │   ├── BindablesUtilsTest.cs
│   │   ├── CharUtilsTest.cs
│   │   ├── ComparableUtilsTest.cs
│   │   ├── CultureInfoUtilsTest.cs
│   │   ├── EnumUtilsTest.cs
│   │   ├── FontUsageUtilsTest.cs
│   │   ├── FontUtilsTest.cs
│   │   ├── JpStringUtilsTest.cs
│   │   ├── RectangleFUtilsTest.cs
│   │   ├── TextIndexUtilsTest.cs
│   │   ├── TypeUtilsTest.cs
│   │   └── VersionUtilsTest.cs
│   ├── VisualTestRunner.cs
│   └── osu.Game.Rulesets.Karaoke.Tests.csproj
├── osu.Game.Rulesets.Karaoke.sln
├── osu.Game.Rulesets.Karaoke.sln.DotSettings
└── osu.licenseheader
Download .txt
Showing preview only (743K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6689 symbols across 1229 files)

FILE: osu.Game.Rulesets.Karaoke.Architectures/BaseTest.cs
  class BaseTest (line 12) | public abstract class BaseTest
    method SetUp (line 16) | [SetUp]
    method GetExecuteProject (line 24) | protected Project.ProjectAttribute GetExecuteProject()
    method GetProjectArchitecture (line 29) | protected Architecture GetProjectArchitecture(params Project.ProjectAt...
    method Assertion (line 44) | protected void Assertion(Action assert)

FILE: osu.Game.Rulesets.Karaoke.Architectures/Edit/Checks/TestCheck.cs
  class TestCheck (line 11) | public class TestCheck : BaseTest
    method CheckCheckClassNamingAndInherit (line 13) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Architectures/Edit/Checks/TestCheckTest.cs
  class TestCheckTest (line 13) | public class TestCheckTest : BaseTest
    method CheckShouldContainsTest (line 15) | [Test]
    method CheckTestClassAndMethod (line 49) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Architectures/Extensions.cs
  class Extensions (line 16) | public static class Extensions
    method GetAllTestClass (line 20) | public static IEnumerable<Class> GetAllTestClass(this Architecture arc...
    method GetInnerClasses (line 46) | public static IEnumerable<Class> GetInnerClasses(this Class @class)
    method GetAllTestMembers (line 54) | public static IEnumerable<IMember> GetAllTestMembers(this Class @class...
    method HasAttributeInSelfOrChild (line 61) | public static bool HasAttributeInSelfOrChild(this Class @class, Attrib...
    method GetGenericTypes (line 70) | public static IEnumerable<IType> GetGenericTypes(this Class @class)
    method RelativeNameStartsWith (line 80) | public static bool RelativeNameStartsWith(
    method RelativeNameMatches (line 94) | public static bool RelativeNameMatches(this IHasName cls,
    method getRelativeNamespace (line 111) | private static string getRelativeNamespace(Project.ProjectAttribute pr...
    method GetMethodMembersContainsName (line 130) | public static IEnumerable<MethodMember> GetMethodMembersContainsName(t...
    method WhereNameContains (line 135) | public static IEnumerable<TType> WhereNameContains<TType>(this IEnumer...

FILE: osu.Game.Rulesets.Karaoke.Architectures/MethodUtils.cs
  class MethodUtils (line 12) | public class MethodUtils
    method GetExecuteProject (line 14) | public static Project.ProjectAttribute GetExecuteProject()

FILE: osu.Game.Rulesets.Karaoke.Architectures/Project.cs
  class Project (line 10) | public class Project
    class KaraokeAttribute (line 12) | public sealed class KaraokeAttribute : ProjectAttribute
      method KaraokeAttribute (line 18) | public KaraokeAttribute(bool execute = false)
    class KaraokeTestAttribute (line 24) | public sealed class KaraokeTestAttribute : ProjectAttribute
      method KaraokeTestAttribute (line 30) | public KaraokeTestAttribute(bool execute = false)
    class OsuGameAttribute (line 36) | public sealed class OsuGameAttribute : ProjectAttribute
      method OsuGameAttribute (line 42) | public OsuGameAttribute(bool execute = false)
    class OsuFrameworkAttribute (line 48) | public sealed class OsuFrameworkAttribute : ProjectAttribute
      method OsuFrameworkAttribute (line 54) | public OsuFrameworkAttribute(bool execute = false)
    class ProjectAttribute (line 60) | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
      method ProjectAttribute (line 69) | protected ProjectAttribute(bool execute)
    type ExecuteType (line 75) | public enum ExecuteType

FILE: osu.Game.Rulesets.Karaoke.Architectures/TestClass.cs
  class TestClass (line 15) | public class TestClass : BaseTest
    method CheckAbstractClassLocation (line 17) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Architectures/TestTestClass.cs
  class TestTestClass (line 12) | public class TestTestClass : BaseTest
    method CheckTestClassAndMethodNaming (line 14) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Asserts/ObjectAssert.cs
  class ObjectAssert (line 14) | public class ObjectAssert : Assert
    method ArePropertyEqual (line 16) | public static void ArePropertyEqual<T>(T expected, T actual) where T :...
    class WritablePropertiesOnlyResolver (line 27) | private class WritablePropertiesOnlyResolver : DefaultContractResolver
      method CreateProperties (line 30) | protected override IList<JsonProperty> CreateProperties(Type type, M...

FILE: osu.Game.Rulesets.Karaoke.Tests/Asserts/RubyTagAssert.cs
  class RubyTagAssert (line 10) | public class RubyTagAssert : Assert
    method ArePropertyEqual (line 12) | public static void ArePropertyEqual(IList<RubyTag> expected, IList<Rub...
    method ArePropertyEqual (line 23) | public static void ArePropertyEqual(RubyTag expected, RubyTag actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Asserts/TimeTagAssert.cs
  class TimeTagAssert (line 10) | public class TimeTagAssert : Assert
    method ArePropertyEqual (line 12) | public static void ArePropertyEqual(IList<TimeTag> expected, IList<Tim...
    method ArePropertyEqual (line 22) | public static void ArePropertyEqual(TimeTag expect, TimeTag actually)

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/ElementIdTest.cs
  class ElementIdTest (line 11) | public class ElementIdTest
    method TestEmptyElementId (line 13) | [Test]
    method TestCreateElementId (line 26) | [TestCase("1234567", true)] // number is OK
    method TestNewElementIdShouldNotDuplicated (line 52) | [Test]
    method TestCompareTo (line 69) | [TestCase("1234567", "1234567", 0)]
    method TestCompareToOther (line 81) | [Test]
    method TestEqual (line 103) | [TestCase("1234567", "1234567", true)]
    method TestEqualWithEqualityComparer (line 114) | [TestCase("1234567", "1234567", true)]
    method TestEqualOperator (line 125) | [TestCase("1234567", "1234567", true)]
    method TestNotEqualOperator (line 136) | [TestCase("1234567", "1234567", false)]
    method TestToString (line 147) | [TestCase("1234567", "1234567")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/KaraokeLegacyBeatmapDecoderTest.cs
  class KaraokeLegacyBeatmapDecoderTest (line 20) | [TestFixture]
    method KaraokeLegacyBeatmapDecoderTest (line 23) | public KaraokeLegacyBeatmapDecoderTest()
    method TestDecodeBeatmapLyric (line 29) | [Test]
    method TestDecodeNotes (line 62) | [Test]
    method TestDecodeTranslations (line 78) | [Test]
    method decodeBeatmap (line 109) | private static KaraokeBeatmap decodeBeatmap(string fileName)
    method testNote (line 124) | private static void testNote(string expectedText, int expectedTone, bo...
    method TestSliceNoteTime (line 131) | [TestCase(0, 1, new double[] { 1000, 3000 })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Formats/KaraokeLegacyBeatmapEncoderTest.cs
  class KaraokeLegacyBeatmapEncoderTest (line 15) | [TestFixture]
    method TestEncodeBeatmapLyric (line 18) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/KaraokeBeatmapConversionTest.cs
  class KaraokeBeatmapConversionTest (line 15) | [TestFixture]
    method KaraokeBeatmapConversionTest (line 20) | public KaraokeBeatmapConversionTest()
    method Test (line 26) | [Ignore("Fix this test case after.")]
    method CreateConvertValue (line 30) | protected override IEnumerable<ConvertValue> CreateConvertValue(HitObj...
    method CreateRuleset (line 48) | protected override Ruleset CreateRuleset() => new KaraokeRuleset();
  type ConvertValue (line 51) | public struct ConvertValue : IEquatable<ConvertValue>
    method Equals (line 62) | public bool Equals(ConvertValue other)

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Metadatas/PageInfoTest.cs
  class PageInfoTest (line 11) | public class PageInfoTest
    method TestGetPageAt (line 13) | [TestCase(new double[] { 1000, 2000, 3000, 4000 }, 999, null)]
    method TestGetPageIndexAt (line 33) | [TestCase(new double[] { 1000, 2000, 3000, 4000 }, 999, null)]
    method TestGetPageOrder (line 53) | [Test]
    method createPages (line 68) | private static IEnumerable<Page> createPages(IEnumerable<double> times)

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Metadatas/SingerInfoTest.cs
  class SingerInfoTest (line 11) | public class SingerInfoTest
    method TestSingers (line 13) | [Test]
    method TestGetAllSingers (line 26) | [Test]
    method TestGetAllAvailableSingerState (line 38) | [Test]
    method TestGetSingerByIds (line 50) | [Test]
    method TestGetSingerMap (line 75) | [Test]
    method TestAddSinger (line 88) | [Test]
    method TestAddSingerState (line 98) | [Test]
    method TestRemoveSinger (line 111) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/TestKaraokeBeatmap.cs
  class TestKaraokeBeatmap (line 12) | public class TestKaraokeBeatmap : Beatmap
    method TestKaraokeBeatmap (line 14) | public TestKaraokeBeatmap(RulesetInfo ruleset)
    method createTestBeatmap (line 30) | private static Beatmap createTestBeatmap()

FILE: osu.Game.Rulesets.Karaoke.Tests/Beatmaps/Utils/SingerUtilsTest.cs
  class SingerUtilsTest (line 9) | [TestFixture]
    method TestGetShiftingStyleIndex (line 12) | [TestCase(new int[] { }, 0)]
    method TestGetSingersIndex (line 22) | [TestCase(-1, new int[] { })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Bindables/BindableCultureInfoTest.cs
  class BindableCultureInfoTest (line 10) | public class BindableCultureInfoTest
    method TestParsingString (line 12) | [TestCase("ar", 1)]
    method TestParsingNumber (line 25) | [TestCase(1, 1)]
    method TestParsingCultureInfo (line 38) | [TestCase(1, 1)]
    method TestParsingNotSupportedCultureInfo (line 51) | [TestCase("中文(简体)")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Bindables/BindableFontUsageTest.cs
  class BindableFontUsageTest (line 11) | public class BindableFontUsageTest
    method TestParsingString (line 13) | [TestCase("family=f weight=w size=10 italics=true fixedWidth=true", "f...

FILE: osu.Game.Rulesets.Karaoke.Tests/Difficulty/DifficultyCalculatorTest.cs
  class DifficultyCalculatorTest (line 21) | [TestFixture]
    method Test (line 28) | protected void Test(double expectedStarRating, int expectedMaxCombo, s...
    method getBeatmap (line 37) | private IWorkingBeatmap getBeatmap(string name)
    method openResource (line 56) | private Stream openResource(string name)
    method CreateDifficultyCalculator (line 62) | protected abstract DifficultyCalculator CreateDifficultyCalculator(IWo...
    method CreateRuleset (line 64) | protected abstract Ruleset CreateRuleset();

FILE: osu.Game.Rulesets.Karaoke.Tests/Difficulty/KaraokeDifficultyCalculatorTest.cs
  class KaraokeDifficultyCalculatorTest (line 12) | [TestFixture]
    method KaraokeDifficultyCalculatorTest (line 15) | public KaraokeDifficultyCalculatorTest()
    method Test (line 23) | [TestCase(1.7535600395779332d, 936, "karaoke-file-samples")]
    method CreateDifficultyCalculator (line 28) | protected override DifficultyCalculator CreateDifficultyCalculator(IWo...
    method CreateRuleset (line 30) | protected override Ruleset CreateRuleset() => new KaraokeRuleset();

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseChangeHandlerTest.cs
  class BaseChangeHandlerTest (line 25) | [HeadlessTest]
    method load (line 32) | [BackgroundDependencyLoader]
    method CreateChangeHandler (line 58) | protected virtual TChangeHandler CreateChangeHandler()
    method SetUp (line 61) | [SetUp]
    method CreateChildDependencies (line 78) | protected override IReadOnlyDependencyContainer CreateChildDependencie...
    method SetUpEditorBeatmap (line 90) | protected virtual void SetUpEditorBeatmap(Action<EditorBeatmap> action)
    method SetUpKaraokeBeatmap (line 99) | protected virtual void SetUpKaraokeBeatmap(Action<KaraokeBeatmap> action)
    method TriggerHandlerChanged (line 108) | protected void TriggerHandlerChanged(Action<TChangeHandler> c)
    method TriggerHandlerChangedWithException (line 118) | protected void TriggerHandlerChangedWithException<T>(Action<TChangeHan...
    method AssertEditorBeatmap (line 126) | protected void AssertEditorBeatmap(Action<EditorBeatmap> assert)
    method AssertKaraokeBeatmap (line 137) | protected void AssertKaraokeBeatmap(Action<KaraokeBeatmap> assert)
    method PrepareHitObject (line 146) | protected void PrepareHitObject(Func<HitObject> hitObject, bool select...
    method PrepareHitObjects (line 149) | protected void PrepareHitObjects(Func<IEnumerable<HitObject>> selected...
    method AssertHitObject (line 165) | protected void AssertHitObject<THitObject>(Action<THitObject> assert) ...
    method AssertHitObjects (line 176) | protected void AssertHitObjects<THitObject>(Action<IEnumerable<THitObj...
    method AssertStatus (line 187) | protected void AssertStatus()
    method AssertTransactionOnlyTriggerOnce (line 199) | protected void AssertTransactionOnlyTriggerOnce()
    method AssertWorkingPropertyInHitObjectValid (line 207) | protected void AssertWorkingPropertyInHitObjectValid()
    class MockEditorChangeHandler (line 223) | private partial class MockEditorChangeHandler : TransactionalCommitCom...
      method MockEditorChangeHandler (line 227) | public MockEditorChangeHandler(EditorBeatmap editorBeatmap)
      method RestoreState (line 234) | public void RestoreState(int direction)
      method UpdateState (line 238) | protected override void UpdateState()

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseHitObjectChangeHandlerTest.cs
  class BaseHitObjectChangeHandlerTest (line 14) | public abstract partial class BaseHitObjectChangeHandlerTest<TChangeHand...
    method AssertHitObject (line 17) | protected void AssertHitObject(Action<THitObject> assert)
    method AssertHitObjects (line 22) | protected void AssertHitObjects(Action<IEnumerable<THitObject>> assert)
    method AssertSelectedHitObject (line 27) | protected void AssertSelectedHitObject(Action<THitObject> assert)
    method AssertSelectedHitObjects (line 38) | protected void AssertSelectedHitObjects(Action<IEnumerable<THitObject>...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/BaseHitObjectPropertyChangeHandlerTest.cs
  class BaseHitObjectPropertyChangeHandlerTest (line 9) | public abstract partial class BaseHitObjectPropertyChangeHandlerTest<TCh...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Beatmaps/BeatmapPagesChangeHandlerTest.cs
  class BeatmapPagesChangeHandlerTest (line 15) | public partial class BeatmapPagesChangeHandlerTest : BaseChangeHandlerTe...
    method TestGeneratePage (line 19) | [Test]
    method TestGeneratePageWithInvalidCase (line 36) | [Test]
    method TestAdd (line 45) | [Test]
    method TestRemove (line 63) | [Test]
    method TestRemoveRange (line 89) | [Test]
    method TestShiftingPageTime (line 115) | [Test]
    method SetUpKaraokeBeatmap (line 140) | protected override void SetUpKaraokeBeatmap(Action<KaraokeBeatmap> act...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Beatmaps/BeatmapSingersChangeHandlerTest.cs
  class BeatmapSingersChangeHandlerTest (line 15) | public partial class BeatmapSingersChangeHandlerTest : BaseChangeHandler...
    method TestChangeOrder (line 17) | [Test]
    method TestChangeSingerAvatar (line 44) | [Test]
    method TestAdd (line 50) | [Test]
    method TestRemove (line 75) | [Test]
    method SetUpKaraokeBeatmap (line 112) | protected override void SetUpKaraokeBeatmap(Action<KaraokeBeatmap> act...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Beatmaps/BeatmapTranslationsChangeHandlerTest.cs
  class BeatmapTranslationsChangeHandlerTest (line 14) | public partial class BeatmapTranslationsChangeHandlerTest : BaseChangeHa...
    method TestAdd (line 16) | [Test]
    method TestRemove (line 40) | [Test]
    method TestIsLanguageContainsTranslation (line 64) | [Test]
    method SetUpKaraokeBeatmap (line 93) | protected override void SetUpKaraokeBeatmap(Action<KaraokeBeatmap> act...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/ImportBeatmapChangeHandlerTest.cs
  class ImportBeatmapChangeHandlerTest (line 12) | public partial class ImportBeatmapChangeHandlerTest : BaseChangeHandlerT...
    method TestImport (line 14) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/LockChangeHandlerTest.cs
  class LockChangeHandlerTest (line 12) | public partial class LockChangeHandlerTest : BaseHitObjectPropertyChange...
    method TestLock (line 14) | [Test]
    method TestUnlock (line 40) | [Test]
    method TestLockToReferenceLyric (line 66) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricLanguageChangeHandlerTest.cs
  class LyricLanguageChangeHandlerTest (line 12) | public partial class LyricLanguageChangeHandlerTest : LyricPropertyChang...
    method TestSetLanguageToJapanese (line 14) | [Test]
    method TestSetLanguageToNull (line 28) | [Test]
    method TestSetLanguageWithReferenceLyric (line 44) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandlerTest.cs
  class LyricPropertyAutoGenerateChangeHandlerTest (line 26) | public partial class LyricPropertyAutoGenerateChangeHandlerTest : LyricP...
    method TestDetectReferenceLyric (line 32) | [Test]
    method TestDetectReferenceLyricWithNonSupportedLyric (line 54) | [Test]
    method TestDetectLanguage (line 74) | [Test]
    method TestDetectLanguageWithNonSupportedLyric (line 90) | [Test]
    method TestAutoGenerateRubyTags (line 110) | [Test]
    method TestAutoGenerateRubyTagsWithNonSupportedLyric (line 129) | [Test]
    method TestAutoGenerateTimeTags (line 156) | [Test]
    method TestAutoGenerateTimeTagsWithNonSupportedLyric (line 173) | [Test]
    method TestAutoGenerateRomanisation (line 200) | [Test]
    method TestAutoGenerateRomanisationWithNonSupportedLyric (line 218) | [Test]
    method TestAutoGenerateNotes (line 238) | [Test]
    method TestAutoGenerateNotesWithNonSupportedLyric (line 267) | [Test]
    method getMatchedNotes (line 278) | private Note[] getMatchedNotes(Lyric lyric)
    method TestChangeWithNormalLyric (line 288) | [Test]
    method TestChangeWithMissingPropertyLyric (line 331) | [Test]
    method TestCheckWithReferencedLyric (line 354) | [Test]
    method isLyricReferenceChangeHandler (line 392) | private bool isLyricReferenceChangeHandler(AutoGenerateType type)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricPropertyChangeHandlerTest.cs
  class LyricPropertyChangeHandlerTest (line 10) | public abstract partial class LyricPropertyChangeHandlerTest<TChangeHand...
    method PrepareLyricWithSyncConfig (line 13) | protected Lyric PrepareLyricWithSyncConfig(Lyric referencedLyric, IRef...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricReferenceChangeHandlerTest.cs
  class LyricReferenceChangeHandlerTest (line 11) | public partial class LyricReferenceChangeHandlerTest : LyricPropertyChan...
    method TestUpdateReferenceLyric (line 13) | [Test]
    method TestSwitchToReferenceLyricConfig (line 37) | [Test]
    method TestSwitchToSyncLyricConfig (line 61) | [Test]
    method TestAdjustLyricConfig (line 85) | [Test]
    method TestWithReferenceLyric (line 115) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricRubyTagsChangeHandlerTest.cs
  class LyricRubyTagsChangeHandlerTest (line 13) | public partial class LyricRubyTagsChangeHandlerTest : LyricPropertyChang...
    method TestAdd (line 15) | [Test]
    method TestAddRange (line 39) | [Test]
    method TestRemove (line 66) | [Test]
    method TestRemoveRange (line 94) | [Test]
    method TestSetIndex (line 128) | [Test]
    method TestShiftingIndex (line 157) | [Test]
    method TestSetText (line 186) | [Test]
    method TestWithReferenceLyric (line 214) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricSingerChangeHandlerTest.cs
  class LyricSingerChangeHandlerTest (line 14) | public partial class LyricSingerChangeHandlerTest : LyricPropertyChangeH...
    method TestAdd (line 16) | [Test]
    method TestAddRange (line 39) | [Test]
    method TestRemove (line 62) | [Test]
    method TestRemoveRange (line 102) | [Test]
    method TestClear (line 142) | [Test]
    method TestWithReferenceLyric (line 169) | [TestCase(true)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricTextChangeHandlerTest.cs
  class LyricTextChangeHandlerTest (line 11) | public partial class LyricTextChangeHandlerTest : LyricPropertyChangeHan...
    method TestInsertText (line 13) | [Test]
    method TestDeleteLyricText (line 29) | [Test]
    method TestDeleteAllLyricText (line 45) | [Test]
    method TestWithReferenceLyric (line 58) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandlerTest.cs
  class LyricTimeTagsChangeHandlerTest (line 17) | public partial class LyricTimeTagsChangeHandlerTest : LyricPropertyChang...
    method TestSetTimeTagTime (line 19) | [Test]
    method TestSetTimeTagFirstSyllable (line 40) | [Test]
    method TestSetTimeTagRomanisedSyllable (line 61) | [Test]
    method TestShiftingTimeTagTime (line 89) | [Test]
    method TestClearTimeTagTime (line 123) | [Test]
    method TestClearAllTimeTagTime (line 144) | [Test]
    method TestAdd (line 166) | [Test]
    method TestAddRange (line 183) | [Test]
    method TestRemove (line 200) | [Test]
    method TestRemoveRange (line 222) | [Test]
    method TestAddByPosition (line 244) | [Test]
    method TestRemoveByPosition (line 264) | [Test]
    method TestRemoveByPositionCase2 (line 291) | [Test]
    method TestShifting (line 317) | [TestCase(ShiftingDirection.Left, ShiftingType.Index, 1)]
    method TestShiftingToFirst (line 349) | [TestCase(ShiftingDirection.Left, ShiftingType.Index, 0)]
    method TestShiftingToLast (line 378) | [TestCase(ShiftingDirection.Left, ShiftingType.Index, 1)]
    method TestShiftingWithNoDuplicatedTimeTag (line 407) | [TestCase(ShiftingDirection.Left, ShiftingType.Index, 1)]
    method TestShiftingWithOneTimeTag (line 437) | [TestCase(ShiftingDirection.Left, ShiftingType.Index, 0)]
    method TestShiftingWithSameTimeTag (line 465) | [Ignore("Will be implement if it will increase better UX.")]
    method TestShiftingException (line 496) | [TestCase(TextIndex.IndexState.Start, ShiftingDirection.Left, Shifting...
    method TestWithReferenceLyric (line 525) | [TestCase(true)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricTranslationChangeHandlerTest.cs
  class LyricTranslationChangeHandlerTest (line 13) | public partial class LyricTranslationChangeHandlerTest : LyricPropertyCh...
    method TestUpdateTranslationWithNewLanguage (line 15) | [Test]
    method TestUpdateTranslationWithExistLanguage (line 32) | [Test]
    method TestUpdateTranslationWithEmptyText (line 53) | [Test]
    method TestUpdateTranslationWithNullText (line 73) | [Test]
    method TestWithReferenceLyric (line 93) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Lyrics/LyricsChangeHandlerTest.cs
  class LyricsChangeHandlerTest (line 11) | public partial class LyricsChangeHandlerTest : BaseHitObjectChangeHandle...
    method TestSplit (line 13) | [Test]
    method TestCombine (line 39) | [Test]
    method TestCreateAtPosition (line 75) | [Test]
    method TestCreateAtLast (line 108) | [Test]
    method TestCreateAtLastWithEmptyBeatmap (line 141) | [Test]
    method TestAddBelowToSelection (line 156) | [Test]
    method TestAddRangeBelowToSelection (line 186) | [Test]
    method TestRemove (line 219) | [Test]
    method TestChangeOrder (line 246) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Notes/NotePropertyChangeHandlerTest.cs
  class NotePropertyChangeHandlerTest (line 16) | public partial class NotePropertyChangeHandlerTest : BaseHitObjectProper...
    method TestChangeText (line 20) | [Test]
    method TestChangeRubyText (line 37) | [Test]
    method TestChangeDisplayStateToVisible (line 54) | [Test]
    method TestChangeDisplayStateToNonVisible (line 70) | [Test]
    method TestWithReferenceLyric (line 89) | [Test]
    method TestOffsetTone (line 106) | [Test]
    method TestOffsetToneWithZeroValue (line 125) | [Test]
    method SetUpEditorBeatmap (line 139) | protected override void SetUpEditorBeatmap(Action<EditorBeatmap> action)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Notes/NotesChangeHandlerTest.cs
  class NotesChangeHandlerTest (line 12) | public partial class NotesChangeHandlerTest : BaseHitObjectChangeHandler...
    method TestSplit (line 14) | [Test]
    method TestCombine (line 44) | [Test]
    method TestClear (line 85) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Stages/BaseStageInfoChangeHandlerTest.cs
  class BaseStageInfoChangeHandlerTest (line 11) | public abstract partial class BaseStageInfoChangeHandlerTest<TChangeHand...
    method SetUpStageInfo (line 14) | protected virtual void SetUpStageInfo<TStageInfo>(Action<TStageInfo>? ...
    method AssertStageInfos (line 17) | public void AssertStageInfos(Action<IList<StageInfo>> assert)
    method AssertStageInfo (line 20) | public void AssertStageInfo<TStageInfo>(Action<TStageInfo> assert) whe...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Stages/ClassicStageChangeHandlerTest.cs
  class ClassicStageChangeHandlerTest (line 12) | [Ignore("Ignore all stage-related change handler test until able to edit...
    method TestEditLayoutDefinition (line 17) | [Test]
    method TestAddTimingPoint (line 43) | [Test]
    method TestRemoveTimingPoint (line 67) | [Test]
    method TestRemoveRangeOfTimingPoints (line 102) | [Test]
    method TestShiftingTimingPoints (line 137) | [Test]
    method TestAddLyricIntoTimingPoint (line 174) | [Test]
    method TestRemoveLyricFromTimingPoint (line 209) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Stages/StageElementCategoryChangeHandlerTest.cs
  class StageElementCategoryChangeHandlerTest (line 18) | [Ignore("Ignore all stage-related change handler test until able to edit...
    method CreateChangeHandler (line 21) | protected override TestStageElementCategoryChangeHandler CreateChangeH...
    method TestAddElement (line 24) | [Test]
    method TestEditElement (line 44) | [Test]
    method TestRemoveElement (line 72) | [Test]
    method TestAddToMapping (line 96) | [Test]
    method TestRemoveFromMapping (line 122) | [Test]
    method TestClearUnusedMapping (line 151) | [Test]
    class TestStageElementCategoryChangeHandler (line 176) | public partial class TestStageElementCategoryChangeHandler : StageElem...
      method TestStageElementCategoryChangeHandler (line 178) | public TestStageElementCategoryChangeHandler(Func<IEnumerable<StageI...
    class TestStageInfo (line 184) | private class TestStageInfo : StageInfo
      method GetLyricStageElements (line 197) | protected override IEnumerable<StageElement> GetLyricStageElements(L...
      method GetNoteStageElements (line 202) | protected override IEnumerable<StageElement> GetNoteStageElements(No...
      method CreatePlayfieldCommandProvider (line 211) | public override IPlayfieldCommandProvider CreatePlayfieldCommandProv...
      method CreateStageElementProvider (line 214) | public override IStageElementProvider? CreateStageElementProvider(bo...
      method CreateHitObjectCommandProvider (line 217) | public override IHitObjectCommandProvider? CreateHitObjectCommandPro...
    class TestCategory (line 228) | private class TestCategory : StageElementCategory<TestStageElement, Ly...
      method CreateDefaultElement (line 230) | protected override TestStageElement CreateDefaultElement()
    class TestStageElement (line 234) | public class TestStageElement : StageElement, IComparable<TestStageEle...
      method CompareTo (line 236) | public int CompareTo(TestStageElement? other)
    class TestCommandProvider (line 244) | private class TestCommandProvider : HitObjectCommandProvider<TestStage...
      method TestCommandProvider (line 246) | public TestCommandProvider(TestStageInfo stageInfo)
      method GeneratePreemptTime (line 251) | protected override double GeneratePreemptTime(Lyric hitObject)
      method GetStartAndEndTime (line 254) | protected override Tuple<double?, double?> GetStartAndEndTime(Lyric ...
      method GetInitialCommands (line 262) | protected override IEnumerable<IStageCommand> GetInitialCommands(Lyr...
      method GetStartTimeStateCommands (line 267) | protected override IEnumerable<IStageCommand> GetStartTimeStateComma...
      method GetHitStateCommands (line 272) | protected override IEnumerable<IStageCommand> GetHitStateCommands(Ly...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/ChangeHandlers/Stages/StagesChangeHandlerTest.cs
  class StagesChangeHandlerTest (line 12) | [Ignore("Ignore all stage-related change handler test until able to edit...
    method TestAutoGenerate (line 17) | [Test]
    method TestRemove (line 41) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/BaseCheckTest.cs
  class BaseCheckTest (line 12) | public abstract class BaseCheckTest<TCheck> where TCheck : class, ICheck...
    method Setup (line 16) | [SetUp]
    method AssertOk (line 26) | protected void AssertOk(BeatmapVerifierContext context)
    method AssertNotOk (line 31) | protected void AssertNotOk<TIssueTemplate>(BeatmapVerifierContext cont...
    method AssertNotOk (line 37) | protected void AssertNotOk<TIssue, TIssueTemplate>(BeatmapVerifierCont...
    method Run (line 51) | protected IEnumerable<Issue> Run(BeatmapVerifierContext context)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/BeatmapPropertyCheckTest.cs
  class BeatmapPropertyCheckTest (line 8) | public abstract class BeatmapPropertyCheckTest<TCheck> : BaseCheckTest<T...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckBeatmapAvailableTranslationsTest.cs
  class CheckBeatmapAvailableTranslationsTest (line 19) | [TestFixture]
    method TestNoLyricAndNoLanguage (line 22) | [Test]
    method TestNoLyricButHaveLanguage (line 31) | [Test]
    method TestHaveLyricButNoLanguage (line 41) | [Test]
    method TestEveryLyricContainsTranslation (line 51) | [Test]
    method TestCheckMissingTranslation (line 64) | [Test]
    method TestCheckMissingPartialTranslation (line 93) | [Test]
    method TestCheckTranslationNotInListedLanguage (line 106) | [Test]
    method createTestingBeatmap (line 117) | private static IBeatmap createTestingBeatmap(List<CultureInfo>? transl...
    method getContext (line 131) | private static BeatmapVerifierContext getContext(IBeatmap beatmap)
    method createLyric (line 134) | private static Lyric createLyric(CultureInfo? cultureInfo = null, stri...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckBeatmapNoteInfoTest.cs
  class CheckBeatmapNoteInfoTest (line 21) | public class CheckBeatmapNoteInfoTest : BeatmapPropertyCheckTest<CheckBe...
    method TestCheckColumnNotEnough (line 23) | [Test]
    method TestCheckColumnExceed (line 30) | [Test]
    method TestCheckNoteToneTooLow (line 37) | [Test]
    method TestCheckNoteToneTooHigh (line 50) | [Test]
    method createTestingBeatmap (line 63) | private static IBeatmap createTestingBeatmap(Action<NoteInfo> action, ...
    method getContext (line 79) | private static BeatmapVerifierContext getContext(IBeatmap beatmap)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckBeatmapPageInfoTest.cs
  class CheckBeatmapPageInfoTest (line 21) | public class CheckBeatmapPageInfoTest : BeatmapPropertyCheckTest<CheckBe...
    method TestCheckLessThanTwoPages (line 23) | [Test]
    method TestCheckPageIntervalTooShort (line 53) | [Test]
    method TestCheckPageIntervalTooLong (line 84) | [Test]
    method TestCheckPageIntervalShouldHaveAtLeastOneLyric (line 115) | [Test]
    method TestCheckLyricNotWrapIntoTime (line 134) | [Test]
    method createTestingBeatmap (line 186) | private static IBeatmap createTestingBeatmap(IEnumerable<Page>? pages,...
    method getContext (line 200) | private static BeatmapVerifierContext getContext(IBeatmap beatmap)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckClassicStageInfoTest.cs
  class CheckClassicStageInfoTest (line 22) | [Ignore("Disable this test until able to get the stage info from the res...
    method TestCheckInvalidRowHeight (line 27) | [Test]
    method TestCheckLessThanTwoTimingPoints (line 49) | [Test]
    method TestCheckTimingIntervalTooShort (line 78) | [Test]
    method TestCheckTimingIntervalTooLong (line 91) | [Test]
    method TestCheckTimingInfoHitObjectNotExist (line 104) | [TestCase(true)]
    method TestCheckTimingInfoMappingHasNoTiming (line 128) | [Test]
    method TestCheckTimingInfoTimingNotExist (line 149) | [Test]
    method TestCheckTimingInfoLyricNotHaveTwoTiming (line 170) | [Test]
    method TestCheckLyricLayoutInvalidLineNumber (line 196) | [Test]
    method createTestingBeatmap (line 218) | private static IBeatmap createTestingBeatmap(IEnumerable<Lyric>? lyrics)
    method createTestingStageInfo (line 231) | private static StageInfo createTestingStageInfo(Action<ClassicLyricTim...
    method createTestingStageInfo (line 241) | private static StageInfo createTestingStageInfo(Action<ClassicStageInf...
    method getContext (line 259) | private static BeatmapVerifierContext getContext(IBeatmap beatmap, Sta...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricLanguageTest.cs
  class CheckLyricLanguageTest (line 13) | public class CheckLyricLanguageTest : HitObjectCheckTest<Lyric, CheckLyr...
    method TestCheck (line 15) | [TestCase("Ja-jp")]
    method TestCheckNotFill (line 27) | [TestCase(null)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricReferenceLyricTest.cs
  class CheckLyricReferenceLyricTest (line 14) | public class CheckLyricReferenceLyricTest : HitObjectCheckTest<Lyric, Ch...
    method TestCheck (line 16) | [Test]
    method TestCheckSelfReference (line 30) | [Test]
    method TestCheckInvalidReferenceLyric (line 44) | [Test]
    method TestCheckNullReferenceLyricConfig (line 58) | [Test]
    method TestCheckHasReferenceLyricConfigWhenNoReferenceLyric (line 71) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricRubyTagTest.cs
  class CheckLyricRubyTagTest (line 13) | public class CheckLyricRubyTagTest : HitObjectCheckTest<Lyric, CheckLyri...
    method TestCheck (line 15) | [TestCase("カラオケ", new[] { "[0]:か", "[1]:ら", "[2]:お", "[3]:け" })]
    method TestCheckOutOfRange (line 28) | [TestCase("カラオケ", new[] { "[-1]:か" })]
    method TestCheckOverlapping (line 41) | [TestCase("カラオケ", new[] { "[0]:か", "[0]:ら" })]
    method TestCheckEmptyText (line 54) | [TestCase("カラオケ", new[] { "[0,3]:" })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricSingerTest.cs
  class CheckLyricSingerTest (line 13) | [TestFixture]
    method TestCheck (line 16) | [TestCase(new[] { 1, 2, 3 })]
    method TestCheckNoSinger (line 29) | [TestCase(new int[] { })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricTextTest.cs
  class CheckLyricTextTest (line 12) | [TestFixture]
    method TestCheck (line 15) | [TestCase("karaoke")]
    method TestCheckEmptyText (line 28) | [TestCase(" ")] // but should not be empty or white space.

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricTimeTagTest.cs
  class CheckLyricTimeTagTest (line 14) | public class CheckLyricTimeTagTest : HitObjectCheckTest<Lyric, CheckLyri...
    method TestCheck (line 16) | [TestCase("カラオケ", new[] { "[0,start]:1000", "[1,start]:2000", "[2,star...
    method TestCheckEmpty (line 30) | [TestCase("カラオケ", new string[] { })]
    method TestCheckMissingStart (line 42) | [TestCase("カラオケ", new[] { "[3,end]:5000" })]
    method TestCheckMissingEnd (line 54) | [TestCase("カラオケ", new[] { "[0,start]:5000" })]
    method TestCheckOutOfRange (line 66) | [TestCase("カラオケ", new[] { "[-1,start]:0", "[0,start]:1000", "[3,end]:1...
    method TestCheckOverlapping (line 79) | [TestCase("カラオケ", new[] { "[0,start]:5000", "[3,end]:1000" })]
    method TestCheckEmptyTime (line 91) | [TestCase("カラオケ", new[] { "[0,start]", "[3,end]:1000" })] // empty sta...
    method TestCheckInvalidRomanisedSyllable (line 105) | [TestCase("カラオケ", "")] // should not be empty.
    method TestCheckShouldFillRomanisedSyllable (line 130) | [TestCase("カラオケ", null)] // should not be white-space only.
    method TestCheckShouldNotFillRomanisedSyllable (line 154) | [TestCase("カラオケ", "")] // should not have empty text if end.
    method TestCheckShouldNotMarkFirstSyllable (line 179) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckLyricTranslationsTest.cs
  class CheckLyricTranslationsTest (line 14) | public class CheckLyricTranslationsTest : HitObjectCheckTest<Lyric, Chec...
    method TestCheck (line 16) | [TestCase("translation")]
    method TestCheckEmptyText (line 32) | [TestCase(null)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckNoteReferenceLyricTest.cs
  class CheckNoteReferenceLyricTest (line 14) | [TestFixture]
    method TestCheck (line 17) | [TestCase(0, new[] { "[0,start]:1000", "[3,end]:5000" })]
    method TestCheckNullReferenceLyric (line 39) | [Test]
    method TestCheckInvalidReferenceLyric (line 51) | [Test]
    method TestCheckMissingReferenceTimeTag (line 69) | [TestCase(2, new[] { "[0,start]:1000", "[3,end]:5000" })] // will find...
    method TestCheckMissingStartReferenceTimeTag (line 91) | [TestCase(-1, new[] { "[0,start]:1000", "[3,end]:5000" })]
    method TestCheckStartReferenceTimeTagMissingTime (line 110) | [TestCase(0, new[] { "[0,start]", "[3,end]:5000" })]
    method TestCheckMissingEndReferenceTimeTag (line 130) | [TestCase(1, new[] { "[0,start]:1000", "[3,end]:5000" })]
    method TestCheckEndReferenceTimeTagMissingTime (line 149) | [TestCase(0, new[] { "[0,start]:1000", "[3,end]" })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckNoteTextTest.cs
  class CheckNoteTextTest (line 13) | public class CheckNoteTextTest : HitObjectCheckTest<Note, CheckNoteText>
    method TestCheck (line 15) | [Test]
    method TestCheckEmptyText (line 27) | [TestCase(null)]
    method TestCheckEmptyRubyText (line 41) | [TestCase("")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckNoteTimeTest.cs
  class CheckNoteTimeTest (line 14) | public class CheckNoteTimeTest : HitObjectCheckTest<Note, CheckNoteTime>
    method TestCheck (line 16) | [TestCase(0, new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:30...
    method TestCheckWithNoReferenceLyric (line 35) | [Test]
    method TestCheckMissingStartOrEndTimeTag (line 49) | [TestCase(3, new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:30...
    method TestCheckInvalidReferenceTimeTagTime (line 69) | [TestCase("[0,start]:2000", "[1,start]:1000")]
    method TestCheckDurationTooShort (line 91) | [TestCase("[0,start]", "[1,start]")]
    method TestCheckDurationTooLong (line 113) | [TestCase("[0,start]", "[1,start]")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/CheckStageInfoTest.cs
  class CheckStageInfoTest (line 22) | [Ignore("Disable this test until able to get the stage info from the res...
    method TestCheckNoElement (line 25) | [Test]
    method TestCheckMappingHitObjectNotExist (line 33) | [Test]
    method TestCheckMappingItemNotExist (line 52) | [Test]
    class CheckStageInfo (line 70) | public class CheckStageInfo : CheckStageInfo<ClassicStageInfo>
      method CheckStageInfo (line 74) | public CheckStageInfo()
      method CheckStageInfoWithHitObjects (line 83) | public override IEnumerable<Issue> CheckStageInfoWithHitObjects(Clas...
      method CheckElement (line 88) | protected override IEnumerable<Issue> CheckElement<TStageElement>(TS...
    method createTestingBeatmap (line 94) | private static IBeatmap createTestingBeatmap(IEnumerable<Lyric>? lyrics)
    method createTestingStageInfo (line 107) | private static StageInfo createTestingStageInfo(Action<ClassicLyricLay...
    method getContext (line 115) | private static BeatmapVerifierContext getContext(IBeatmap beatmap, Sta...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Checks/HitObjectCheckTest.cs
  class HitObjectCheckTest (line 14) | public abstract class HitObjectCheckTest<THitObject, TCheck> : BaseCheck...
    method AssertOk (line 16) | protected void AssertOk(HitObject hitObject)
    method AssertOk (line 21) | protected void AssertOk(IEnumerable<HitObject> hitObjects)
    method AssertNotOk (line 26) | protected void AssertNotOk<TIssue, TIssueTemplate>(HitObject hitObject)
    method AssertNotOk (line 33) | protected void AssertNotOk<TIssue, TIssueTemplate>(IEnumerable<HitObje...
    method getContext (line 40) | private BeatmapVerifierContext getContext(IEnumerable<HitObject> hitOb...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/BaseGeneratorSelectorTest.cs
  class BaseGeneratorSelectorTest (line 10) | public abstract class BaseGeneratorSelectorTest<TGenerator, TItem, TProp...
    method CreateSelector (line 14) | protected TGenerator CreateSelector()

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/BasePropertyDetectorTest.cs
  class BasePropertyDetectorTest (line 11) | public abstract class BasePropertyDetectorTest<TDetector, TItem, TProper...
    method GeneratorEmptyConfig (line 16) | protected static TConfig GeneratorEmptyConfig(Action<TConfig>? action ...
    method GeneratorDefaultConfig (line 25) | protected static TConfig GeneratorDefaultConfig(Action<TConfig>? actio...
    method CheckCanDetect (line 33) | protected static void CheckCanDetect(TItem item, bool canDetect, TConf...
    method CheckDetectResult (line 40) | protected void CheckDetectResult(TItem item, TProperty expected, TConf...
    method CheckCanDetect (line 51) | protected static void CheckCanDetect(TItem item, bool canDetect, TDete...
    method CheckDetectResult (line 57) | protected void CheckDetectResult(TItem item, TProperty expected, TDete...
    method AssertEqual (line 64) | protected abstract void AssertEqual(TProperty expected, TProperty actu...
  class BasePropertyDetectorTest (line 48) | public abstract class BasePropertyDetectorTest<TDetector, TItem, TProperty>
    method GeneratorEmptyConfig (line 16) | protected static TConfig GeneratorEmptyConfig(Action<TConfig>? action ...
    method GeneratorDefaultConfig (line 25) | protected static TConfig GeneratorDefaultConfig(Action<TConfig>? actio...
    method CheckCanDetect (line 33) | protected static void CheckCanDetect(TItem item, bool canDetect, TConf...
    method CheckDetectResult (line 40) | protected void CheckDetectResult(TItem item, TProperty expected, TConf...
    method CheckCanDetect (line 51) | protected static void CheckCanDetect(TItem item, bool canDetect, TDete...
    method CheckDetectResult (line 57) | protected void CheckDetectResult(TItem item, TProperty expected, TDete...
    method AssertEqual (line 64) | protected abstract void AssertEqual(TProperty expected, TProperty actu...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/BasePropertyGeneratorTest.cs
  class BasePropertyGeneratorTest (line 11) | public abstract class BasePropertyGeneratorTest<TGenerator, TItem, TProp...
    method GeneratorEmptyConfig (line 16) | protected static TConfig GeneratorEmptyConfig(Action<TConfig>? action ...
    method GeneratorDefaultConfig (line 25) | protected static TConfig GeneratorDefaultConfig(Action<TConfig>? actio...
    method CheckCanGenerate (line 33) | protected static void CheckCanGenerate(TItem item, bool canGenerate, T...
    method CheckGenerateResult (line 40) | protected void CheckGenerateResult(TItem item, TProperty expected, TCo...
    method CheckCanGenerate (line 51) | protected static void CheckCanGenerate(TItem item, bool canGenerate, T...
    method CheckGenerateResult (line 57) | protected void CheckGenerateResult(TItem item, TProperty expected, TGe...
    method AssertEqual (line 64) | protected abstract void AssertEqual(TProperty expected, TProperty actu...
  class BasePropertyGeneratorTest (line 48) | public abstract class BasePropertyGeneratorTest<TGenerator, TItem, TProp...
    method GeneratorEmptyConfig (line 16) | protected static TConfig GeneratorEmptyConfig(Action<TConfig>? action ...
    method GeneratorDefaultConfig (line 25) | protected static TConfig GeneratorDefaultConfig(Action<TConfig>? actio...
    method CheckCanGenerate (line 33) | protected static void CheckCanGenerate(TItem item, bool canGenerate, T...
    method CheckGenerateResult (line 40) | protected void CheckGenerateResult(TItem item, TProperty expected, TCo...
    method CheckCanGenerate (line 51) | protected static void CheckCanGenerate(TItem item, bool canGenerate, T...
    method CheckGenerateResult (line 57) | protected void CheckGenerateResult(TItem item, TProperty expected, TGe...
    method AssertEqual (line 64) | protected abstract void AssertEqual(TProperty expected, TProperty actu...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/BaseBeatmapDetectorTest.cs
  class BaseBeatmapDetectorTest (line 10) | public abstract class BaseBeatmapDetectorTest<TDetector, TObject, TConfig>

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/BaseBeatmapGeneratorTest.cs
  class BaseBeatmapGeneratorTest (line 10) | public abstract class BaseBeatmapGeneratorTest<TGenerator, TObject, TCon...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Beatmaps/Pages/PageGeneratorTest.cs
  class PageGeneratorTest (line 16) | [TestFixture]
    method TestCanGenerate (line 22) | [TestCase(new[] { "[1000,3000]:karaoke" }, true)]
    method TestGenerateWithSingleLyric (line 38) | [TestCase("[1000,3000]:karaoke", new double[] { 1000, 3000 })]
    method TestGenerateWithTwoLyrics (line 59) | [TestCase("[1000,4000]:karaoke", "[4000,7000]:karaoke", new double[] {...
    method TestGenerateWithSingleLyricWithPage (line 84) | [Ignore("Waiting for implementation.")]
    method TestGenerateWithTwoLyricsWithPage (line 89) | [Ignore("Waiting for implementation.")]
    method AssertEqual (line 94) | protected override void AssertEqual(Page[] expected, Page[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/GeneratorConfigExtensionTest.cs
  class GeneratorConfigExtensionTest (line 14) | public class GeneratorConfigExtensionTest
    method TestGetOrderedConfigsSourceDictionary (line 16) | [Test]
    method TestGetOrderedConfigsSourceProperties (line 27) | [Test]
    method TestGetConfigSourceProperties (line 41) | [Test]
    class TestGeneratorConfig (line 59) | private class TestGeneratorConfig : GeneratorConfig

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/GeneratorConfigHelper.cs
  class GeneratorConfigHelper (line 13) | public class GeneratorConfigHelper
    method ClearValue (line 15) | public static void ClearValue(GeneratorConfig config)
    method getAllBindableProperty (line 27) | private static IEnumerable<PropertyInfo> getAllBindableProperty(Genera...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/BaseLyricDetectorTest.cs
  class BaseLyricDetectorTest (line 10) | public abstract class BaseLyricDetectorTest<TDetector, TObject, TConfig>

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/BaseLyricGeneratorSelectorTest.cs
  class BaseLyricGeneratorSelectorTest (line 9) | public abstract class BaseLyricGeneratorSelectorTest<TGenerator, TProperty>

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/BaseLyricGeneratorTest.cs
  class BaseLyricGeneratorTest (line 10) | public abstract class BaseLyricGeneratorTest<TGenerator, TObject, TConfig>

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Language/LanguageDetectorTest.cs
  class LanguageDetectorTest (line 11) | [TestFixture]
    method TestCanDetect (line 14) | [TestCase("花火大会", true)]
    method TestDetect (line 25) | [TestCase("花火大会", "zh-CN")]
    method AssertEqual (line 38) | protected override void AssertEqual(CultureInfo? expected, CultureInfo...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Notes/NoteGeneratorTest.cs
  class NoteGeneratorTest (line 12) | [TestFixture]
    method TestCanGenerate (line 15) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestGenerate (line 34) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestGenerateWithRuby (line 50) | [TestCase(new string[] { }, new[] { "カ", "ラ", "オ", "ケ" })]
    method AssertEqual (line 81) | protected override void AssertEqual(Note[] expected, Note[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/ReferenceLyric/ReferenceLyricDetectorTest.cs
  class ReferenceLyricDetectorTest (line 11) | [TestFixture]
    method TestCanDetect (line 14) | [TestCase("karaoke", "karaoke", true)]
    method TestCanDetectWithIgnorePrefixAndPostfixSymbol (line 37) | [TestCase("karaoke", "karaoke", true)]
    method TestDetect (line 67) | [TestCase("karaoke", "karaoke", true)]
    method AssertEqual (line 88) | protected override void AssertEqual(Lyric? expected, Lyric? actual)
    method CheckCanDetect (line 95) | protected static void CheckCanDetect(IEnumerable<Lyric> lyrics, Lyric ...
    method CheckDetectResult (line 102) | protected void CheckDetectResult(IEnumerable<Lyric> lyrics, Lyric lyri...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Romanisation/BaseRomanisationGeneratorTest.cs
  class BaseRomanisationGeneratorTest (line 13) | public abstract class BaseRomanisationGeneratorTest<TRomanisationGenerat...
    method CheckGenerateResult (line 16) | protected void CheckGenerateResult(Lyric lyric, string[] expectedRubie...
    method AssertEqual (line 22) | protected override void AssertEqual(IReadOnlyDictionary<TimeTag, Roman...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Romanisation/Ja/JaRomanisationGeneratorTest.cs
  class JaRomanisationGeneratorTest (line 13) | public class JaRomanisationGeneratorTest : BaseRomanisationGeneratorTest...
    method TestCanGenerate (line 15) | [TestCase("花火大会", new[] { "[0,start]", "[3,end]" }, true)]
    method TestGenerate (line 37) | [TestCase("はなび", new[] { "[0,start]" }, new[] { "^hana bi" })]
    method TestGenerateWithUppercase (line 57) | [TestCase("はなび", new[] { "[0,start]" }, new[] { "^HANA BI" })]
    method TestConvertToRomanisationGenerateResult (line 73) | [TestCase("花", new[] { "[0,start]", "[0,end]" }, new[] { "[0]:hana" },...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Romanisation/RomanisationGenerateResultHelper.cs
  class RomanisationGenerateResultHelper (line 12) | public class RomanisationGenerateResultHelper
    method ParseRomanisationGenerateResult (line 24) | public static KeyValuePair<TimeTag, RomanisationGenerateResult> ParseR...
    method ParseRomanisationGenerateResults (line 35) | public static IReadOnlyDictionary<TimeTag, RomanisationGenerateResult>...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/Romanisation/RomanisationGeneratorSelectorTest.cs
  class RomanisationGeneratorSelectorTest (line 16) | public class RomanisationGeneratorSelectorTest : BaseLyricGeneratorSelec...
    method TestCanGenerate (line 18) | [TestCase(17, "花火大会", true)]
    method TestGenerate (line 40) | [TestCase(17, "はなび", new[] { "[0,start]" }, new[] { "^hana bi" })] // ...
    method AssertEqual (line 58) | protected override void AssertEqual(IReadOnlyDictionary<TimeTag, Roman...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/RubyTags/BaseRubyTagGeneratorTest.cs
  class BaseRubyTagGeneratorTest (line 11) | public abstract class BaseRubyTagGeneratorTest<TRubyTagGenerator, TConfi...
    method CheckCanGenerate (line 14) | protected static void CheckCanGenerate(string text, bool canGenerate, ...
    method CheckGenerateResult (line 20) | protected void CheckGenerateResult(string text, string[] expectedRubie...
    method AssertEqual (line 27) | protected override void AssertEqual(RubyTag[] expected, RubyTag[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/RubyTags/Ja/JaRubyTagGeneratorTest.cs
  class JaRubyTagGeneratorTest (line 9) | [TestFixture]
    method TestCanGenerate (line 12) | [TestCase("花火大会", true)]
    method TestGenerate (line 22) | [TestCase("花火大会", new[] { "[0,1]:はなび", "[2,3]:たいかい" })]
    method TestGenerateWithRubyAsKatakana (line 30) | [TestCase("花火大会", new[] { "[0,1]:ハナビ", "[2,3]:タイカイ" })]
    method TestGenerateWithEnableDuplicatedRuby (line 38) | [TestCase("はなび", new[] { "[0,1]:はな", "[2]:び" })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/RubyTags/RubyTagGeneratorSelectorTest.cs
  class RubyTagGeneratorSelectorTest (line 13) | public class RubyTagGeneratorSelectorTest : BaseLyricGeneratorSelectorTe...
    method TestCanGenerate (line 15) | [TestCase(17, "花火大会", true)]
    method TestGenerate (line 33) | [TestCase(17, "花火大会", new[] { "[0,1]:はなび", "[2,3]:たいかい" })] // Japanese
    method AssertEqual (line 48) | protected override void AssertEqual(RubyTag[] expected, RubyTag[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/TimeTags/BaseTimeTagGeneratorTest.cs
  class BaseTimeTagGeneratorTest (line 11) | public abstract class BaseTimeTagGeneratorTest<TTimeTagGenerator, TConfi...
    method CheckCanGenerate (line 14) | protected static void CheckCanGenerate(string text, bool canGenerate, ...
    method CheckGenerateResult (line 20) | protected void CheckGenerateResult(string text, string[] expectedTimeT...
    method CheckGenerateResult (line 27) | protected void CheckGenerateResult(Lyric lyric, string[] expectedTimeT...
    method AssertEqual (line 33) | protected override void AssertEqual(TimeTag[] expected, TimeTag[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/TimeTags/Ja/JaTimeTagGeneratorTest.cs
  class JaTimeTagGeneratorTest (line 10) | [TestFixture]
    method TestCanGenerate (line 13) | [TestCase("花火大会", true)]
    method TestGenerateWithCheckWhiteCheckん (line 24) | [TestCase("がんばって", new[] { "[0,start]", "[2,start]", "[4,start]" }, fa...
    method TestGenerateWithCheckっ (line 32) | [TestCase("買って", new[] { "[0,start]", "[2,start]" }, false)]
    method TestGenerateWithCheckBlankLine (line 40) | [TestCase(" ", new string[] { }, false)]
    method TestGenerateWithCheckLineEndKeyUp (line 48) | [TestCase("か", new[] { "[0,start]" }, false)]
    method TestGenerateWithCheckWhiteSpace (line 56) | [TestCase("か     ", new[] { "[0,start]", "[1,start]", "[2,start]", "[3...
    method TestGenerateWithCheckWhiteSpaceKeyUp (line 64) | [TestCase("か ", new[] { "[0,start]", "[1,start]" }, false)]
    method TestGenerateWithCheckWhiteSpaceAlphabet (line 76) | [TestCase("a b c", new[] { "[0,start]", "[2,start]", "[4,start]" }, fa...
    method TestGenerateWithCheckWhiteSpaceDigit (line 93) | [TestCase("0 1 2", new[] { "[0,start]", "[2,start]", "[4,start]" }, fa...
    method TestGenerateWitCheckWhiteSpaceAsciiSymbol (line 110) | [TestCase("! ! !", new[] { "[0,start]", "[2,start]", "[4,start]" }, fa...
    method TestGenerateWithRubyLyric (line 124) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/TimeTags/TimeTagGeneratorSelectorTest.cs
  class TimeTagGeneratorSelectorTest (line 13) | public class TimeTagGeneratorSelectorTest : BaseLyricGeneratorSelectorTe...
    method TestCanGenerate (line 15) | [TestCase(17, "花火大会", true)]
    method TestGenerate (line 33) | [TestCase(17, "か", new[] { "[0,start]", "[0,end]" })] // Japanese
    method AssertEqual (line 49) | protected override void AssertEqual(TimeTag[] expected, TimeTag[] actual)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Lyrics/TimeTags/Zh/ZhTimeTagGeneratorTest.cs
  class ZhTimeTagGeneratorTest (line 9) | [TestFixture]
    method TestCanGenerate (line 12) | [TestCase("拉拉拉~~~", true)]
    method TestGenerateWithCheckLineEndKeyUp (line 23) | [TestCase("測試一些歌詞", new[] { "[0,start]", "[1,start]", "[2,start]", "[3...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/BaseStageElementCategoryGeneratorTest.cs
  class BaseLyricStageElementCategoryGeneratorTest (line 13) | public abstract class BaseLyricStageElementCategoryGeneratorTest<TGenera...
  class BaseStageElementCategoryGeneratorTest (line 20) | public abstract class BaseStageElementCategoryGeneratorTest<TGenerator, ...
    method AssertEqual (line 28) | protected sealed override void AssertEqual(TObject expected, TObject a...
    method AssertEqual (line 43) | protected abstract void AssertEqual(TStageElement expected, TStageElem...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/BaseStageInfoGeneratorTest.cs
  class BaseStageInfoGeneratorTest (line 11) | public abstract class BaseStageInfoGeneratorTest<TGenerator, TStageInfo,...
    method AssertEqual (line 17) | protected sealed override void AssertEqual(StageInfo expected, StageIn...
    method AssertEqual (line 28) | protected abstract void AssertEqual(TStageInfo expected, TStageInfo ac...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/BaseStageInfoPropertyGeneratorTest.cs
  class BaseStageInfoPropertyGeneratorTest (line 10) | public abstract class BaseStageInfoPropertyGeneratorTest<TGenerator, TOb...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/Classic/ClassicLyricLayoutCategoryGeneratorTest.cs
  class ClassicLyricLayoutCategoryGeneratorTest (line 14) | public class ClassicLyricLayoutCategoryGeneratorTest
    method TestCanGenerate (line 17) | [Test]
    method TestCanGenerateWithNonLyricBeatmap (line 35) | [Test]
    method TestGenerate (line 43) | [Test]
    method TestGenerateWithThreeLyrics (line 74) | [Test]
    method TestGenerateWithNotMapping (line 109) | [Test]
    method AssertEqual (line 136) | protected override void AssertEqual(ClassicLyricLayout expected, Class...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/Classic/ClassicLyricTimingInfoGeneratorTest.cs
  class ClassicLyricTimingInfoGeneratorTest (line 15) | public class ClassicLyricTimingInfoGeneratorTest
    method TestCanGenerate (line 18) | [Test]
    method TestCanGenerateWithNonLyricBeatmap (line 36) | [Test]
    method TestGenerate (line 44) | [Test]
    method TestGenerateWithThreeLyrics (line 84) | [Test]
    method AssertEqual (line 128) | protected override void AssertEqual(ClassicLyricTimingInfo expected, C...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/Classic/ClassicStageInfoGeneratorTest.cs
  class ClassicStageInfoGeneratorTest (line 14) | public class ClassicStageInfoGeneratorTest : BaseStageInfoGeneratorTest<...
    method TestCanGenerate (line 16) | [Test]
    method TestCanGenerateWithNonLyricBeatmap (line 34) | [Test]
    method TestGenerate (line 42) | [Test]
    method AssertEqual (line 67) | protected override void AssertEqual(ClassicStageInfo expected, Classic...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/Preview/PreviewStageInfoGeneratorTest.cs
  class PreviewStageInfoGeneratorTest (line 14) | public class PreviewStageInfoGeneratorTest : BaseStageInfoGeneratorTest<...
    method TestCanGenerate (line 16) | [Test]
    method TestCanGenerateWithNonLyricBeatmap (line 34) | [Test]
    method TestGenerate (line 44) | [Test]
    method AssertEqual (line 69) | protected override void AssertEqual(PreviewStageInfo expected, Preview...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Generator/Stages/StageInfoGeneratorSelectorTest.cs
  class StageInfoGeneratorSelectorTest (line 16) | [TestFixture(typeof(ClassicStageInfo))]
    method TestCanGenerate (line 21) | [Test]
    method TestGenerate (line 30) | [Test]
    method AssertEqual (line 40) | protected override void AssertEqual(StageInfo expected, StageInfo actual)
    method createBeatmap (line 47) | private KaraokeBeatmap createBeatmap()

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/TestSceneEditor.cs
  class TestSceneEditor (line 11) | [TestFixture]
    method CreateBeatmap (line 14) | protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new ...
    method CreateEditorRuleset (line 16) | protected override Ruleset CreateEditorRuleset() => new KaraokeRuleset();

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/TestSceneSetupScreen.cs
  class TestSceneSetupScreen (line 16) | [TestFixture]
    method TestKaraoke (line 32) | [Test]
    method runForRuleset (line 35) | private void runForRuleset(RulesetInfo rulesetInfo)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/TestSceneTimeTagTooltip.cs
  class TestSceneTimeTagTooltip (line 13) | [TestFixture]
    method SetUp (line 18) | [SetUp]
    method TestDisplayToolTip (line 29) | [Test]
    method setTooltip (line 37) | private void setTooltip(string testName, TimeTag timeTag)

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Utils/HitObjectWritableUtilsTest.cs
  class HitObjectWritableUtilsTest (line 15) | public class HitObjectWritableUtilsTest
    method TestIsRemoveLyricLocked (line 19) | [Test]
    method TestIsWriteLyricPropertyLocked (line 56) | [Test]
    method TestIsCreateOrRemoveNoteLocked (line 96) | [Test]
    method TestIsWriteNotePropertyLocked (line 133) | [Test]
    method testEveryWritablePropertiesInObjectAtTheSameTime (line 159) | private static void testEveryWritablePropertiesInObjectAtTheSameTime<T...
    method testEveryWritablePropertiesInObject (line 171) | private static void testEveryWritablePropertiesInObject<THitObject>(TH...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Utils/LockStateUtilsTest.cs
  class LockStateUtilsTest (line 12) | public class LockStateUtilsTest
    method TestFindUnlockObjects (line 14) | [TestCase(new[] { LockState.Full, LockState.Partial, LockState.None },...

FILE: osu.Game.Rulesets.Karaoke.Tests/Editor/Utils/ValueChangedEventUtilsTest.cs
  class ValueChangedEventUtilsTest (line 14) | public class ValueChangedEventUtilsTest
    method TestLyricChangedWithSameLyric (line 16) | [Test]
    method TestLyricChangedWithDifferentLyric (line 30) | [Test]
    method TestLyricChangedWithSameLyricButDifferentCaretPosition (line 49) | [Test]
    method TestEditModeChangedWithDefaultValue (line 63) | [Test]
    method TestEditModeChanged (line 75) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Extensions/EnumerableExtensionsTest.cs
  class EnumerableExtensionsTest (line 9) | public class EnumerableExtensionsTest
    method TestGetNextMatch (line 11) | [TestCase(new[] { 1, 2, 3, 4, 5, 6 }, 1, 3, 3)]
    method TestGetPreviousMatch (line 21) | [TestCase(new[] { 1, 2, 3, 4, 5, 6 }, 6, 3, 3)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Extensions/PlayerTestSceneExtensions.cs
  class PlayerTestSceneExtensions (line 10) | public static class PlayerTestSceneExtensions
    method GetDrawableRuleset (line 12) | public static DrawableKaraokeRuleset? GetDrawableRuleset(this TestPlay...
    method GetPlayfield (line 17) | public static KaraokePlayfield? GetPlayfield(this TestPlayer testPlayer)
    method GetNotePlayfield (line 22) | public static Playfield? GetNotePlayfield(this TestPlayer testPlayer)
    method GetLyricPlayfield (line 27) | public static Playfield? GetLyricPlayfield(this TestPlayer testPlayer)

FILE: osu.Game.Rulesets.Karaoke.Tests/Extensions/PrimaryKeyObjectExtension.cs
  class PrimaryKeyObjectExtension (line 9) | public static class PrimaryKeyObjectExtension
    method ChangeId (line 11) | public static TObject ChangeId<TObject>(this TObject obj, int id)

FILE: osu.Game.Rulesets.Karaoke.Tests/Flags/FlagStateTest.cs
  class FlagStateTest (line 11) | public class FlagStateTest
    method TestInvalidate (line 13) | [TestCase(default, new[] { TestEnum.Enum0, TestEnum.Enum1, TestEnum.En...
    method TestInvalidateAll (line 39) | [TestCase(TestEnum.Enum0)]
    method TestValidate (line 55) | [TestCase(default, new TestEnum[] { })]
    method TestValidateAll (line 81) | [TestCase(TestEnum.Enum0)]
    method TestIsValid (line 96) | [TestCase(TestEnum.Enum0, TestEnum.Enum0, true)]
    method TestGetAllValidFlags (line 114) | [Test]
    method TestGetAllInvalidFlags (line 128) | [Test]
    method TestGetAllValidFlagsWithAndCondition (line 142) | [Test]
    method TestGetAllInvalidFlagsWithAndCondition (line 159) | [Test]
    type TestEnum (line 175) | [Flags]
    type TestAndEnum (line 185) | [Flags]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/Sprites/DisplayLyricProcessorTest.cs
  class DisplayLyricProcessorTest (line 10) | public class DisplayLyricProcessorTest
    method Setup (line 21) | [SetUp]
    method TestTextChanged (line 62) | [Test]
    method TestSwitchDisplayType (line 75) | [Test]
    method TestSwitchDisplayProperty (line 88) | [Test]
    method TearDown (line 101) | [TearDown]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/Sprites/Processor/DisplayProcessorTestScene.cs
  class DisplayProcessorTestScene (line 29) | public abstract partial class DisplayProcessorTestScene : OsuGridTestScene
    method DisplayProcessorTestScene (line 48) | protected DisplayProcessorTestScene()
    method TestDisplayProperty (line 65) | [Test]
    method Initialize (line 119) | protected void Initialize(LyricDisplayProperty displayProperty = Lyric...
    method Initialize (line 124) | protected void Initialize(Func<Lyric> createLyricFunc, LyricDisplayPro...
    method createSampleSpriteText (line 171) | private void createSampleSpriteText(Lyric lyric, LyricDisplayType disp...
    method TriggerChange (line 220) | protected void TriggerChange(Action<Lyric> targetLyric)
    method AssertTopTextChanged (line 234) | protected void AssertTopTextChanged(IEnumerable<PositionText> expected...
    method AssertTopTextChanged (line 240) | protected void AssertTopTextChanged()
    method AssertTopTextNotChanged (line 245) | protected void AssertTopTextNotChanged()
    method AssertCenterTextChanged (line 250) | protected void AssertCenterTextChanged(string expectedValue)
    method AssertCenterTextChanged (line 256) | protected void AssertCenterTextChanged()
    method AssertCenterTextNotChanged (line 261) | protected void AssertCenterTextNotChanged()
    method AssertBottomTextChanged (line 266) | protected void AssertBottomTextChanged(IEnumerable<PositionText> expec...
    method AssertBottomTextChanged (line 272) | protected void AssertBottomTextChanged()
    method AssertBottomTextNotChanged (line 277) | protected void AssertBottomTextNotChanged()
    method AssertTimeTagsChanged (line 282) | protected void AssertTimeTagsChanged(Dictionary<double, TextIndex> exp...
    method AssertTimeTagsChanged (line 288) | protected void AssertTimeTagsChanged()
    method AssertTimeTagsNotChanged (line 293) | protected void AssertTimeTagsNotChanged()

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/Sprites/Processor/TestSceneLyricFirstDisplayProcessor.cs
  class TestSceneLyricFirstDisplayProcessor (line 14) | public partial class TestSceneLyricFirstDisplayProcessor : DisplayProces...
    method TestTextChanged (line 20) | [Test]
    method TestRubiesChanged (line 35) | [Test]
    method TestTimeTagsChanged (line 60) | [Test]
    method TestRubiesChangedWithEmptyText (line 94) | [Test]
    method TestTimeTagsChangedWithEmptyText (line 117) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/Sprites/Processor/TestSceneRomanisedSyllableFirstDisplayProcessor.cs
  class TestSceneRomanisedSyllableFirstDisplayProcessor (line 14) | public partial class TestSceneRomanisedSyllableFirstDisplayProcessor : D...
    method TestTextChanged (line 20) | [Test]
    method TestRubiesChanged (line 39) | [Test]
    method TestTimeTagsChanged (line 60) | [Test]
    method TestTextChangedWithNoTimeTags (line 82) | [Test]
    method TestRubiesChangedWithNoTimeTags (line 98) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneFontSelector.cs
  class TestSceneFontSelector (line 16) | public partial class TestSceneFontSelector : OsuManualInputManagerTestScene
    method load (line 22) | [BackgroundDependencyLoader]
    method TestAllFiles (line 34) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneLanguageSelector.cs
  class TestSceneLanguageSelector (line 14) | public partial class TestSceneLanguageSelector : OsuManualInputManagerTe...
    method TestAllLanguages (line 16) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneLyricTooltip.cs
  class TestSceneLyricTooltip (line 14) | [TestFixture]
    method SetUp (line 19) | [SetUp]
    method TestDisplayToolTip (line 30) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneRightTriangle.cs
  class TestSceneRightTriangle (line 17) | public partial class TestSceneRightTriangle : OsuTestScene
    method load (line 21) | [BackgroundDependencyLoader]
    method TestRightAngleDirections (line 45) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Graphics/TestSceneSingerToolTip.cs
  class TestSceneSingerToolTip (line 13) | [TestFixture]
    method SetUp (line 18) | [SetUp]
    method TestDisplayToolTip (line 29) | [Test]
    method setTooltip (line 69) | private void setTooltip(string testName, Action<Singer> callBack)

FILE: osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseCheckHelper.cs
  class TestCaseCheckHelper (line 19) | public class TestCaseCheckHelper
    method GetAllAvailableChecks (line 21) | public static IEnumerable<ICheck> GetAllAvailableChecks()
    method GetAllAvailableIssueTemplates (line 31) | public static IReadOnlyDictionary<ICheck, IEnumerable<IssueTemplate>> ...
    method CreateAllAvailableIssues (line 36) | public static IReadOnlyDictionary<ICheck, Issue[]> CreateAllAvailableI...

FILE: osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseElementIdHelper.cs
  class TestCaseElementIdHelper (line 10) | public static class TestCaseElementIdHelper
    method CreateElementIdByNumber (line 24) | public static ElementId CreateElementIdByNumber(int number)
    method CreateElementIdsByNumbers (line 31) | public static ElementId[] CreateElementIdsByNumbers(IEnumerable<int> ids)

FILE: osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseNoteHelper.cs
  class TestCaseNoteHelper (line 11) | public static class TestCaseNoteHelper
    method CreateLyricForNote (line 13) | public static Lyric CreateLyricForNote(int id, string text, double sta...

FILE: osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs
  class TestCaseTagHelper (line 18) | public static class TestCaseTagHelper
    method getStringPropertyRegex (line 25) | private static string getStringPropertyRegex(char prefix, string prope...
    method getNumberPropertyRegex (line 28) | private static string getNumberPropertyRegex(char prefix, string prope...
    method generateRegex (line 31) | private static string generateRegex(string regexPrefix, IEnumerable<st...
    method getMatchByStatement (line 34) | private static TObject getMatchByStatement<TObject>(string? str, strin...
    method ParseRubyTag (line 60) | public static RubyTag ParseRubyTag(string? str)
    method ParseTimeTag (line 98) | public static TimeTag ParseTimeTag(string? str)
    method ParseTextIndex (line 134) | public static TextIndex ParseTextIndex(string? str)
    method ParseLyric (line 161) | public static Lyric ParseLyric(string str, int? id = null)
    method ParseLyricWithTimeTag (line 197) | public static Lyric ParseLyricWithTimeTag(string? str)
    method ParseSinger (line 217) | public static Singer ParseSinger(string? str)
    method ParseRubyTags (line 233) | public static RubyTag[] ParseRubyTags(IEnumerable<string?> strings)
    method ParseTimeTags (line 236) | public static TimeTag[] ParseTimeTags(IEnumerable<string?> strings)
    method ParseLyrics (line 239) | public static Lyric[] ParseLyrics(IEnumerable<string> strings)
    method ParseSingers (line 242) | public static Singer[] ParseSingers(IEnumerable<string?> strings)

FILE: osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseToneHelper.cs
  class TestCaseToneHelper (line 9) | public static class TestCaseToneHelper
    method NumberToTone (line 11) | public static Tone NumberToTone(double tone)

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/BaseSingleConverterTest.cs
  class BaseSingleConverterTest (line 11) | public abstract class BaseSingleConverterTest<TConverter> where TConvert...
    method CreateSettings (line 13) | protected JsonSerializerSettings CreateSettings()
    method CreateExtraConverts (line 29) | protected virtual IEnumerable<JsonConverter> CreateExtraConverts() => ...

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ColourConverterTest.cs
  class ColourConverterTest (line 12) | public class ColourConverterTest : BaseSingleConverterTest<ColourConverter>
    method TestSerialize (line 14) | [TestCase("#aaaaaa", "#AAAAAA")]
    method TestDeserialize (line 25) | [TestCase("#aaaaaa", "#AAAAAA")]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/CultureInfoConverterTest.cs
  class CultureInfoConverterTest (line 11) | [TestFixture]
    method TestSerialize (line 14) | [TestCase(1, "1")]
    method TestDeserialize (line 23) | [TestCase("1", 1)]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ElementIdConverterTest.cs
  class ElementIdConverterTest (line 11) | public class ElementIdConverterTest : BaseSingleConverterTest<ElementIdC...
    method TestSerialize (line 13) | [TestCase("1234567", "\"1234567\"")]
    method TestDeserialize (line 23) | [TestCase("\"1234567\"", "1234567")]
    method createElementId (line 33) | private static ElementId? createElementId(string? str) =>

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/FontUsageConverterTest.cs
  class FontUsageConverterTest (line 11) | public class FontUsageConverterTest : BaseSingleConverterTest<FontUsageC...
    method TestSerialize (line 13) | [TestCase("", 20, "", false, false, "{}")]
    method TestDeserialize (line 27) | [TestCase("{}", null, 20, null, false, false)]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/KaraokeSkinElementConverterTest.cs
  class KaraokeSkinElementConverterTest (line 14) | public class KaraokeSkinElementConverterTest : BaseSingleConverterTest<K...
    method CreateExtraConverts (line 16) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestLyricConfigSerializer (line 24) | [Test]
    method TestLyricConfigDeserialize (line 35) | [Test]
    method TestNoteStyleSerializer (line 46) | [Test]
    method TestNoteStyleDeserializer (line 56) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/LyricConverterTest.cs
  class LyricConverterTest (line 14) | public class LyricConverterTest : BaseSingleConverterTest<LyricConverter>
    method CreateExtraConverts (line 16) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestLyricConverterWithNoConfig (line 22) | [Test]
    method TestDeserializeWithNoConfig (line 33) | [Test]
    method TestLyricConverterWithSyncConfig (line 58) | [Test]
    method TestLyricConverterWithReferenceConfig (line 75) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ReferenceLyricPropertyConfigConverterTest.cs
  class ReferenceLyricPropertyConfigConverterTest (line 11) | public class ReferenceLyricPropertyConfigConverterTest : BaseSingleConve...
    method TestReferenceLyricConfigSerializer (line 13) | [Test]
    method TestReferenceLyricConfigDeserializer (line 26) | [Test]
    method TestSyncLyricConfigSerializer (line 39) | [Test]
    method TestSyncLyricConfigDeserializer (line 54) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/RubyTagConverterTest.cs
  class RubyTagConverterTest (line 13) | public class RubyTagConverterTest : BaseSingleConverterTest<RubyTagConve...
    method TestSerialize (line 15) | [TestCase(0, 1, "ルビ", "[0,1]:ルビ")]
    method TestDeserialize (line 34) | [TestCase("[0,1]:ルビ", 0, 1, "ルビ")]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/RubyTagsConverterTest.cs
  class RubyTagsConverterTest (line 14) | public class RubyTagsConverterTest : BaseSingleConverterTest<RubyTagsCon...
    method CreateExtraConverts (line 16) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestSerialize (line 21) | [Test]
    method TestDeserialize (line 45) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ShaderConverterTest.cs
  class ShaderConverterTest (line 16) | public class ShaderConverterTest : BaseSingleConverterTest<ShaderConverter>
    method CreateExtraConverts (line 18) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestSerializer (line 23) | [Test]
    method TestDeserialize (line 37) | [Test]
    method TestSerializerListItems (line 52) | [Test]
    method TestDeserializeListItems (line 74) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/StageInfoConverterTest.cs
  class StageInfoConverterTest (line 14) | public class StageInfoConverterTest : BaseSingleConverterTest<StageInfoC...
    method TestClassicStageInfoSerializer (line 16) | [Test]
    method TestClassicStageInfoDeserializer (line 27) | [Test]
    method TestPreviewStageInfoSerializer (line 39) | [Test]
    method TestPreviewStageInfoDeserializer (line 50) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagConverterTest.cs
  class TimeTagConverterTest (line 12) | [TestFixture]
    method TestSerialize (line 15) | [TestCase(1, TextIndex.IndexState.Start, 1000, "[1,start]:1000")]
    method TestDeserialize (line 29) | [TestCase("[1,start]:1000", 1, TextIndex.IndexState.Start, 1000)]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TimeTagsConverterTest.cs
  class TimeTagsConverterTest (line 15) | [TestFixture]
    method CreateExtraConverts (line 18) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestSerialize (line 23) | [Test]
    method TestDeserialize (line 37) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/ToneConverterTest.cs
  class ToneConverterTest (line 11) | public class ToneConverterTest : BaseSingleConverterTest<ToneConverter>
    method TestSerialize (line 13) | [TestCase(1, true, "1.5")]
    method TestDeserialize (line 32) | [TestCase("1.5", 1, true)]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/Converters/TranslationConverterTest.cs
  class TranslationConverterTest (line 13) | public class TranslationConverterTest : BaseSingleConverterTest<Translat...
    method CreateExtraConverts (line 15) | protected override IEnumerable<JsonConverter> CreateExtraConverts()
    method TestSerialize (line 20) | [Test]
    method TestDeserialize (line 34) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/KaraokeJsonSerializableExtensionsTest.cs
  class KaraokeJsonSerializableExtensionsTest (line 12) | public class KaraokeJsonSerializableExtensionsTest
    method TestSerializeLyric (line 14) | [Test]
    method TestDeserializeLyric (line 26) | [Test]
    method TestSerializeNote (line 37) | [Test]
    method TestDeserializeNote (line 49) | [Test]
    method createSettings (line 60) | private JsonSerializerSettings createSettings()

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Serialization/SkinJsonSerializableExtensionsTest.cs
  class SkinJsonSerializableExtensionsTest (line 9) | [Ignore($"Test case already in the {nameof(KaraokeSkinElementConverterTe...

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Stores/BaseGlyphStoreTest.cs
  class BaseGlyphStoreTest (line 17) | public abstract class BaseGlyphStoreTest<TGlyphStore> where TGlyphStore ...
    method OneTimeSetUp (line 23) | [OneTimeSetUp]
    method CreateFontStore (line 41) | protected abstract TGlyphStore CreateFontStore(ResourceStore<byte[]> s...
    method TestCompareFontNameWithOrigin (line 43) | [Test]
    method TestCompareHasGlyphWithOrigin (line 51) | [TestCase('a')]
    method TestCompareGetBaseHeightWithOrigin (line 62) | [Test]
    method TestCompareGetCharacterGlyphWithOrigin (line 70) | [TestCase('a')]
    method TestCompareGetKerningWithOrigin (line 92) | [TestCase('a', 'a')]
    method TestCompareGetTextureUploadWithOrigin (line 104) | [TestCase('a')]

FILE: osu.Game.Rulesets.Karaoke.Tests/IO/Stores/TtfGlyphStoreTest.cs
  class TtfGlyphStoreTest (line 10) | [Ignore("This shit is not implemented.")]
    method CreateFontStore (line 17) | protected override TtfGlyphStore CreateFontStore(ResourceStore<byte[]>...

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/KarDecoderTest.cs
  class KarDecoderTest (line 13) | public class KarDecoderTest
    method TestLyricTextAndTime (line 15) | [TestCase("[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]", "か...
    method TestLyricTimeTag (line 28) | [TestCase("[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]", ne...
    method TestDecodeLyricWithDuplicatedTimeTag (line 41) | [Ignore("Time-tags with same time might be allowed.")]
    method TestDecodeLyricWithTimeTagNotOrder (line 48) | [Ignore("Waiting for lyric parser update.")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/KarEncoderTest.cs
  class KarEncoderTest (line 14) | public class KarEncoderTest
    method TestLyricWithTimeTag (line 16) | [TestCase("からおけ", new string[] { }, "からおけ")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/KarFileTest.cs
  class KarFileTest (line 18) | public class KarFileTest
    method TestDecodeEncodedBeatmap (line 23) | [TestCaseSource(nameof(allKarFileNames))]
    method decode (line 33) | private static Beatmap decode(string filename, out Beatmap encoded)

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/LrcDecoderTest.cs
  class LrcDecoderTest (line 14) | public class LrcDecoderTest
    method TestLyricWithTimeTag (line 16) | [TestCase("からおけ", new string[] { }, "[00:00.00] からおけ")] // todo: handl...

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/LrcEncoderTest.cs
  class LrcEncoderTest (line 13) | public class LrcEncoderTest
    method TestLyricTextAndTime (line 15) | [TestCase("[00:01.00]<00:01.00>か<00:02.00>ら<00:03.00>お<00:04.00>け<00:0...
    method TestLyricTimeTag (line 28) | [TestCase("[00:01.00]<00:01.00>か<00:02.00>ら<00:03.00>お<00:04.00>け<00:0...
    method TestDecodeLyricWithDuplicatedTimeTag (line 41) | [Ignore("Time-tags with same time might be allowed.")]
    method TestDecodeLyricWithTimeTagNotOrder (line 48) | [Ignore("Waiting for lyric parser update.")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/LrcParserUtilsTest.cs
  class LrcParserUtilsTest (line 11) | public class LrcParserUtilsTest
    method TestToDictionary (line 13) | [TestCase(new[] { "[0,start]:1100", "[0,end]:2000", "[1,start]:2100", ...

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/LyricTextDecoderTest.cs
  class LyricTextDecoderTest (line 10) | public class LyricTextDecoderTest
    method TestDecodeBeatmapToPureText (line 12) | [TestCase("karaoke", new[] { "[0,0]:karaoke" })] // only one lyric.

FILE: osu.Game.Rulesets.Karaoke.Tests/Integration/Formats/LyricTextEncoderTest.cs
  class LyricTextEncoderTest (line 13) | [TestFixture]
    method TestEncodeBeatmapToPureText (line 16) | [TestCase(new[] { "[0,0]:karaoke" }, "karaoke")] // only one lyric.

FILE: osu.Game.Rulesets.Karaoke.Tests/KaraokeTestBrowser.cs
  class KaraokeTestBrowser (line 9) | public partial class KaraokeTestBrowser : OsuTestBrowser
    method load (line 11) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/KaraokeModStageTestScene.cs
  class KaraokeModStageTestScene (line 12) | public abstract partial class KaraokeModStageTestScene<TModStage, TStage...
    method CreatePlayerRuleset (line 16) | protected override Ruleset CreatePlayerRuleset() => new KaraokeRuleset();
    method TestCreateModWithStage (line 18) | [Test]
    method TestCreateModWithoutStage (line 29) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/KaraokeModTestScene.cs
  class KaraokeModTestScene (line 8) | public abstract partial class KaraokeModTestScene : ModTestScene
    method CreatePlayerRuleset (line 10) | protected override Ruleset CreatePlayerRuleset() => new KaraokeRuleset();

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/ModsTest.cs
  class ModsTest (line 13) | public class ModsTest
    method TestCheckDuplicatedProperty (line 15) | [Test]
    method getAllModsFromTheRuleset (line 33) | private IEnumerable<Mod> getAllModsFromTheRuleset() =>

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModAutoplay.cs
  class TestSceneKaraokeModAutoplay (line 10) | public partial class TestSceneKaraokeModAutoplay : KaraokeModTestScene
    method TestMod (line 12) | [Ignore("mod auto-play will cause crash")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModAutoplayBySinger.cs
  class TestSceneKaraokeModAutoplayBySinger (line 10) | public partial class TestSceneKaraokeModAutoplayBySinger : KaraokeModTes...
    method TestMod (line 12) | [Ignore("mod auto-play will cause crash")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModClassicStage.cs
  class TestSceneKaraokeModClassicStage (line 9) | public partial class TestSceneKaraokeModClassicStage : KaraokeModStageTe...

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModDisableNote.cs
  class TestSceneKaraokeModDisableNote (line 12) | public partial class TestSceneKaraokeModDisableNote : KaraokeModTestScene
    method TestCheckNoteExistInPlayfield (line 14) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModFlashlight.cs
  class TestSceneKaraokeModFlashlight (line 13) | public partial class TestSceneKaraokeModFlashlight : KaraokeModTestScene
    method TestFlashlightExist (line 15) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModFun.cs
  class TestSceneKaraokeModFun (line 10) | public partial class TestSceneKaraokeModFun : KaraokeModTestScene
    method TestSnowMod (line 12) | [Test]
    method TestWindowsUpdateMod (line 21) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModLyricConfiguration.cs
  class TestSceneKaraokeModLyricConfiguration (line 10) | public partial class TestSceneKaraokeModLyricConfiguration : KaraokeModT...
    method TestAllPanelExist (line 12) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModPerfect.cs
  class TestSceneKaraokeModPerfect (line 12) | public partial class TestSceneKaraokeModPerfect : ModFailConditionTestScene
    method CreatePlayerRuleset (line 14) | protected override Ruleset CreatePlayerRuleset() => new KaraokeRuleset();
    method TestSceneKaraokeModPerfect (line 16) | public TestSceneKaraokeModPerfect()
    method TestLyric (line 22) | [Ignore("Scoring should judgement by note, not lyric.")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModPractice.cs
  class TestSceneKaraokeModPractice (line 13) | public partial class TestSceneKaraokeModPractice : KaraokeModTestScene
    method TestAllPanelExist (line 15) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModPreviewStage.cs
  class TestSceneKaraokeModPreviewStage (line 9) | public partial class TestSceneKaraokeModPreviewStage : KaraokeModStageTe...

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModSuddenDeath.cs
  class TestSceneKaraokeModSuddenDeath (line 17) | [Ignore("Scoring is not implemented.")]
    method CreatePlayerRuleset (line 20) | protected override Ruleset CreatePlayerRuleset() => new KaraokeRuleset();
    method TestSceneKaraokeModSuddenDeath (line 24) | public TestSceneKaraokeModSuddenDeath()
    method TestGreatHit (line 29) | [Test]
    method TestBreakOnHoldNote (line 54) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Mods/TestSceneKaraokeModTranslation.cs
  class TestSceneKaraokeModTranslation (line 10) | public partial class TestSceneKaraokeModTranslation : KaraokeModTestScene
    method TestAllPanelExist (line 12) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/LyricTest.cs
  class LyricTest (line 15) | public class LyricTest
    method TestClone (line 19) | [Test]
    method TestSyncFromReferenceLyric (line 95) | [Test]
    method TestReferenceLyricPropertyChanged (line 126) | [Test]
    method TestReferenceLyricListPropertyChanged (line 156) | [Test]
    method TestConfigChange (line 208) | [Test]
    method TestLyricPropertyWritableVersion (line 256) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/NoteTest.cs
  class NoteTest (line 11) | public class NoteTest
    method TestClone (line 13) | [Test]
    method TestReferenceTime (line 63) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/RubyTagTest.cs
  class RubyTagTest (line 9) | public class RubyTagTest
    method TestClone (line 11) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/TimeTagTest.cs
  class TimeTagTest (line 10) | public class TimeTagTest
    method TestClone (line 12) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/ToneCalculationTest.cs
  class ToneCalculationTest (line 10) | [TestFixture]
    method TestCompareTo (line 13) | [TestCase(0, false, 0)]
    method TestOperatorPlus (line 27) | [TestCase(1, 1, 2)]
    method TestOperatorPlusWithInt (line 40) | [TestCase(1, 1, 2)]
    method TestOperatorMinus (line 50) | [TestCase(1, 1, 0)]
    method TestOperatorMinusWithInt (line 63) | [TestCase(1, 1, 0)]
    method TestOperatorEqual (line 73) | [TestCase(1, 1)]
    method TestOperatorEqualWithInt (line 83) | [TestCase(1, 1)]
    method TestOperatorNotEqual (line 90) | [TestCase(-1, 1)]
    method TestOperatorNotEqualWithInt (line 103) | [TestCase(-1, 1)]
    method TestOperatorGreater (line 112) | [TestCase(1, 0, true)]
    method TestOperatorGreaterWithInt (line 122) | [TestCase(1, 0, true)]
    method TestOperatorGreaterOrEqual (line 130) | [TestCase(1, 0, true)]
    method TestOperatorGreaterOrEqualWithInt (line 140) | [TestCase(1, 0, true)]
    method TestOperatorLess (line 148) | [TestCase(-1, 0, true)]
    method TestOperatorLessWithInt (line 158) | [TestCase(-1, 0, true)]
    method TestOperatorLessOrEqual (line 166) | [TestCase(-1, 0, true)]
    method TestOperatorLessOrEqualWithInt (line 176) | [TestCase(-1, 0, true)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/LyricUtilsTest.cs
  class LyricUtilsTest (line 15) | public class LyricUtilsTest
    method TestRemoveText (line 19) | [TestCase("karaoke", 2, 2, "kaoke")]
    method TestRemoveTextRuby (line 41) | [TestCase(new[] { "[0]:か", "[1]:ら", "[2]:お", "[3]:け" }, 0, 2, new[] { ...
    method TestRemoveTextTimeTag (line 60) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestAddTextText (line 77) | [TestCase("kake", 2, "rao", "karaoke")]
    method TestAddTextRuby (line 92) | [TestCase(new[] { "[0]:か", "[1]:ら", "[2]:お", "[3]:け" }, 0, "karaoke", ...
    method TestAddTextTimeTag (line 109) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestHasTimedTimeTags (line 133) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestGetTimeTagIndexDisplayText (line 147) | [TestCase("[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]", "[...
    method TestGetTimeTagDisplayText (line 172) | [TestCase("[00:01.00]か[00:02.00]ら[00:03.00]お[00:04.00]け[00:05.00]", "[...
    method TestGetTimeTagDisplayRubyText (line 187) | [TestCase(0, "(か)-")]
    method TestAbleToInsertRubyTagAtIndex (line 231) | [TestCase("からおけ", 0, true)]
    method TestLyricTimeFormattedString (line 248) | [TestCase(0, 0, "00:00:000 - 00:00:000")]
    method TestTimeTagTimeFormattedString (line 268) | [TestCase(new[] { "[0,start]:1000", "[1,start]:2000", "[2,start]:3000"...
    method TestContainsSinger (line 292) | [TestCase(new[] { "[1]name:Singer1" }, "[1]name:Singer1", true)]
    method TestOnlyContainsSingers (line 307) | [TestCase(new[] { "[1]name:Singer1" }, new[] { "[1]name:Singer1", "[1]...

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/LyricsUtilsTest.cs
  class LyricsUtilsTest (line 14) | public class LyricsUtilsTest
    method TestSeparateLyricText (line 18) | [TestCase("karaoke", 4, "kara", "oke")]
    method TestSeparateLyricTimeTag (line 39) | [TestCase("カラオケ", new[] { "[0,start]:1000", "[1,start]:2000", "[2,star...
    method TestSeparateLyricRubyTag (line 56) | [TestCase("カラオケ", new[] { "[0]:か", "[1]:ら", "[2]:お", "[3]:け" }, 2,
    method TestSeparateLyricStartTime (line 77) | [Ignore("Not really sure second lyric is based on lyric time or time-t...
    method TestSeparateLyricDuration (line 83) | [Ignore("Not really sure second lyric is based on lyric time or time-t...
    method TestSeparateLyricSinger (line 89) | [TestCase(new[] { 1, 2 }, new[] { 1, 2 }, new[] { 1, 2 })]
    method TestSeparateLyricLanguage (line 114) | [TestCase(1, 1, 1)]
    method TestCombineLyricText (line 140) | [TestCase("Kara", "oke", "Karaoke")]
    method TestCombineLyricTimeTag (line 152) | [TestCase(new[] { "[0,start]" }, new[] { "[0,start]" }, new[] { "[0,st...
    method TestCombineLyricRubyTag (line 181) | [TestCase(new[] { "[0]:ruby" }, new[] { "[0]:ルビ" }, new[] { "[0]:ruby"...
    method TestCombineLyricSinger (line 206) | [TestCase(new[] { 1 }, new[] { 2 }, new[] { 1, 2 })]
    method TestCombineLayoutLanguage (line 221) | [TestCase(1, 1, 1)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/NoteUtilsTest.cs
  class NoteUtilsTest (line 10) | public class NoteUtilsTest
    method TestDisplayText (line 12) | [TestCase("karaoke", "", false, "karaoke")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/NotesUtilsTest.cs
  class NotesUtilsTest (line 12) | public class NotesUtilsTest
    method TestSplitNoteTime (line 14) | [TestCase(new double[] { 1000, 5000 }, 0.2, new double[] { 1000, 1000 ...
    method TestSplitNoteOtherProperty (line 46) | [Test]
    method TestCombineNoteTime (line 89) | [TestCase(new double[] { 1000, -1000 }, new double[] { 2000, -4000 }, ...

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/OrderUtilsTest.cs
  class OrderUtilsTest (line 12) | public class OrderUtilsTest
    method TestContainDuplicatedId (line 14) | [TestCase(new[] { 1, 2, 3, 4 }, false)]
    method TestGetMinOrderNumber (line 28) | [TestCase(new[] { 1, 2, 3, 4 }, 1)]
    method TestGetMaxOrderNumber (line 39) | [TestCase(new[] { 1, 2, 3, 4 }, 4)]
    method TestSorted (line 50) | [TestCase(new[] { 1, 2, 3, 4 }, new[] { 1, 2, 3, 4 })]
    method TestShiftingOrder (line 63) | [TestCase(new[] { 1, 2, 3, 4 }, 1, new[] { 2, 3, 4, 5 })]
    method TestResortOrder (line 77) | [TestCase(new[] { 1, 2, 3, 4 }, 1, new int[] { }, new[] { 1, 2, 3, 4 })]
    method TestChangeOrder (line 101) | [TestCase(new[] { 1, 2, 3, 4 }, 1, 2, new[] { 1, 2, -1 }, new[] { 2, 1...
    class TestOrderObject (line 126) | internal class TestOrderObject : IHasOrder

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/RubyTagUtilsTest.cs
  class RubyTagUtilsTest (line 13) | [TestFixture]
    method TestGetFixedIndex (line 16) | [TestCase("[0,1]:ka", "karaoke", "[0,1]:ka")]
    method TestGetShiftingIndex (line 43) | [TestCase("[0]:ka", "karaoke", 1, "[1]:ka")]
    method TestOutOfRange (line 78) | [TestCase("[0,1]:ka", "karaoke", false)]
    method TestValidNewStartIndex (line 91) | [TestCase("[0,1]:ka", 0, true)]
    method TestValidNewEndIndex (line 105) | [TestCase("[0,1]:ka", 1, true)]
    method TestOutOfRange (line 120) | [TestCase("karaoke", 0, false)]
    method TestEmptyText (line 133) | [TestCase("[0,1]:ka", false)]
    method TestPositionFormattedString (line 143) | [TestCase("[0,1]:ka", "ka(0 ~ 1)")]
    method TestGetTextFromLyric (line 157) | [TestCase("[0]:ka", "カラオケ", "カ")]
    method TestToPositionText (line 178) | [TestCase("[0,1]:ka")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/RubyTagsUtilsTest.cs
  class RubyTagsUtilsTest (line 11) | [TestFixture]
    method TestSort (line 14) | [TestCase(new[] { "[0]:ka", "[1]:ra", "[2]:o" }, RubyTagsUtils.Sorting...
    method TestFindOutOfRange (line 25) | [TestCase(new[] { "[0,6]:ka" }, "karaoke", new string[] { })]
    method TestFindOverlapping (line 35) | [TestCase(new[] { "[0]:ka", "[1]:ra", "[2]:o" }, RubyTagsUtils.Sorting...
    method TestFindEmptyText (line 51) | [TestCase(new[] { "[0]:ka", "[1]:ra", "[2]:o" }, new string[] { })]
    method TestCombine (line 62) | [TestCase(new[] { "[0]:ka" }, "[0]:ka")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/TimeTagUtilsTest.cs
  class TimeTagUtilsTest (line 10) | public class TimeTagUtilsTest
    method TestShiftingTimeTag (line 12) | [TestCase("[1,start]:1000", 2, "[3,start]:1000")]
    method TestFormattedString (line 28) | [TestCase("[1,start]:1000", "00:01:000")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Utils/TimeTagsUtilsTest.cs
  class TimeTagsUtilsTest (line 13) | [TestFixture]
    method TestGenerateTimeTag (line 16) | [TestCase("[1,start]:1000", "[3,start]:3000", 2, "[2,start]:2000")]
    method TestSort (line 45) | [TestCase(new[] { "[0,start]:1100", "[0,end]:2000", "[1,start]:2100", ...
    method TestFindOutOfRange (line 59) | [TestCase("カラオケ", new[] { "[0,start]:1000", "[1,start]:2000", "[2,star...
    method TestFindNoneTime (line 72) | [TestCase(new[] { "[0,start]:1000", "[1,start]", "[2,start]:3000", "[3...
    method TestHasStartTimeTagInLyric (line 83) | [TestCase("カラオケ", new[] { "[0,start]:1000", "[3,end]:2000" }, true)]
    method TestHasEndTimeTagInLyric (line 98) | [TestCase("カラオケ", new[] { "[0,start]:1000", "[3,end]:2000" }, true)]
    method TestFindOverlapping (line 112) | [TestCase(new[] { "[0,start]:2000", "[0,end]:1000" }, GroupCheck.Asc, ...
    method TestFixOverlapping (line 134) | [TestCase(new[] { "[0,start]:2000", "[0,end]:1000" }, GroupCheck.Asc, ...
    method TestToTimeBasedDictionary (line 162) | [TestCase(new[] { "[0,start]:1100", "[0,end]:2000", "[1,start]:2100", ...
    method TestGetStartTime (line 175) | [TestCase(new[] { "[0,start]:1100", "[0,end]:2000", "[1,start]:2100", ...
    method TestGetEndTime (line 188) | [TestCase(new[] { "[0,start]:1100", "[0,end]:2000", "[1,start]:2100", ...

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/HitObjectWorkingPropertyValidatorTest.cs
  class HitObjectWorkingPropertyValidatorTest (line 12) | public abstract class HitObjectWorkingPropertyValidatorTest<THitObject, ...
    method TestInitialState (line 16) | [Test]
    method TestAllInvalidateTest (line 23) | [Test]
    method AssetInitialStateIsValid (line 30) | protected void AssetInitialStateIsValid(THitObject hitObject, TFlag flag)
    method AssetIsValid (line 36) | protected void AssetIsValid(THitObject hitObject, TFlag flag, bool isV...
    method IsInitialStateValid (line 41) | protected abstract bool IsInitialStateValid(TFlag flag);

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/LyricWorkingPropertyValidatorTest.cs
  class LyricWorkingPropertyValidatorTest (line 16) | public class LyricWorkingPropertyValidatorTest : HitObjectWorkingPropert...
    method TestSingers (line 18) | [Test]
    method TestPage (line 95) | [Test]
    method TestReferenceLyric (line 105) | [Test]
    method IsInitialStateValid (line 155) | protected override bool IsInitialStateValid(LyricWorkingProperty flag)

FILE: osu.Game.Rulesets.Karaoke.Tests/Objects/Workings/NoteWorkingPropertyValidatorTest.cs
  class NoteWorkingPropertyValidatorTest (line 12) | public class NoteWorkingPropertyValidatorTest : HitObjectWorkingProperty...
    method TestPage (line 14) | [Test]
    method TestReferenceLyric (line 24) | [Test]
    method IsInitialStateValid (line 74) | protected override bool IsInitialStateValid(NoteWorkingProperty flag)

FILE: osu.Game.Rulesets.Karaoke.Tests/Overlays/Changelog/ChangelogPullRequestInfoTest.cs
  class ChangelogPullRequestInfoTest (line 10) | public class ChangelogPullRequestInfoTest
    method TestGetPullRequestInfoFromLink (line 12) | [TestCase("#2152@andy840119", new[] { 2152 }, new[] { "andy840119" })]
    method TestTestGetPullRequestInfoFromLinkWithNull (line 28) | [TestCase("unknown_repo", "#2152@andy840119")] // "unknown_repo" does ...

FILE: osu.Game.Rulesets.Karaoke.Tests/Overlays/Changelog/TestSceneKaraokeChangeLogMarkdownContainer.cs
  class TestSceneKaraokeChangeLogMarkdownContainer (line 16) | [TestFixture]
    method SetUp (line 24) | [SetUp]
    method TestShowWithNoFetch (line 54) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Overlays/Changelog/TestSceneKaraokeChangeLogOverlay.cs
  class TestSceneKaraokeChangeLogOverlay (line 10) | [TestFixture]
    method SetUp (line 15) | [SetUp]
    method TestShowWithNoFetch (line 18) | [Test]
    class TestChangelogOverlay (line 25) | private partial class TestChangelogOverlay : KaraokeChangelogOverlay
      method TestChangelogOverlay (line 27) | public TestChangelogOverlay()

FILE: osu.Game.Rulesets.Karaoke.Tests/Overlays/TestSceneOverlayColourProvider.cs
  class TestSceneOverlayColourProvider (line 24) | [TestFixture]
    method TestShowWithNoFetch (line 27) | [Test]
    class TitleTableColumn (line 70) | private class TitleTableColumn : TableColumn
      method TitleTableColumn (line 72) | public TitleTableColumn(string title)
    class PreviewColourDrawable (line 78) | private partial class PreviewColourDrawable : CompositeDrawable
      method PreviewColourDrawable (line 85) | public PreviewColourDrawable(Color4 color)
      method OnClick (line 106) | protected override bool OnClick(ClickEvent e)

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestKaraokeScoreInfo.cs
  class TestKaraokeScoreInfo (line 14) | public class TestKaraokeScoreInfo : ScoreInfo
    method TestKaraokeScoreInfo (line 16) | public TestKaraokeScoreInfo()

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestSceneBeatmapMetadataGraph.cs
  class TestSceneBeatmapMetadataGraph (line 20) | public partial class TestSceneBeatmapMetadataGraph : OsuTestScene
    method TestBeatmapMetadataGraph (line 22) | [Test]
    method createTest (line 34) | private void createTest(ScoreInfo score, IBeatmap beatmap) => AddStep(...
    method createSingerInfo (line 52) | private static SingerInfo createSingerInfo()

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestSceneHitEventTimingDistributionGraph.cs
  class TestSceneHitEventTimingDistributionGraph (line 19) | public partial class TestSceneHitEventTimingDistributionGraph : OsuTestS...
    method TestManyDistributedEvents (line 21) | [Test]
    method TestZeroTimeOffset (line 27) | [Test]
    method TestNoEvents (line 33) | [Test]
    method createTest (line 39) | private void createTest(IReadOnlyList<HitEvent> events) => AddStep("cr...
    method CreateDistributedHitEvents (line 57) | public static List<HitEvent> CreateDistributedHitEvents()

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestSceneNotScorableGraph.cs
  class TestSceneNotScorableGraph (line 14) | public partial class TestSceneNotScorableGraph : OsuTestScene
    method TestBeatmapInfoGraph (line 16) | [Test]
    method createTest (line 22) | private void createTest() => AddStep("create test", () =>

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestSceneScoringResultGraph.cs
  class TestSceneScoringResultGraph (line 17) | public partial class TestSceneScoringResultGraph : OsuTestScene
    method TestManyDistributedEvents (line 19) | [Test]
    method createTest (line 27) | private void createTest(ScoreInfo score, IBeatmap beatmap) => AddStep(...

FILE: osu.Game.Rulesets.Karaoke.Tests/Ranking/TestSceneStatisticsPanel.cs
  class TestSceneStatisticsPanel (line 13) | public partial class TestSceneStatisticsPanel : OsuTestScene
    method TestScoreWithStatistics (line 15) | [Test]
    method TestScoreWithoutStatistics (line 26) | [Test]
    method TestNullScore (line 32) | [Test]
    method loadPanel (line 38) | private void loadPanel(ScoreInfo? score) => AddStep("load panel", () =>

FILE: osu.Game.Rulesets.Karaoke.Tests/Replays/TestSceneAutoGeneration.cs
  class TestSceneAutoGeneration (line 15) | public partial class TestSceneAutoGeneration : OsuTestScene
    method TestSingleShortNote (line 17) | [Test]
    method TestSingleNoteWithLongTime (line 45) | [Test]
    method TestNoteStair (line 73) | [Test]
    method checkMatching (line 112) | private static bool checkMatching(ReplayFrame frame, Tone? tone)

FILE: osu.Game.Rulesets.Karaoke.Tests/Replays/TestSceneAutoGenerationBySinger.cs
  class TestSceneAutoGenerationBySinger (line 17) | public partial class TestSceneAutoGenerationBySinger : OsuTestScene
    method TestSingDemoSong (line 19) | [Test]
    method getCompareResultFromName (line 48) | private static IReadOnlyList<TestKaraokeReplayFrame> getCompareResultF...
    type TestKaraokeReplayFrame (line 57) | private struct TestKaraokeReplayFrame

FILE: osu.Game.Rulesets.Karaoke.Tests/Resources/TestResources.cs
  class TestResources (line 17) | public static class TestResources
    method GetStore (line 19) | public static DllResourceStore GetStore() => new(typeof(TestResources)...
    method OpenResource (line 21) | public static Stream OpenResource(string name) => GetStore().GetStream...
    method OpenBeatmapResource (line 23) | public static Stream OpenBeatmapResource(string name) => OpenResource(...
    method OpenSkinResource (line 25) | public static Stream OpenSkinResource(string name) => OpenResource($"T...
    method OpenKarResource (line 27) | public static Stream OpenKarResource(string name) => OpenResource($"Te...
    method GetTestKarForImport (line 29) | public static string GetTestKarForImport(string name)
    method OpenTrackResource (line 41) | public static Stream OpenTrackResource(string name) => OpenResource($"...
    method OpenTrackInfo (line 43) | public static Track OpenTrackInfo(AudioManager audioManager, string na...
    method CreateSkinStorageResourceProvider (line 45) | public static IStorageResourceProvider CreateSkinStorageResourceProvid...
    class TestStorageResourceProvider (line 47) | private class TestStorageResourceProvider : IStorageResourceProvider
      method TestStorageResourceProvider (line 49) | public TestStorageResourceProvider(string skinName)
      method CreateTextureLoaderStore (line 61) | public IResourceStore<TextureUpload> CreateTextureLoaderStore(IResou...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/BeatmapEditorScreenTestScene.cs
  class BeatmapEditorScreenTestScene (line 8) | public abstract partial class BeatmapEditorScreenTestScene<T> : GenericE...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Components/TestSceneLyricSelector.cs
  class TestSceneLyricSelector (line 18) | public partial class TestSceneLyricSelector : OsuManualInputManagerTestS...
    method TestSceneLyricSelector (line 23) | public TestSceneLyricSelector()
    method TestAllFiles (line 30) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/BaseCaretPositionAlgorithmTest.cs
  class BaseCaretPositionAlgorithmTest (line 14) | public abstract class BaseCaretPositionAlgorithmTest<TAlgorithm, TCaret>...
    method TestPositionMovable (line 16) | protected static void TestPositionMovable(Lyric[] lyrics, TCaret caret...
    method TestMoveToPreviousLyric (line 31) | protected static void TestMoveToPreviousLyric(Lyric[] lyrics, TCaret c...
    method TestMoveToNextLyric (line 41) | protected static void TestMoveToNextLyric(Lyric[] lyrics, TCaret caret...
    method TestMoveToFirstLyric (line 51) | protected static void TestMoveToFirstLyric(Lyric[] lyrics, TCaret? exp...
    method TestMoveToLastLyric (line 61) | protected static void TestMoveToLastLyric(Lyric[] lyrics, TCaret? expe...
    method TestMoveToTargetLyric (line 71) | protected static void TestMoveToTargetLyric(Lyric[] lyrics, Lyric lyri...
    method CreateAlgorithm (line 81) | protected static TAlgorithm CreateAlgorithm(Lyric[] lyrics)
    method AssertEqual (line 84) | protected static void AssertEqual(TCaret? expected, TCaret? actual)
    method GetLyricsByMethodName (line 97) | protected Lyric[] GetLyricsByMethodName(string methodName)
    method getMethod (line 107) | private static PropertyInfo? getMethod(Type type, string methodName)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/BaseCharIndexCaretPositionAlgorithmTest.cs
  class BaseCharIndexCaretPositionAlgorithmTest (line 14) | public abstract class BaseCharIndexCaretPositionAlgorithmTest<TAlgorithm...
    method TestPositionMovable (line 19) | [TestCase(nameof(singleLyric), 0, 0, true)]
    method TestMoveToPreviousLyric (line 35) | [TestCase(nameof(singleLyric), 0, 0, null, null)] // cannot move up if...
    method TestMoveToNextLyric (line 50) | [TestCase(nameof(singleLyric), 0, 0, null, null)] // cannot move down ...
    method TestMoveToFirstLyric (line 65) | [TestCase(nameof(singleLyric), 0, 0)]
    method TestMoveToLastLyric (line 78) | [TestCase(nameof(singleLyric), 0, 3)]
    method TestMoveToTargetLyric (line 91) | [TestCase(nameof(singleLyric), 0, 0)]
    method TestMoveToPreviousIndex (line 107) | [TestCase(nameof(singleLyric), 0, 0, null, null)]
    method TestMoveToNextIndex (line 120) | [TestCase(nameof(singleLyric), 0, 3, null, null)]
    method TestMoveToFirstIndex (line 133) | [TestCase(nameof(singleLyric), 0, 0, 0)]
    method TestMoveToLastIndex (line 145) | [TestCase(nameof(singleLyric), 0, 0, 3)]
    method TestMoveToTargetLyric (line 157) | [TestCase(nameof(singleLyric), 0, 0, 0)]
    method CreateCaret (line 173) | protected abstract TCaret CreateCaret(Lyric lyric, int index);
    method createCaretPosition (line 175) | private TCaret createCaretPosition(IEnumerable<Lyric> lyrics, int lyri...
    method createExpectedCaretPosition (line 184) | private TCaret? createExpectedCaretPosition(IEnumerable<Lyric> lyrics,...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/BaseIndexCaretPositionAlgorithmTest.cs
  class BaseIndexCaretPositionAlgorithmTest (line 11) | public abstract class BaseIndexCaretPositionAlgorithmTest<TAlgorithm, TC...
    method TestMoveToPreviousIndex (line 14) | protected static void TestMoveToPreviousIndex(Lyric[] lyrics, TCaret c...
    method TestMoveToNextIndex (line 24) | protected static void TestMoveToNextIndex(Lyric[] lyrics, TCaret caret...
    method TestMoveToFirstIndex (line 34) | protected static void TestMoveToFirstIndex(Lyric[] lyrics, Lyric lyric...
    method TestMoveToLastIndex (line 44) | protected static void TestMoveToLastIndex(Lyric[] lyrics, Lyric lyric,...
    method TestMoveToTargetLyric (line 54) | protected static void TestMoveToTargetLyric<TIndex>(Lyric[] lyrics, Ly...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/ClickingCaretPositionAlgorithmTest.cs
  class ClickingCaretPositionAlgorithmTest (line 14) | public class ClickingCaretPositionAlgorithmTest : BaseCaretPositionAlgor...
    method TestPositionMovable (line 18) | [TestCase(nameof(singleLyric), 0, true)]
    method TestMoveToPreviousLyric (line 29) | [TestCase(nameof(singleLyric), 0, null)] // should always not movable.
    method TestMoveToNextLyric (line 43) | [TestCase(nameof(singleLyric), 0, null)] // should always not movable.
    method TestMoveToFirstLyric (line 57) | [TestCase(nameof(singleLyric), null)] // should always not movable.
    method TestMoveToLastLyric (line 70) | [TestCase(nameof(singleLyric), null)] // should always not movable.
    method TestMoveToTargetLyric (line 83) | [TestCase(nameof(singleLyric), 0)]
    method createCaretPosition (line 97) | private static ClickingCaretPosition createCaretPosition(IEnumerable<L...
    method createExpectedCaretPosition (line 106) | private static ClickingCaretPosition? createExpectedCaretPosition(IEnu...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/CreateRemoveTimeTagCaretPositionAlgorithmTest.cs
  class CreateRemoveTimeTagCaretPositionAlgorithmTest (line 11) | [TestFixture]
    method CreateCaret (line 14) | protected override CreateRemoveTimeTagCaretPosition CreateCaret(Lyric ...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/CreateRubyTagCaretPositionAlgorithmTest.cs
  class CreateRubyTagCaretPositionAlgorithmTest (line 11) | [TestFixture]
    method CreateCaret (line 14) | protected override CreateRubyTagCaretPosition CreateCaret(Lyric lyric,...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/CuttingCaretPositionAlgorithmTest.cs
  class CuttingCaretPositionAlgorithmTest (line 14) | [TestFixture]
    method TestPositionMovable (line 19) | [TestCase(nameof(singleLyric), 0, 1, true)]
    method TestMoveToPreviousLyric (line 39) | [TestCase(nameof(singleLyric), 0, 1, null, null)] // cannot move up if...
    method TestMoveToNextLyric (line 54) | [TestCase(nameof(singleLyric), 0, 1, null, null)] // cannot move down ...
    method TestMoveToFirstLyric (line 69) | [TestCase(nameof(singleLyric), 0, 1)]
    method TestMoveToLastLyric (line 82) | [TestCase(nameof(singleLyric), 0, 3)]
    method TestMoveToTargetLyric (line 95) | [TestCase(nameof(singleLyric), 0, 1)]
    method TestMoveToPreviousIndex (line 111) | [TestCase(nameof(singleLyric), 0, 1, null, null)]
    method TestMoveToNextIndex (line 124) | [TestCase(nameof(singleLyric), 0, 3, null, null)]
    method TestMoveToFirstIndex (line 137) | [TestCase(nameof(singleLyric), 0, 0, 1)]
    method TestMoveToLastIndex (line 149) | [TestCase(nameof(singleLyric), 0, 0, 3)]
    method TestMoveToTargetLyric (line 161) | [TestCase(nameof(singleLyric), 0, 1, 1)]
    method createCaretPosition (line 177) | private static CuttingCaretPosition createCaretPosition(IEnumerable<Ly...
    method createExpectedCaretPosition (line 186) | private static CuttingCaretPosition? createExpectedCaretPosition(IEnum...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/NavigateCaretPositionAlgorithmTest.cs
  class NavigateCaretPositionAlgorithmTest (line 14) | public class NavigateCaretPositionAlgorithmTest : BaseCaretPositionAlgor...
    method TestPositionMovable (line 18) | [TestCase(nameof(singleLyric), 0, true)]
    method TestMoveToPreviousLyric (line 29) | [TestCase(nameof(singleLyric), 0, null)] // cannot move up if at top i...
    method TestMoveToNextLyric (line 43) | [TestCase(nameof(singleLyric), 0, null)] // cannot move down if at bot...
    method TestMoveToFirstLyric (line 57) | [TestCase(nameof(singleLyric), 0)]
    method TestMoveToLastLyric (line 70) | [TestCase(nameof(singleLyric), 0)]
    method TestMoveToTargetLyric (line 83) | [TestCase(nameof(singleLyric), 0)]
    method createCaretPosition (line 97) | private static NavigateCaretPosition createCaretPosition(IEnumerable<L...
    method createExpectedCaretPosition (line 106) | private static NavigateCaretPosition? createExpectedCaretPosition(IEnu...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/RecordingTimeTagCaretPositionAlgorithmTest.cs
  class RecordingTimeTagCaretPositionAlgorithmTest (line 16) | [TestFixture]
    method TestPositionMovable (line 23) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToPreviousLyric (line 41) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToNextLyric (line 60) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToFirstLyric (line 79) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, 0)]
    method TestMoveToLastLyric (line 100) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, 4)]
    method TestMoveToTargetLyric (line 121) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToPreviousIndex (line 142) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToNextIndex (line 156) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToFirstIndex (line 170) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToLastIndex (line 186) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method TestMoveToTargetLyric (line 202) | [TestCase(nameof(singleLyric), RecordingTimeTagCaretMoveMode.None, 0, ...
    method createCaretPosition (line 217) | private static RecordingTimeTagCaretPosition createCaretPosition(IEnum...
    method createExpectedCaretPosition (line 230) | private static RecordingTimeTagCaretPosition? createExpectedCaretPosit...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/Algorithms/TypingCaretPositionAlgorithmTest.cs
  class TypingCaretPositionAlgorithmTest (line 14) | [TestFixture]
    method TestPositionMovable (line 19) | [TestCase(nameof(singleLyric), 0, 0, true)]
    method TestMoveToPreviousLyric (line 34) | [TestCase(nameof(singleLyric), 0, 0, null, null)] // cannot move up if...
    method TestMoveToNextLyric (line 49) | [TestCase(nameof(singleLyric), 0, 0, null, null)] // cannot move down ...
    method TestMoveToFirstLyric (line 64) | [TestCase(nameof(singleLyric), 0, 0)]
    method TestMoveToLastLyric (line 77) | [TestCase(nameof(singleLyric), 0, 4)]
    method TestMoveToTargetLyric (line 90) | [TestCase(nameof(singleLyric), 0, 0)]
    method TestMoveToPreviousIndex (line 106) | [TestCase(nameof(singleLyric), 0, 0, null, null)]
    method TestMoveToNextIndex (line 119) | [TestCase(nameof(singleLyric), 0, 4, null, null)]
    method TestMoveToFirstIndex (line 132) | [TestCase(nameof(singleLyric), 0, 0, 0)]
    method TestMoveToLastIndex (line 144) | [TestCase(nameof(singleLyric), 0, 0, 4)]
    method TestMoveToTargetLyric (line 156) | [TestCase(nameof(singleLyric), 0, 0, 0)]
    method createCaretPosition (line 172) | private static TypingCaretPosition createCaretPosition(IEnumerable<Lyr...
    method createExpectedCaretPosition (line 181) | private static TypingCaretPosition? createExpectedCaretPosition(IEnume...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/CaretPosition/IndexCaretPositionTest.cs
  class IndexCaretPositionTest (line 12) | [TestFixture(typeof(CreateRubyTagCaretPosition))]
    method TestCompareWithLargerIndex (line 19) | [Test]
    method TestCompareEqualIndex (line 33) | [Test]
    method TestCompareWithSmallerIndex (line 47) | [Test]
    method TestCompareWithDifferentLyric (line 61) | [Test]
    method TestCompareDifferentType (line 76) | [Test]
    method createSmallerCaretPosition (line 90) | private static IIndexCaretPosition createSmallerCaretPosition(Lyric ly...
    method createBiggerCaretPosition (line 101) | private static IIndexCaretPosition createBiggerCaretPosition(Lyric lyr...
    type FakeCaretPosition (line 112) | private struct FakeCaretPosition : IIndexCaretPosition
      method FakeCaretPosition (line 114) | public FakeCaretPosition(Lyric lyric)
      method CompareTo (line 121) | public int CompareTo(IIndexCaretPosition? other)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/Content/SingleLyricEditorTest.cs
  class SingleLyricEditorTest (line 11) | public class SingleLyricEditorTest
    method TestLockMessage (line 13) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/Content/TestSceneInteractableLyric.cs
  class TestSceneInteractableLyric (line 34) | public partial class TestSceneInteractableLyric : EditorClockTestScene
    method TestSceneInteractableLyric (line 57) | public TestSceneInteractableLyric()
    method TestGridLayer (line 63) | [Test]
    method TestEditLyricLayer (line 93) | [Test]
    method TestTimeTagLayer (line 109) | [Test]
    method TestCaretLayer (line 125) | [Test]
    method TestBlueprintLayer (line 148) | [Test]
    method load (line 174) | [BackgroundDependencyLoader]
    method switchMode (line 189) | private void switchMode(LyricEditorMode mode, Enum? step = null)
    method switchEditRubyModeState (line 200) | private void switchEditRubyModeState(RubyTagEditMode mode)
    method getLoader (line 218) | private LayerLoader? getLoader<TLayer>()
    method addLoader (line 221) | private void addLoader<TLayer>(bool reloadView = true) where TLayer : ...
    method addLoader (line 226) | private void addLoader<TLayer>(LayerLoader<TLayer> instance, bool relo...
    method removeLoader (line 241) | private void removeLoader<TLoader>(bool reloadView = true)
    method changeLayerProperty (line 256) | private void changeLayerProperty<TLayer>(Action<TLayer> action, bool r...
    method updateInteractableLyric (line 275) | private void updateInteractableLyric()
    method createInteractableLyric (line 308) | private static InteractableLyric createInteractableLyric(LayerLoader[]...
    method reorderLoaders (line 323) | private static LayerLoader[] reorderLoaders(LayerLoader[] loaders)
    class MockLyricEditorState (line 347) | [Cached(typeof(ILyricEditorState))]
      method LoadComplete (line 373) | protected override void LoadComplete()
      method SwitchMode (line 385) | public void SwitchMode(LyricEditorMode mode)
      method SwitchEditStep (line 388) | public void SwitchEditStep<TEditStep>(TEditStep editStep) where TEdi...
      method NavigateToFix (line 398) | public void NavigateToFix(LyricEditorMode mode)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/Content/TestScenePreviewKaraokeSpriteText.cs
  class TestScenePreviewKaraokeSpriteText (line 23) | public partial class TestScenePreviewKaraokeSpriteText : OsuTestScene
    method Update (line 38) | protected override void Update()
    method load (line 44) | [BackgroundDependencyLoader]
    method Setup (line 98) | [SetUp]
    method TestGetCharIndexByPosition (line 112) | [Test]
    method TestGetRectByCharIndex (line 136) | [Test]
    method TestGetCharIndicatorByPosition (line 154) | [Test]
    method TestGetRectByCharIndicator (line 178) | [Test]
    method TestGetRubyPosition (line 196) | [Test]
    method TestGetTimeTagByPosition (line 213) | [Test]
    method TestGetPositionByTimeTag (line 237) | [Test]
    method TearDown (line 252) | [TearDown]
    method getMousePosition (line 261) | private Vector2 getMousePosition()
    method triggerUpdate (line 267) | private void triggerUpdate(Action action)
    method updateText (line 272) | private void updateText(string? text)
    method hidePosition (line 279) | private void hidePosition()
    method showPosition (line 284) | private void showPosition(Vector2 position)
    method showPosition (line 290) | private void showPosition(RectangleF? position)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/LyricEditorTest.cs
  class LyricEditorTest (line 9) | public class LyricEditorTest
    method TestGetSuitableLayout (line 11) | [TestCase(LyricEditorLayout.List, LyricEditorLayout.List, LyricEditorL...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/LyricEditorVerifierTest.cs
  class LyricEditorVerifierTest (line 19) | [HeadlessTest]
    method load (line 26) | [BackgroundDependencyLoader]
    method SetUp (line 42) | [SetUp]
    method TestFirstLoad (line 61) | [Test]
    method TestAdd (line 72) | [Test]
    method TestRemove (line 87) | [Test]
    method TestUpdate (line 98) | [Test]
    method TestRefresh (line 111) | [Test]
    method TestRefreshByHitObject (line 124) | [Test]
    method createLyricWithLanguageIssueOnly (line 139) | private static Lyric createLyricWithLanguageIssueOnly()
    method updateEditorBeatmap (line 150) | private void updateEditorBeatmap(Action<EditorBeatmap> action)
    method assertHitObjectIssueAmount (line 163) | private void assertHitObjectIssueAmount(KaraokeHitObject karaokeHitObj...
    method assertEditModeIssueAmount (line 172) | private void assertEditModeIssueAmount(LyricEditorMode editMode, int i...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/Settings/TestSceneLyricEditorDescriptionTextFlowContainer.cs
  class TestSceneDescriptionTextFlowContainer (line 18) | [TestFixture]
    method SetUp (line 26) | [SetUp]
    method TestDisplayDescriptionWithEditMode (line 41) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/States/BaseLyricCaretStateTest.cs
  class BaseLyricCaretStateTest (line 26) | [HeadlessTest]
    method load (line 36) | [BackgroundDependencyLoader]
    method Setup (line 66) | [SetUp]
    method PrepareLyrics (line 77) | public void PrepareLyrics(IEnumerable<string> lyricTexts)
    method ChangeMode (line 88) | protected void ChangeMode(TestCaretType type)
    method GetLyric (line 118) | protected Lyric GetLyric(int index)
    method PrepareHoverCaretPosition (line 128) | public void PrepareHoverCaretPosition(Func<ICaretPosition?> getPosition)
    method PrepareCaretPosition (line 139) | public void PrepareCaretPosition(Func<ICaretPosition?> getPosition)
    method PrepareRangeCaretPosition (line 150) | public void PrepareRangeCaretPosition(Func<RangeCaretPosition?> getPos...
    method AssertHoverCaretPosition (line 161) | protected void AssertHoverCaretPosition(Func<ICaretPosition?> getPosit...
    method AssertCaretPosition (line 166) | protected void AssertCaretPosition(Func<ICaretPosition?> getPosition)
    method AssertDraggableCaretPosition (line 171) | protected void AssertDraggableCaretPosition(Func<RangeCaretPosition?> ...
    class TestLyricEditorState (line 178) | private partial class TestLyricEditorState : Component, ILyricEditorState
      method SwitchMode (line 193) | public void SwitchMode(LyricEditorMode mode)
      method updateModeWithEditStep (line 207) | private void updateModeWithEditStep()
      method SwitchEditStep (line 232) | public void SwitchEditStep<TEditStep>(TEditStep editStep) where TEdi...
      method NavigateToFix (line 240) | public void NavigateToFix(LyricEditorMode mode)
  type TestCaretType (line 250) | public enum TestCaretType

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/States/LyricCaretStateActionTest.cs
  class LyricCaretStateActionTest (line 12) | public partial class LyricCaretStateActionTest : BaseLyricCaretStateTest
    method TestGetCaretPositionByActionWithViewOnlyMode (line 16) | [Test]
    method TestGetCaretPositionByActionWithCaretEnableMode (line 33) | [Test]
    method TestGetCaretPositionByActionWithCaretWithIndexMode (line 80) | [Test]
    method TestGetCaretPositionByActionWithCaretDraggableMode (line 143) | [Test]
    method TestGetCaretPositionByActionWithCaretDraggableModeWithDragRange (line 206) | [Test]
    method TestGetCaretPositionByActionWithNoLyric (line 288) | [Test]
    method AssertGetCaretPositionByAction (line 302) | protected void AssertGetCaretPositionByAction(MovingCaretAction action...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/States/LyricCaretStateMoveCaretTest.cs
  class LyricCaretStateMoveCaretTest (line 12) | public partial class LyricCaretStateMoveCaretTest : BaseLyricCaretStateTest
    method TestMoveHoverCaretToTargetPosition (line 16) | [Test]
    method TestConfirmHoverCaretPosition (line 70) | [Test]
    method TestClearHoverCaretPosition (line 111) | [Test]
    method TestMoveCaretToTargetPosition (line 152) | [Test]
    method TestMoveDraggingCaretIndex (line 206) | [Test]
    method MoveHoverCaretToTargetPosition (line 254) | protected void MoveHoverCaretToTargetPosition(Func<Lyric> lyric)
    method MoveHoverCaretToTargetPosition (line 262) | protected void MoveHoverCaretToTargetPosition<TIndex>(Func<Lyric> lyri...
    method ConfirmHoverCaretPosition (line 271) | protected void ConfirmHoverCaretPosition()
    method ClearHoverCaretPosition (line 279) | protected void ClearHoverCaretPosition()
    method MoveCaretToTargetPosition (line 287) | protected void MoveCaretToTargetPosition(Func<Lyric> lyric)
    method MoveCaretToTargetPosition (line 295) | protected void MoveCaretToTargetPosition<TIndex>(Func<Lyric> lyric, Fu...
    method StartDragging (line 304) | protected void StartDragging()
    method MoveDraggingCaretIndex (line 312) | protected void MoveDraggingCaretIndex<TIndex>(Func<TIndex> index)
    method EndDragging (line 321) | protected void EndDragging()

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/States/LyricCaretStateSwitchModeTest.cs
  class LyricCaretStateSwitchModeTest (line 12) | public partial class LyricCaretStateSwitchModeTest : BaseLyricCaretState...
    method TestViewOnlyMode (line 16) | [Test]
    method TestCaretEnableMode (line 32) | [Test]
    method TestCaretWithIndexMode (line 48) | [Test]
    method TestCaretDraggableMode (line 64) | [Test]
    method TestDefaultModeWithNoLyric (line 84) | [Test]
    method TestSwitchModeNotCauseBroken (line 99) | [Test]
    method TestSwitchTestFromRangeOfCaret (line 107) | [Test]
    method AssertCaretEnabled (line 132) | protected void AssertCaretEnabled(bool enabled)
    method AssertCaretDraggable (line 137) | protected void AssertCaretDraggable(bool caretDraggable)
    method AssertCaretPositionAlgorithmIsNull (line 142) | protected void AssertCaretPositionAlgorithmIsNull()
    method AssertCaretPositionAlgorithm (line 147) | protected void AssertCaretPositionAlgorithm<TCaretPositionAlgorithm>()

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/Lyrics/TestSceneLyricEditorColourProvider.cs
  class TestSceneLyricEditorColourProvider (line 24) | public partial class TestSceneLyricEditorColourProvider : OsuTestScene
    method TestShowWithNoFetch (line 26) | [Test]
    class TitleTableColumn (line 100) | private class TitleTableColumn : TableColumn
      method TitleTableColumn (line 102) | public TitleTableColumn(string title)
    class PreviewColourDrawable (line 108) | private partial class PreviewColourDrawable : CompositeDrawable
      method PreviewColourDrawable (line 115) | public PreviewColourDrawable(Color4 color)
      method OnClick (line 136) | protected override bool OnClick(ClickEvent e)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestSceneEditorMenuBar.cs
  class TestSceneEditorMenuBar (line 21) | [TestFixture]
    method load (line 27) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestSceneKaraokeBeatmapEditor.cs
  class TestSceneKaraokeBeatmapEditor (line 8) | public partial class TestSceneKaraokeBeatmapEditor : GenericEditorTestSc...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestSceneLyricEditorScreen.cs
  class TestSceneLyricEditorScreen (line 21) | public partial class TestSceneLyricEditorScreen : BeatmapEditorScreenTes...
    method CreateEditorScreen (line 28) | protected override LyricEditorScreen CreateEditorScreen() => new();
    method load (line 33) | [BackgroundDependencyLoader]
    method TestViewMode (line 49) | [Test]
    method TestEditTextMode (line 55) | [Test]
    method TestEditReferenceMode (line 62) | [Test]
    method TestEditLanguageMode (line 68) | [Test]
    method TestEditRubyMode (line 75) | [Test]
    method TestEditTimeTagMode (line 82) | [Test]
    method TestEditRomanisation (line 89) | [Test]
    method TestEditNoteMode (line 96) | [Test]
    method TestEditSingerMode (line 103) | [Test]
    method switchToMode (line 109) | private void switchToMode(LyricEditorMode mode)
    method clickEditStepButtons (line 118) | private void clickEditStepButtons<T>() where T : struct, Enum
    method clickTargetEditModeButton (line 126) | private void clickTargetEditModeButton<T>(T editMode) where T : struct...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestScenePageScreen.cs
  class TestScenePageScreen (line 17) | [TestFixture]
    method CreateEditorScreen (line 22) | protected override PageScreen CreateEditorScreen() => new();
    method CreateBeatmap (line 24) | protected override KaraokeBeatmap CreateBeatmap()
    method load (line 50) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestSceneSingerScreen.cs
  class TestSceneSingerScreen (line 17) | [TestFixture]
    method CreateEditorScreen (line 22) | protected override SingerScreen CreateEditorScreen() => new();
    method CreateBeatmap (line 24) | protected override KaraokeBeatmap CreateBeatmap()
    method load (line 67) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Beatmap/TestSceneTranslationsScreen.cs
  class TestSceneTranslationsScreen (line 17) | [TestFixture]
    method CreateEditorScreen (line 22) | protected override TranslationScreen CreateEditorScreen() => new();
    method CreateBeatmap (line 24) | protected override KaraokeBeatmap CreateBeatmap()
    method load (line 41) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Components/Issues/TestSceneIssueIcon.cs
  class TestSceneIssueIcon (line 13) | [TestFixture]
    method SetUp (line 18) | [SetUp]
    method TestDisplayIconByIssues (line 29) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Components/Issues/TestSceneIssuesToolTip.cs
  class TestSceneIssuesToolTip (line 14) | [TestFixture]
    method SetUp (line 19) | [SetUp]
    method TestTooltipWithoutIssue (line 30) | [Test]
    method TestTooltipWithIssue (line 39) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Components/Markdown/TestSceneDescriptionTextFlowContainer.cs
  class TestSceneDescriptionTextFlowContainer (line 16) | [TestFixture]
    method SetUp (line 24) | [SetUp]
    method TestDisplayDescription (line 39) | [Test]
    method TestDisplayDescriptionWithKey (line 51) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/GenericEditorScreenTestScene.cs
  class GenericEditorScreenTestScene (line 18) | public abstract partial class GenericEditorScreenTestScene<TScreen, TTyp...
    method GenericEditorScreenTestScene (line 28) | protected GenericEditorScreenTestScene()
    method LoadComplete (line 33) | protected override void LoadComplete()
    method CreateEditorScreen (line 49) | protected abstract GenericEditorScreen<TType> CreateEditorScreen();
    method CreateBeatmap (line 51) | protected virtual KaraokeBeatmap CreateBeatmap()

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/GenericEditorTestScene.cs
  class GenericEditorTestScene (line 18) | public abstract partial class GenericEditorTestScene<TEditor, TScreenMod...
    method CreateScreen (line 28) | protected override TEditor CreateScreen() => new();
    method GenericEditorTestScene (line 32) | protected GenericEditorTestScene()
    method load (line 38) | [BackgroundDependencyLoader]
    method CreateBeatmap (line 57) | protected virtual KaraokeBeatmap CreateBeatmap()
    class EditorBeatmapDependencyContainer (line 66) | private partial class EditorBeatmapDependencyContainer : Container
      method EditorBeatmapDependencyContainer (line 76) | public EditorBeatmapDependencyContainer(IBeatmap beatmap, BindableBe...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Import/TestSceneLyricImporter.cs
  class TestSceneLyricImporter (line 21) | [TestFixture]
    method CreateScreen (line 32) | protected override TestLyricImporter CreateScreen()
    method load (line 40) | [BackgroundDependencyLoader]
    method TestGoToStep (line 53) | [Test]
    class TestLyricImporter (line 64) | public partial class TestLyricImporter : LyricImporter
      method TestLyricImporter (line 70) | public TestLyricImporter(FileInfo fileInfo)
      method LoadComplete (line 75) | protected override void LoadComplete()
      method GoToStep (line 85) | public void GoToStep(LyricImporterStep step)

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Stages/Classic/ClassicStageScreenTestScene.cs
  class ClassicStageScreenTestScene (line 8) | public abstract partial class ClassicStageScreenTestScene<T> : GenericEd...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Stages/Classic/TestSceneClassicStageEditor.cs
  class TestSceneClassicStageEditor (line 8) | public partial class TestSceneClassicStageEditor : GenericEditorTestScen...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Stages/Classic/TestSceneConfigScreen.cs
  class TestSceneConfigScreen (line 8) | public partial class TestSceneConfigScreen : ClassicStageScreenTestScene...
    method CreateEditorScreen (line 10) | protected override ConfigScreen CreateEditorScreen() => new();

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Edit/Stages/Classic/TestSceneStageScreen.cs
  class TestSceneStageScreen (line 11) | [Ignore("Ingore this test until able to edit the stage.")]
    method CreateEditorScreen (line 14) | protected override StageScreen CreateEditorScreen() => new();
    method TestSwitchCategoryAndEditMode (line 16) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/ScreenTestScene.cs
  class ScreenTestScene (line 9) | public abstract partial class ScreenTestScene<T> : ScreenTestScene where...
    method SetUpSteps (line 13) | public override void SetUpSteps()
    method LoadScreen (line 21) | protected virtual void LoadScreen()
    method CreateScreen (line 26) | protected abstract T CreateScreen();

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Settings/Previews/TestSceneMicrophoneSoundVisualizer.cs
  class TestSceneMicrophoneSoundVisualizer (line 12) | [TestFixture]
    method SetUp (line 17) | [SetUp]

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Settings/TestSceneKaraokeSettings.cs
  class TestSceneKaraokeSettings (line 9) | [TestFixture]
    method CreateScreen (line 12) | protected override KaraokeSettings CreateScreen() => new();

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Skin/KaraokeSkinEditorScreenTestScene.cs
  class KaraokeSkinEditorScreenTestScene (line 21) | public abstract partial class KaraokeSkinEditorScreenTestScene<T> : Edit...
    method KaraokeSkinEditorScreenTestScene (line 32) | protected KaraokeSkinEditorScreenTestScene()
    method LoadComplete (line 38) | protected override void LoadComplete()
    method CreateEditorScreen (line 54) | protected abstract T CreateEditorScreen(KaraokeSkin karaokeSkin);
    class TestKaraokeBeatmapSkin (line 56) | protected class TestKaraokeBeatmapSkin : KaraokeBeatmapSkin
      method TestKaraokeBeatmapSkin (line 58) | public TestKaraokeBeatmapSkin()
    method createBeatmap (line 64) | private KaraokeBeatmap createBeatmap()

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Skin/TestSceneConfigScreen.cs
  class TestSceneConfigScreen (line 9) | public partial class TestSceneConfigScreen : KaraokeSkinEditorScreenTest...
    method CreateEditorScreen (line 11) | protected override ConfigScreen CreateEditorScreen(KaraokeSkin karaoke...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Skin/TestSceneKaraokeSkinEditor.cs
  class TestSceneKaraokeSkinEditor (line 19) | public partial class TestSceneKaraokeSkinEditor : ScreenTestScene<Karaok...
    method load (line 33) | [BackgroundDependencyLoader]
    method CreateScreen (line 41) | protected override KaraokeSkinEditor CreateScreen() => new(karaokeSkin);
    class TestingSkin (line 47) | public class TestingSkin : KaraokeSkin
      method CreateInfo (line 51) | public static SkinInfo CreateInfo() => new()
      method TestingSkin (line 60) | public TestingSkin(IStorageResourceProvider? resources)
      method TestingSkin (line 65) | [UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructo...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/Skin/TestSceneStyleScreen.cs
  class TestSceneStyleScreen (line 10) | [TestFixture]
    method CreateEditorScreen (line 14) | protected override StyleScreen CreateEditorScreen(KaraokeSkin karaokeS...

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/TestManageFontPreview.cs
  class TestManageFontPreview (line 16) | public partial class TestManageFontPreview : OsuTestScene
    method TestManageFontPreview (line 20) | public TestManageFontPreview()
    method load (line 32) | [BackgroundDependencyLoader]
    method LoadComplete (line 46) | protected override void LoadComplete()

FILE: osu.Game.Rulesets.Karaoke.Tests/Screens/TestSceneGeneratorConfigPopover.cs
  class TestSceneGeneratorConfigPopover (line 14) | [TestFixture]
    method load (line 20) | [BackgroundDependencyLoader]
    method TestPopover (line 28) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/Fonts/BitmapFontCompressorTest.cs
  class BitmapFontGeneratorTest (line 18) | public class BitmapFontGeneratorTest
    method OneTimeSetUp (line 22) | [OneTimeSetUp]
    method TestCompress (line 37) | [TestCase("A", 1)]
    method TestGeneratePage (line 69) | [TestCase(new int[] { }, new string[] { })]
    method TestGenerateCharactersPropertyWithSingleLine (line 89) | [TestCase("A")]
    method TestGenerateCharactersPropertyWithMultiLine (line 126) | [TestCase("A")]
    method TestGenerateCharactersPropertyWithMultiPage (line 159) | [TestCase("A")]
    method TestGenerateAllCharacters (line 194) | [Test]
    method TestGenerateCharactersIfNotExist (line 207) | [TestCase("カラオケ", 0)]
    method TestGenerateKerningPairs (line 218) | [TestCase("", 0)]
    method TestGenerateKerningPairsWithAllChars (line 232) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/Fonts/BitmapFontImageGeneratorTest.cs
  class BitmapFontImageGeneratorTest (line 17) | public class BitmapFontImageGeneratorTest
    method OneTimeSetUp (line 23) | [OneTimeSetUp]
    method TestGenerate (line 38) | [Test]
    method TestGeneratePage (line 55) | [Test]
    class TestFntGlyphStore (line 72) | private class TestFntGlyphStore : FntGlyphStore
      method TestFntGlyphStore (line 74) | public TestFntGlyphStore(ResourceStore<byte[]> store, string assetName)
      method GetPageImage (line 80) | public new TextureUpload GetPageImage(int page)

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/KaraokeBeatmapSkinDecodingTest.cs
  class KaraokeBeatmapSkinDecodingTest (line 13) | public class KaraokeBeatmapSkinDecodingTest
    method TestKaraokeBeatmapSkinDefaultValue (line 15) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/KaraokeHitObjectTestScene.cs
  class KaraokeHitObjectTestScene (line 17) | public abstract partial class KaraokeHitObjectTestScene : KaraokeSkinnab...
    method load (line 21) | [BackgroundDependencyLoader]
    method CreateHitObject (line 55) | protected abstract DrawableHitObject CreateHitObject();

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/KaraokeSkinDecodingTest.cs
  class KaraokeSkinDecodingTest (line 13) | public class KaraokeSkinDecodingTest
    method TestKaraokeSkinDefaultValue (line 15) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/KaraokeSkinnableColumnTestScene.cs
  class KaraokeSkinnableColumnTestScene (line 23) | public abstract partial class KaraokeSkinnableColumnTestScene : KaraokeS...
    method KaraokeSkinnableColumnTestScene (line 36) | protected KaraokeSkinnableColumnTestScene()
    method load (line 48) | [BackgroundDependencyLoader]
    method TestScrollingDown (line 58) | [Test]
    method TestScrollingUp (line 64) | [Test]
    class TestScrollingInfo (line 70) | private class TestScrollingInfo : IScrollingInfo
    class ZeroScrollAlgorithm (line 79) | private class ZeroScrollAlgorithm : IScrollAlgorithm
      method GetDisplayStartTime (line 81) | public double GetDisplayStartTime(double originTime, float offset, d...
      method GetLength (line 84) | public float GetLength(double startTime, double endTime, double time...
      method PositionAt (line 87) | public float PositionAt(double time, double currentTime, double time...
      method TimeAt (line 90) | public double TimeAt(float position, double currentTime, double time...
      method Reset (line 93) | public void Reset()
    class PreviewNotePositionInfo (line 98) | private class PreviewNotePositionInfo : INotePositionInfo

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/KaraokeSkinnableTestScene.cs
  class KaraokeSkinnableTestScene (line 10) | public abstract partial class KaraokeSkinnableTestScene : SkinnableTestS...
    method CreateBeatmap (line 12) | protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new ...
    method CreateRulesetForSkinProvider (line 14) | protected override Ruleset CreateRulesetForSkinProvider() => new Karao...

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/NotePlayfieldTestContainer.cs
  class NotePlayfieldTestContainer (line 14) | public partial class NotePlayfieldTestContainer : Container
    method NotePlayfieldTestContainer (line 23) | public NotePlayfieldTestContainer(int column)

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneColumnBackground.cs
  class TestSceneColumnBackground (line 13) | public partial class TestSceneColumnBackground : KaraokeSkinnableColumnT...
    method load (line 15) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneDrawableJudgement.cs
  class TestSceneDrawableJudgement (line 15) | public partial class TestSceneDrawableJudgement : KaraokeSkinnableTestScene
    method TestSceneDrawableJudgement (line 17) | public TestSceneDrawableJudgement()

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneHitExplosion.cs
  class TestSceneHitExplosion (line 18) | [TestFixture]
    method TestSceneHitExplosion (line 21) | public TestSceneHitExplosion()
    method load (line 45) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneLyric.cs
  class TestSceneLyric (line 18) | [TestFixture]
    method TestSceneLyric (line 23) | public TestSceneLyric()
    method testSingle (line 28) | private Drawable testSingle(double timeOffset = 0)
    method CreateDrawableLyric (line 81) | protected virtual TestDrawableLyric CreateDrawableLyric(Lyric lyric)
    class TestDrawableLyric (line 89) | protected partial class TestDrawableLyric : DrawableLyric
      method TestDrawableLyric (line 91) | public TestDrawableLyric(Lyric h)

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneNote.cs
  class TestSceneNote (line 16) | public partial class TestSceneNote : KaraokeHitObjectTestScene
    method TestSceneNote (line 18) | public TestSceneNote()
    method CreateHitObject (line 29) | protected override DrawableHitObject CreateHitObject()

FILE: osu.Game.Rulesets.Karaoke.Tests/Skinning/TestSceneNotePlayfield.cs
  class TestSceneNotePlayfield (line 9) | public partial class TestSceneNotePlayfield : KaraokeSkinnableColumnTest...
    method load (line 11) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/Stages/Drawables/TestSceneDrawableStageBeatmapCoverInfo.cs
  class TestSceneDrawableStageBeatmapCoverInfo (line 13) | public partial class TestSceneDrawableStageBeatmapCoverInfo : OsuTestScene
    method TestSceneDrawableStageBeatmapCoverInfo (line 17) | public TestSceneDrawableStageBeatmapCoverInfo()
    method TestSize (line 26) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Stages/Infos/Classic/ClassicLyricTimingInfoTest.cs
  class ClassicLyricTimingInfoTest (line 12) | public class ClassicLyricTimingInfoTest
    method TestAddTimingPoint (line 16) | [Test]
    method TestRemoveTimingPoint (line 32) | [Test]
    method TestAddToMapping (line 47) | [Test]
    method TestRemoveFromMapping (line 70) | [Test]
    method TestClearTimingPointFromMapping (line 96) | [Test]
    method TestClearLyricFromMapping (line 122) | [Test]
    method TestGetTimingPointOrder (line 152) | [Test]
    method TestGetLyricTimingPoints (line 167) | [Test]
    method TestGetStartAndEndTime (line 186) | [TestCase("[2000,3000]:カラオケ", new double[] { 1000, 4000 }, 1000, 4000)]
    method TestGetStartTime (line 210) | [Test]
    method TestGetEndTime (line 226) | [Test]
    method TestGetMatchedLyricIds (line 242) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Stages/Infos/Preview/PreviewStageTimingCalculatorTest.cs
  class PreviewStageTimingCalculatorTest (line 17) | public class PreviewStageTimingCalculatorTest
    method TestGetStartTime (line 35) | [TestCase(lyric_1_id, 0)]
    method TestGetEndTime (line 50) | [TestCase(lyric_1_id, 2000)]
    method TestGetTiming (line 65) | [TestCase(lyric_1_id, new string[] { })]
    method convertKeyToDictionary (line 81) | private static IDictionary<int, double> convertKeyToDictionary(IEnumer...
    method createCalculator (line 84) | private PreviewStageTimingCalculator createCalculator(IBeatmap beatmap)
    method createBeatmap (line 97) | private IBeatmap createBeatmap()
    method createLyric (line 115) | private static Lyric createLyric(int id, double startTime, double endT...

FILE: osu.Game.Rulesets.Karaoke.Tests/Stages/Infos/StageElementCategoryTest.cs
  class StageElementCategoryTest (line 14) | public class StageElementCategoryTest
    method TestAddElement (line 18) | [Test]
    method TestEditElement (line 37) | [Test]
    method TestRemoveElement (line 54) | [Test]
    method TestClearElements (line 82) | [Test]
    method TestAddToMapping (line 109) | [Test]
    method TestRemoveHitObjectFromMapping (line 130) | [Test]
    method TestRemoveElementFromMapping (line 146) | [Test]
    method TestClearUnusedMapping (line 162) | [Test]
    method TestGetElementByItem (line 192) | [Test]
    method TestGetHitObjectIdsByElement (line 211) | [Test]
    class TestStageElement (line 231) | private class TestStageElement : StageElement, IComparable<TestStageEl...
      method CompareTo (line 233) | public int CompareTo(TestStageElement? other)
    class TestStageElementCategory (line 241) | private class TestStageElementCategory : StageElementCategory<TestStag...
      method CreateDefaultElement (line 243) | protected override TestStageElement CreateDefaultElement()

FILE: osu.Game.Rulesets.Karaoke.Tests/TestSceneOsuGame.cs
  class TestSceneOsuGame (line 12) | public partial class TestSceneOsuGame : OsuTestScene
    method load (line 14) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/Position/NotePositionCalculatorTest.cs
  class NotePositionCalculatorTest (line 12) | [TestFixture]
    method TestPositionAtTone (line 19) | [TestCase(0, 0)]
    method TestPositionAtNote (line 34) | [TestCase(0, 0)]
    method TestPositionAtScoringAction (line 46) | [TestCase(0f, 0)]
    method TestPositionAtReplayFrame (line 61) | [TestCase(0f, 0)]
    method TestPositionAtScale (line 73) | [TestCase(0f, 0)]
    method TestGetMaxTone (line 86) | [TestCase(1, 0)]
    method TestGetMinTone (line 96) | [TestCase(1, 0)]

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/TestSceneControlLayer.cs
  class TestSceneControlLayer (line 14) | [TestFixture]
    method CreateRuleset (line 19) | protected override Ruleset CreateRuleset() => new KaraokeRuleset();
    method load (line 21) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/TestSceneKaraokePlayer.cs
  class TestSceneKaraokePlayer (line 11) | [TestFixture]
    method CreateBeatmap (line 14) | protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new ...
    method CreatePlayerRuleset (line 16) | protected override Ruleset CreatePlayerRuleset() => new KaraokeRuleset();

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/TestSceneNotePlayfield.cs
  class TestSceneNotePlayfield (line 28) | [TestFixture]
    method CreateRuleset (line 41) | protected override Ruleset CreateRuleset() => new KaraokeRuleset();
    method load (line 43) | [BackgroundDependencyLoader]
    method LoadComplete (line 68) | protected override void LoadComplete()
    method createNote (line 110) | private void createNote(double increaseTime = 2000, double duration = ...
    method createScoringPath (line 133) | private void createScoringPath(double increaseTime = 2000, double dura...
    method createBar (line 148) | private void createBar(bool isMajor, double increaseTime = 2000)
    method createColumn (line 159) | private Drawable createColumn(ScrollingDirection direction, int column)
    class PreviewNotePositionInfo (line 180) | private class PreviewNotePositionInfo : INotePositionInfo

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/TestSceneRulesetIcon.cs
  class TestSceneRulesetIcon (line 12) | [TestFixture]
    method TestSceneRulesetIcon (line 15) | public TestSceneRulesetIcon()

FILE: osu.Game.Rulesets.Karaoke.Tests/UI/TestSceneScoringStatus.cs
  class TestSceneScoringStatus (line 11) | [TestFixture]
    method TestMode (line 14) | [TestCase(ScoringStatusMode.AndroidMicrophonePermissionDeclined)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/BindablesUtilsTest.cs
  class BindablesUtilsTest (line 11) | public class BindablesUtilsTest
    method TestSyncWithAddItems (line 13) | [TestCase(null, null, new[] { 1 }, null, new[] { 1 }, new[] { 1 })]
    method TestSyncWithRemoveItems (line 36) | [TestCase(null, null, new[] { 1 }, null, new int[] { }, new int[] { })...
    method TestOnyWaySyncWithAddItems (line 63) | [TestCase(new[] { 1 }, null, null, new[] { 1 })] // should sync defaul...
    method TestOnyWaySyncWithRemoveItems (line 84) | [TestCase(new[] { 1, 2, 3 }, null, new[] { 1 }, new[] { 2, 3 })]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/CharUtilsTest.cs
  class CharUtilsTest (line 9) | [TestFixture]
    method TestIsSpacing (line 12) | [TestCase(' ', true)]
    method TestIsKana (line 21) | [TestCase('ひ', true)]
    method TestIsEnglish (line 37) | [TestCase('A', true)]
    method TestIsAsciiSymbol (line 49) | [TestCase(':', true)]
    method TestIsChinese (line 61) | [TestCase('你', true)]
    method TestIsLatin (line 80) | [TestCase('A', true)]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/ComparableUtilsTest.cs
  class ComparableUtilsTest (line 11) | public class ComparableUtilsTest
    method TestCompare (line 13) | [TestCase("{\"A\":0,\"B\":0,\"C\":\" \"}", "{\"A\":0,\"B\":0,\"C\":\" ...
    method TestCompareByProperty (line 32) | [TestCase("{\"A\":0,\"B\":0,\"C\":\" \"}", "{\"A\":0,\"B\":0,\"C\":\" ...
    class TestObject (line 51) | private class TestObject

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/CultureInfoUtilsTest.cs
  class CultureInfoUtilsTest (line 11) | public class CultureInfoUtilsTest
    method TestGetAvailableLanguages (line 13) | [Test]
    method TestGetAvailableLanguagesWithUniqueLcid (line 23) | [Test]
    method TestIsLanguage (line 39) | [TestCase("zh-Hans", true)] // 中文(简体), 4
    method TestIsLanguage (line 52) | [TestCase(4, true)] // 中文(简体)
    method TestGetLanguageDisplayText (line 63) | [TestCase(4, "中文(简体)")]
    method TestSaveAndLoadCultureInfoById (line 75) | [Test]
    method TestSaveAndLoadCultureInfoByCode (line 93) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/EnumUtilsTest.cs
  class EnumUtilsTest (line 10) | [TestFixture]
    method TestGetPreviousValue (line 13) | [TestCase(TestEnum.Enum1, TestEnum.Enum3)]
    method TestGetNextValue (line 22) | [TestCase(TestEnum.Enum1, TestEnum.Enum2)]
    method TestCasting (line 31) | [TestCase(TestEnum.Enum1, TestEnum.Enum1)]
    type TestEnum (line 41) | public enum TestEnum
    type TestEnum2 (line 50) | public enum TestEnum2

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/FontUsageUtilsTest.cs
  class FontUsageUtilsTest (line 11) | [TestFixture]
    method TestToFontInfo (line 14) | [TestCase("OpenSans", null, false, "OpenSans")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/FontUtilsTest.cs
  class FontUtilsTest (line 9) | [TestFixture]
    method TestGetText (line 12) | [TestCase(10, "10 px")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/JpStringUtilsTest.cs
  class JpStringUtilsTest (line 9) | [TestFixture]
    method TestToHiragana (line 12) | [TestCase("ハナビ", "はなび")]
    method TestToKatakana (line 21) | [TestCase("はなび", "ハナビ")]
    method TestToRomaji (line 30) | [TestCase("はなび", "hanabi")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/RectangleFUtilsTest.cs
  class RectangleFUtilsTest (line 14) | public class RectangleFUtilsTest
    method TestUnion (line 16) | [TestCase(new[] { "[5,5,10,10]" }, "[5,5,10,10]")]
    method convertTestCaseToValue (line 31) | private RectangleF convertTestCaseToValue(string str)

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/TextIndexUtilsTest.cs
  class TextIndexUtilsTest (line 10) | [TestFixture]
    method TestToGapIndex (line 13) | [TestCase(0, TextIndex.IndexState.Start, 0)]
    method TestToCharIndex (line 25) | [TestCase(0, TextIndex.IndexState.Start, 0)]
    method TestFromStringIndex (line 37) | [TestCase(0, false, 0, TextIndex.IndexState.Start)]
    method TestReverseState (line 47) | [TestCase(TextIndex.IndexState.Start, TextIndex.IndexState.End)]
    method TestGetPreviousIndex (line 55) | [TestCase(1, TextIndex.IndexState.End, 1, TextIndex.IndexState.Start)]
    method TestGetNextIndex (line 68) | [TestCase(0, TextIndex.IndexState.Start, 0, TextIndex.IndexState.End)]
    method TestShiftingIndex (line 81) | [TestCase(0, TextIndex.IndexState.Start, 1, 1, TextIndex.IndexState.St...
    method TestOutOfRange (line 94) | [TestCase(0, TextIndex.IndexState.Start, "karaoke", false)]
    method TestGetValueByState (line 108) | [TestCase(TextIndex.IndexState.Start, 1, -1, 1)]
    method TestPositionFormattedString (line 129) | [TestCase(0, TextIndex.IndexState.Start, "0")]

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/TypeUtilsTest.cs
  class TypeUtilsTest (line 11) | public class TypeUtilsTest
    method TestChangeTypeToSameType (line 13) | [Test]
    method TestChangeTypeToDifferentType (line 33) | [Test]
    class TestClass (line 47) | private class TestClass;

FILE: osu.Game.Rulesets.Karaoke.Tests/Utils/VersionUtilsTest.cs
  class VersionUtilsTest (line 10) | public class VersionUtilsTest
    method TestGetVersion (line 12) | [Test]
    method TestMajorVersionName (line 24) | [Test]
    method TestIsDeployedBuild (line 32) | [Test]
    method TestGetDisplayVersion (line 41) | [Test]

FILE: osu.Game.Rulesets.Karaoke.Tests/VisualTestRunner.cs
  class VisualTestRunner (line 9) | public static class VisualTestRunner
    method Main (line 11) | [STAThread]

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/ElementId.cs
  type ElementId (line 13) | public readonly struct ElementId : IComparable, IComparable<ElementId>, ...
    method ElementId (line 21) | public ElementId(string id)
    method checkFormat (line 42) | private static bool checkFormat(string id)
    method NewElementId (line 45) | public static ElementId NewElementId()
    method CompareTo (line 53) | public int CompareTo(ElementId other)
    method CompareTo (line 58) | public int CompareTo(object? obj)
    method Equals (line 73) | public bool Equals(ElementId other)
    method Equals (line 78) | public override bool Equals(object? obj)
    method GetHashCode (line 87) | public override int GetHashCode()
    method ToString (line 92) | public override string ToString()

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapDecoder.cs
  class KaraokeJsonBeatmapDecoder (line 17) | public class KaraokeJsonBeatmapDecoder : JsonBeatmapDecoder
    method Register (line 19) | public new static void Register()
    method ParseStreamInto (line 27) | protected override void ParseStreamInto(LineBufferedReader stream, Bea...
    class KaraokeBeatmapContractResolver (line 45) | private class KaraokeBeatmapContractResolver : SnakeCaseKeyContractRes...
      method CreateProperties (line 47) | protected override IList<JsonProperty> CreateProperties(Type type, M...

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapEncoder.cs
  class KaraokeJsonBeatmapEncoder (line 10) | public class KaraokeJsonBeatmapEncoder
    method Encode (line 12) | public string Encode(Beatmap output)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapDecoder.cs
  class KaraokeLegacyBeatmapDecoder (line 17) | public class KaraokeLegacyBeatmapDecoder : LegacyBeatmapDecoder
    method Register (line 21) | public new static void Register()
    method KaraokeLegacyBeatmapDecoder (line 29) | public KaraokeLegacyBeatmapDecoder(int version = LATEST_VERSION)
    method ParseLine (line 38) | protected override void ParseLine(Beatmap beatmap, Section section, st...
    method processNotes (line 89) | private void processNotes(Beatmap beatmap, IList<string> lines)
    method processTranslations (line 216) | private void processTranslations(Beatmap beatmap, IEnumerable<string> ...
    method SliceNote (line 255) | internal static Note SliceNote(Note note, double startPercentage, doub...

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapEncoder.cs
  class KaraokeLegacyBeatmapEncoder (line 13) | public class KaraokeLegacyBeatmapEncoder
    method Encode (line 15) | public string Encode(Beatmap output)
    method encodeNotes (line 28) | private IEnumerable<string> encodeNotes(Beatmap output)
    method encodeTranslations (line 65) | private IEnumerable<string> encodeTranslations(Beatmap output)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/IHasPrimaryKey.cs
  type IHasPrimaryKey (line 8) | public interface IHasPrimaryKey
  class PrimaryKeyObjectExtension (line 13) | public static class PrimaryKeyObjectExtension
    method ChangeId (line 15) | public static TObject ChangeId<TObject>(this TObject obj, ElementId id)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/IKaraokeBeatmapResourcesProvider.cs
  type IKaraokeBeatmapResourcesProvider (line 9) | public interface IKaraokeBeatmapResourcesProvider
    method GetSingerAvatar (line 11) | Texture? GetSingerAvatar(ISinger singer);

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmap.cs
  class KaraokeBeatmap (line 14) | public class KaraokeBeatmap : Beatmap<KaraokeHitObject>
    method GetStatistics (line 26) | public override IEnumerable<BeatmapStatistic> GetStatistics()

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapConverter.cs
  class KaraokeBeatmapConverter (line 14) | public class KaraokeBeatmapConverter : BeatmapConverter<KaraokeHitObject>
    method KaraokeBeatmapConverter (line 16) | public KaraokeBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
    method CanConvert (line 21) | public override bool CanConvert() => Beatmap.HitObjects.All(h => h is ...
    method ConvertBeatmap (line 23) | protected override Beatmap<KaraokeHitObject> ConvertBeatmap(IBeatmap o...
    method ConvertHitObject (line 42) | protected override IEnumerable<KaraokeHitObject> ConvertHitObject(HitO...
    method CreateBeatmap (line 45) | protected override Beatmap<KaraokeHitObject> CreateBeatmap() => new Ka...

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapExtension.cs
  class KaraokeBeatmapExtension (line 11) | public static class KaraokeBeatmapExtension
    method IsScorable (line 13) | public static bool IsScorable(this IBeatmap beatmap)
    method AvailableTranslationLanguages (line 20) | public static IList<CultureInfo> AvailableTranslationLanguages(this IB...
    method AnyTranslation (line 22) | public static bool AnyTranslation(this IBeatmap beatmap) => beatmap.Av...
    method PitchToScale (line 24) | public static float PitchToScale(this IBeatmap beatmap, float pitch)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs
  class KaraokeBeatmapProcessor (line 12) | public class KaraokeBeatmapProcessor : BeatmapProcessor
    method KaraokeBeatmapProcessor (line 14) | public KaraokeBeatmapProcessor(IBeatmap beatmap)
    method PreProcess (line 19) | public override void PreProcess()
    method applyInvalidProperty (line 38) | private void applyInvalidProperty(KaraokeBeatmap beatmap)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapResourcesProvider.cs
  class KaraokeBeatmapResourcesProvider (line 13) | public partial class KaraokeBeatmapResourcesProvider : Component, IKarao...
    method GetSingerAvatar (line 21) | public Texture? GetSingerAvatar(ISinger singer)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/NoteInfo.cs
  class NoteInfo (line 8) | public class NoteInfo

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Page.cs
  class Page (line 11) | public class Page : IDeepCloneable<Page>, IComparable<Page>
    method DeepClone (line 22) | public Page DeepClone()
    method CompareTo (line 30) | public int CompareTo(Page? other) => Time.CompareTo(other?.Time);
    method GetHashCode (line 32) | public override int GetHashCode() => Time.GetHashCode();

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/PageInfo.cs
  class PageInfo (line 15) | public class PageInfo : IDeepCloneable<PageInfo>
    method PageInfo (line 27) | public PageInfo()
    method GetPageAt (line 61) | public Page? GetPageAt(double time)
    method GetPageIndexAt (line 76) | public int? GetPageIndexAt(double time)
    method GetPageOrder (line 85) | public int? GetPageOrder(Page page)
    method DeepClone (line 91) | public PageInfo DeepClone()

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Singer.cs
  class Singer (line 10) | public class Singer : ISinger

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerInfo.cs
  class SingerInfo (line 12) | public class SingerInfo
    method GetAllSingers (line 22) | public IEnumerable<Singer> GetAllSingers() =>
    method GetAllAvailableSingerStates (line 25) | public IEnumerable<SingerState> GetAllAvailableSingerStates(Singer sin...
    method GetSingerByIds (line 28) | public IDictionary<Singer, SingerState[]> GetSingerByIds(ElementId[] s...
    method GetSingerMap (line 39) | public IDictionary<Singer, SingerState[]> GetSingerMap()
    method AddSinger (line 45) | public Singer AddSinger(Action<Singer>? action = null)
    method AddSingerState (line 55) | public SingerState AddSingerState(Singer singer, Action<SingerState>? ...
    method RemoveSinger (line 69) | public bool RemoveSinger(ISinger singer)
    method HasSinger (line 93) | public bool HasSinger(ISinger singer)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerState.cs
  class SingerState (line 10) | public class SingerState : ISinger
    method SingerState (line 12) | public SingerState()
    method SingerState (line 16) | public SingerState(ElementId mainSingerId)

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Types/ISinger.cs
  type ISinger (line 8) | public interface ISinger : IHasOrder, IHasPrimaryKey

FILE: osu.Game.Rulesets.Karaoke/Beatmaps/Utils/SingerUtils.cs
  class SingerUtils (line 13) | public static class SingerUtils
    method GetShiftingStyleIndex (line 15) | public static int GetShiftingStyleIndex(IEnumerable<int> singerIds)
    method GetSingersIndex (line 18) | public static int[] GetSingersIndex(int styleIndex)
    method GetContentColour (line 29) | public static Color4 GetContentColour(ISinger singer)
    method GetBackgroundColour (line 32) | public static Color4 GetBackgroundColour(ISinger singer)

FILE: osu.Game.Rulesets.Karaoke/Bindables/BindableCultureInfo.cs
  class BindableCultureInfo (line 12) | public class BindableCultureInfo : Bindable<CultureInfo?>
    method BindableCultureInfo (line 14) | public BindableCultureInfo(CultureInfo? value = default)
    method Parse (line 19) | public override void Parse(object? input, IFormatProvider provider)
    method CreateInstance (line 58) | protected override Bindable<CultureInfo?> CreateInstance() => new Bind...
    method ToString (line 60) | public override string ToString(string? format, IFormatProvider? forma...

FILE: osu.Game.Rulesets.Karaoke/Bindables/BindableFontUsage.cs
  class BindableFontUsage (line 13) | public class BindableFontUsage : RangeConstrainedBindable<FontUsage>
    method BindableFontUsage (line 21) | public BindableFontUsage(FontUsage value = default)
    method ToString (line 39) | public override string ToString(string? format, IFormatProvider? forma...
    method Parse (line 42) | public override void Parse(object? input, IFormatProvider provider)
    method CreateInstance (line 75) | protected override Bindable<FontUsage> CreateInstance() => new Bindabl...
    method ClampValue (line 77) | protected sealed override FontUsage ClampValue(FontUsage value, FontUs...
    method IsValidRange (line 82) | protected sealed override bool IsValidRange(FontUsage min, FontUsage max)

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetConfigManager.cs
  class KaraokeRulesetConfigManager (line 16) | public class KaraokeRulesetConfigManager : RulesetConfigManager<KaraokeR...
    method KaraokeRulesetConfigManager (line 18) | public KaraokeRulesetConfigManager(SettingsStore? settings, RulesetInf...
    method InitialiseDefaults (line 23) | protected override void InitialiseDefaults()
    method AddBindable (line 63) | protected override void AddBindable<TBindable>(KaraokeRulesetSetting l...
    method SetDefault (line 81) | protected BindableFontUsage SetDefault(KaraokeRulesetSetting setting, ...
    method CreateTrackedSettings (line 97) | public override TrackedSettings CreateTrackedSettings() => new()
  type KaraokeRulesetSetting (line 106) | public enum KaraokeRulesetSetting

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditCheckerConfigManager.cs
  class KaraokeRulesetEditCheckerConfigManager (line 9) | public class KaraokeRulesetEditCheckerConfigManager : InMemoryConfigMana...
    method InitialiseDefaults (line 11) | protected override void InitialiseDefaults()
  type KaraokeRulesetEditCheckerSetting (line 22) | public enum KaraokeRulesetEditCheckerSetting

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditConfigManager.cs
  class KaraokeRulesetEditConfigManager (line 8) | public class KaraokeRulesetEditConfigManager : InMemoryConfigManager<Kar...
  type KaraokeRulesetEditSetting (line 10) | public enum KaraokeRulesetEditSetting;

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditGeneratorConfigManager.cs
  class KaraokeRulesetEditGeneratorConfigManager (line 22) | public class KaraokeRulesetEditGeneratorConfigManager : InMemoryConfigMa...
    method InitialiseDefaults (line 24) | protected override void InitialiseDefaults()
    method SetDefault (line 59) | protected void SetDefault<T>() where T : GeneratorConfig, new()
    method CreateDefaultConfig (line 67) | protected static T CreateDefaultConfig<T>() where T : GeneratorConfig,...
    method GetSettingByType (line 69) | protected static KaraokeRulesetEditGeneratorSetting GetSettingByType<T...
    method Get (line 87) | public TValue Get<TValue>() where TValue : GeneratorConfig, new()
    method GetGeneratorConfig (line 93) | public GeneratorConfig GetGeneratorConfig(KaraokeRulesetEditGeneratorS...
  type KaraokeRulesetEditGeneratorSetting (line 106) | public enum KaraokeRulesetEditGeneratorSetting

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetLyricEditorConfigManager.cs
  class KaraokeRulesetLyricEditorConfigManager (line 13) | public class KaraokeRulesetLyricEditorConfigManager : InMemoryConfigMana...
    method InitialiseDefaults (line 15) | protected override void InitialiseDefaults()
    method BindWith (line 50) | public void BindWith<TValue>(KaraokeRulesetLyricEditorSetting lookup, ...
  type KaraokeRulesetLyricEditorSetting (line 53) | public enum KaraokeRulesetLyricEditorSetting

FILE: osu.Game.Rulesets.Karaoke/Configuration/KaraokeSessionStatics.cs
  class KaraokeSessionStatics (line 12) | public class KaraokeSessionStatics : InMemoryConfigManager<KaraokeRulese...
    method KaraokeSessionStatics (line 16) | public KaraokeSessionStatics(KaraokeRulesetConfigManager config, IBeat...
    method getValue (line 45) | private T getValue<T>(KaraokeRulesetSetting setting) => rulesetConfigM...
  type KaraokeRulesetSession (line 48) | public enum KaraokeRulesetSession

FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyAttributes.cs
  class KaraokeDifficultyAttributes (line 11) | public class KaraokeDifficultyAttributes : DifficultyAttributes
    method ToDatabaseAttributes (line 28) | public override IEnumerable<(int attributeId, object value)> ToDatabas...
    method FromDatabaseAttributes (line 36) | public override void FromDatabaseAttributes(IReadOnlyDictionary<int, d...

FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyCalculator.cs
  class KaraokeDifficultyCalculator (line 21) | public class KaraokeDifficultyCalculator : DifficultyCalculator
    method KaraokeDifficultyCalculator (line 28) | public KaraokeDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatm...
    method CreateDifficultyAttributes (line 35) | protected override DifficultyAttributes CreateDifficultyAttributes(IBe...
    method CreateDifficultyHitObjects (line 50) | protected override IEnumerable<DifficultyHitObject> CreateDifficultyHi...
    method SortObjects (line 66) | protected override IEnumerable<DifficultyHitObject> SortObjects(IEnume...
    method CreateSkills (line 68) | protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, ...
    method getHitWindow300 (line 80) | private int getHitWindow300(Mod[] mods)

FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceAttributes.cs
  class KaraokePerformanceAttributes (line 10) | public class KaraokePerformanceAttributes : PerformanceAttributes
    method GetAttributesForDisplay (line 21) | public override IEnumerable<PerformanceDisplayAttribute> GetAttributes...

FILE: osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceCalculator.cs
  class KaraokePerformanceCalculator (line 14) | public class KaraokePerformanceCalculator : PerformanceCalculator
    method KaraokePerformanceCalculator (line 26) | public KaraokePerformanceCalculator()
    method CreatePerformanceAttributes (line 31) | protected override PerformanceAttributes CreatePerformanceAttributes(S...
    method computeDifficultyValue (line 75) | private double computeDifficultyValue(KaraokeDifficultyAttributes attr...
    method computeAccuracyValue (line 111) | private double computeAccuracyValue(double difficultyValue, KaraokeDif...

FILE: osu.Game.Rulesets.Karaoke/Difficulty/Preprocessing/KaraokeDifficultyHitObject.cs
  class KaraokeDifficultyHitObject (line 11) | public class KaraokeDifficultyHitObject : DifficultyHitObject
    method KaraokeDifficultyHitObject (line 15) | public KaraokeDifficultyHitObject(HitObject hitObject, HitObject lastO...

FILE: osu.Game.Rulesets.Karaoke/Difficulty/Skills/Strain.cs
  class Strain (line 15) | public class Strain : StrainDecaySkill
    method Strain (line 29) | public Strain(Mod[] mods, NoteInfo noteInfo)
    method StrainValueOf (line 39) | protected override double StrainValueOf(DifficultyHitObject current)
    method CalculateInitialStrain (line 81) | protected override double CalculateInitialStrain(double offset, Diffic...
    method applyDecay (line 85) | private double applyDecay(double value, double deltaTime, double decay...

FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/KaraokeSelectionBlueprint.cs
  class KaraokeSelectionBlueprint (line 10) | public partial class KaraokeSelectionBlueprint<T> : HitObjectSelectionBl...
    method KaraokeSelectionBlueprint (line 13) | protected KaraokeSelectionBlueprint(T hitObject)

FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Lyrics/LyricSelectionBlueprint.cs
  class LyricSelectionBlueprint (line 8) | public partial class LyricSelectionBlueprint : KaraokeSelectionBlueprint...
    method LyricSelectionBlueprint (line 10) | public LyricSelectionBlueprint(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/Components/EditBodyPiece.cs
  class EditBodyPiece (line 13) | public partial class EditBodyPiece : Container
    method load (line 15) | [BackgroundDependencyLoader]

FILE: osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/NoteSelectionBlueprint.cs
  class NoteSelectionBlueprint (line 20) | public partial class NoteSelectionBlueprint : KaraokeSelectionBlueprint<...
    method NoteSelectionBlueprint (line 42) | public NoteSelectionBlueprint(Note note)
    method Update (line 51) | protected override void Update()
    method OnClick (line 72) | protected override bool OnClick(ClickEvent e)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapListPropertyChangeHandler.cs
  class BeatmapListPropertyChangeHandler (line 20) | public abstract partial class BeatmapListPropertyChangeHandler<TItem> : ...
    method load (line 32) | [BackgroundDependencyLoader]
    method PerformObjectChanged (line 54) | protected void PerformObjectChanged(TItem item, Action<TItem>? action)
    method GetItemsFromBeatmap (line 62) | protected abstract IList<TItem> GetItemsFromBeatmap(KaraokeBeatmap bea...
    method Add (line 64) | public void Add(TItem item)
    method Remove (line 77) | public void Remove(TItem item)
    method OnItemAdded (line 90) | protected abstract void OnItemAdded(TItem item);
    method OnItemRemoved (line 92) | protected abstract void OnItemRemoved(TItem item);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs
  class BeatmapPropertyChangeHandler (line 19) | public partial class BeatmapPropertyChangeHandler : Component
    method BeatmapPropertyChangeHandler (line 30) | protected BeatmapPropertyChangeHandler()
    method PerformBeatmapChanged (line 35) | protected void PerformBeatmapChanged(Action<KaraokeBeatmap> action)
    method PerformOnSelection (line 54) | protected void PerformOnSelection<T>(Action<T> action) where T : HitOb...
    method InvalidateAllHitObjectWorkingProperty (line 89) | protected void InvalidateAllHitObjectWorkingProperty<TWorkingProperty>...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapPagesChangeHandler.cs
  class BeatmapPagesChangeHandler (line 16) | public partial class BeatmapPagesChangeHandler : BeatmapPropertyChangeHa...
    method CanGenerate (line 23) | public bool CanGenerate()
    method GetGeneratorNotSupportedMessage (line 30) | public LocalisableString? GetGeneratorNotSupportedMessage()
    method AutoGenerate (line 37) | public void AutoGenerate()
    method getGeneratorConfig (line 52) | private PageGeneratorConfig getGeneratorConfig()
    method Add (line 57) | public void Add(Page page)
    method Remove (line 68) | public void Remove(Page page)
    method RemoveRange (line 79) | public void RemoveRange(IEnumerable<Page> pages)
    method ShiftingPageTime (line 93) | public void ShiftingPageTime(IEnumerable<Page> pages, double offset)
    method checkPageExist (line 107) | private static bool checkPageExist(PageInfo pageInfo, Page page)
    method performPageInfoChanged (line 112) | private void performPageInfoChanged(Action<PageInfo> action)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapSingersChangeHandler.cs
  class BeatmapSingersChangeHandler (line 17) | public partial class BeatmapSingersChangeHandler : BeatmapPropertyChange...
    method ChangeOrder (line 29) | public void ChangeOrder(ISinger singer, int newIndex)
    method ChangeSingerAvatar (line 42) | public bool ChangeSingerAvatar(Singer singer, FileInfo fileInfo)
    method Add (line 75) | public Singer Add()
    method Remove (line 88) | public void Remove(Singer singer)
    method performSingerInfoChanged (line 102) | private void performSingerInfoChanged(Action<SingerInfo> action)
    method performSingerChanged (line 110) | private void performSingerChanged<TSinger>(TSinger singer, Action<TSin...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapTranslationsChangeHandler.cs
  class BeatmapTranslationsChangeHandler (line 12) | public partial class BeatmapTranslationsChangeHandler : BeatmapListPrope...
    method GetItemsFromBeatmap (line 16) | protected override IList<CultureInfo> GetItemsFromBeatmap(KaraokeBeatm...
    method OnItemAdded (line 19) | protected override void OnItemAdded(CultureInfo item)
    method OnItemRemoved (line 24) | protected override void OnItemRemoved(CultureInfo item)
    method IsLanguageContainsTranslation (line 33) | public bool IsLanguageContainsTranslation(CultureInfo cultureInfo)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapPagesChangeHandler.cs
  type IBeatmapPagesChangeHandler (line 10) | public interface IBeatmapPagesChangeHandler : IAutoGenerateChangeHandler
    method GetGeneratorNotSupportedMessage (line 12) | LocalisableString? GetGeneratorNotSupportedMessage();
    method Add (line 14) | void Add(Page page);
    method Remove (line 16) | void Remove(Page page);
    method RemoveRange (line 18) | void RemoveRange(IEnumerable<Page> pages);
    method ShiftingPageTime (line 20) | void ShiftingPageTime(IEnumerable<Page> pages, double offset);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapSingersChangeHandler.cs
  type IBeatmapSingersChangeHandler (line 11) | public interface IBeatmapSingersChangeHandler
    method ChangeOrder (line 16) | void ChangeOrder(ISinger singer, int newIndex);
    method ChangeSingerAvatar (line 18) | bool ChangeSingerAvatar(Singer singer, FileInfo fileInfo);
    method Add (line 20) | Singer Add();
    method Remove (line 22) | void Remove(Singer singer);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapTranslationsChangeHandler.cs
  type IBeatmapTranslationsChangeHandler (line 9) | public interface IBeatmapTranslationsChangeHandler
    method Add (line 13) | void Add(CultureInfo culture);
    method Remove (line 15) | void Remove(CultureInfo culture);
    method IsLanguageContainsTranslation (line 17) | bool IsLanguageContainsTranslation(CultureInfo cultureInfo);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ChangeForbiddenException.cs
  class ChangeForbiddenException (line 8) | public class ChangeForbiddenException : InvalidOperationException
    method ChangeForbiddenException (line 10) | public ChangeForbiddenException(string message)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs
  class HitObjectChangeHandler (line 18) | public abstract partial class HitObjectChangeHandler<THitObject> : Compo...
    method HitObjectChangeHandler (line 29) | protected HitObjectChangeHandler()
    method CheckExactlySelectedOneHitObject (line 34) | protected void CheckExactlySelectedOneHitObject()
    method NotTriggerSaveStateOnThisChange (line 43) | protected void NotTriggerSaveStateOnThisChange()
    method PerformOnSelection (line 48) | protected virtual void PerformOnSelection(Action<THitObject> action)
    method PerformOnSelection (line 51) | protected void PerformOnSelection<T>(Action<T> action) where T : HitOb...
    method AddRange (line 100) | protected void AddRange<T>(IEnumerable<T> hitObjects) where T : HitObj...
    method Add (line 102) | protected virtual void Add<T>(T hitObject) where T : HitObject
    method Insert (line 114) | protected virtual void Insert<T>(int index, T hitObject) where T : Hit...
    method RemoveRange (line 126) | protected void RemoveRange<T>(IEnumerable<T> hitObjects) where T : Hit...
    method Remove (line 128) | protected void Remove<T>(T hitObject) where T : HitObject
    method isCreateObjectLocked (line 136) | private bool isCreateObjectLocked<T>(T hitObject)
    method isRemoveObjectLocked (line 146) | private bool isRemoveObjectLocked<T>(T hitObject)
    method TriggerHitObjectUpdate (line 162) | protected void TriggerHitObjectUpdate<T>(T hitObject) where T : HitObject
    class AddOrRemoveForbiddenException (line 167) | public class AddOrRemoveForbiddenException : Exception
      method AddOrRemoveForbiddenException (line 169) | public AddOrRemoveForbiddenException()

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectPropertyChangeHandler.cs
  class HitObjectPropertyChangeHandler (line 12) | public abstract partial class HitObjectPropertyChangeHandler<THitObject>...
    method PerformOnSelection (line 18) | protected sealed override void PerformOnSelection(Action<THitObject> a...
    method IsWritePropertyLocked (line 27) | protected abstract bool IsWritePropertyLocked(THitObject hitObject);
    method IsSelectionsLocked (line 29) | public virtual bool IsSelectionsLocked()

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectsChangeHandler.cs
  class HitObjectsChangeHandler (line 8) | public abstract partial class HitObjectsChangeHandler<THitObject> : HitO...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs
  type IEnumAutoGenerateChangeHandler (line 12) | public interface IEnumAutoGenerateChangeHandler<in TEnum> where TEnum : ...
    method CanGenerate (line 14) | bool CanGenerate(TEnum type);
    method AutoGenerate (line 16) | void AutoGenerate(TEnum type);
  type IAutoGenerateChangeHandler (line 23) | public interface IAutoGenerateChangeHandler<in TType>
    method CanGenerate (line 25) | bool CanGenerate<T>() where T : TType;
    method AutoGenerate (line 27) | void AutoGenerate<T>() where T : TType;
    method CanGenerate (line 35) | bool CanGenerate();
    method AutoGenerate (line 37) | void AutoGenerate();
  type IAutoGenerateChangeHandler (line 33) | public interface IAutoGenerateChangeHandler
    method CanGenerate (line 25) | bool CanGenerate<T>() where T : TType;
    method AutoGenerate (line 27) | void AutoGenerate<T>() where T : TType;
    method CanGenerate (line 35) | bool CanGenerate();
    method AutoGenerate (line 37) | void AutoGenerate();

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IHitObjectPropertyChangeHandler.cs
  type IHitObjectPropertyChangeHandler (line 6) | public interface IHitObjectPropertyChangeHandler
    method IsSelectionsLocked (line 8) | bool IsSelectionsLocked();

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IImportBeatmapChangeHandler.cs
  type IImportBeatmapChangeHandler (line 8) | public interface IImportBeatmapChangeHandler
    method Import (line 10) | void Import(IBeatmap newBeatmap);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ILockChangeHandler.cs
  type ILockChangeHandler (line 8) | public interface ILockChangeHandler : IHitObjectPropertyChangeHandler
    method Lock (line 10) | void Lock(LockState lockState);
    method Unlock (line 12) | void Unlock();

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ImportBeatmapChangeHandler.cs
  class ImportBeatmapChangeHandler (line 13) | public partial class ImportBeatmapChangeHandler : Component, IImportBeat...
    method Import (line 18) | public void Import(IBeatmap newBeatmap)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/LockChangeHandler.cs
  class LockChangeHandler (line 11) | public partial class LockChangeHandler : HitObjectPropertyChangeHandler<...
    method Lock (line 13) | public void Lock(LockState lockState)
    method Unlock (line 22) | public void Unlock()
    method IsWritePropertyLocked (line 27) | protected sealed override bool IsWritePropertyLocked(KaraokeHitObject ...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricLanguageChangeHandler.cs
  type ILyricLanguageChangeHandler (line 8) | public interface ILyricLanguageChangeHandler : ILyricPropertyChangeHandler
    method SetLanguage (line 10) | void SetLanguage(CultureInfo? language);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricListPropertyChangeHandler.cs
  type ILyricListPropertyChangeHandler (line 8) | public interface ILyricListPropertyChangeHandler<in TItem> : ILyricPrope...
    method Add (line 10) | void Add(TItem item);
    method AddRange (line 12) | void AddRange(IEnumerable<TItem> items);
    method Remove (line 14) | void Remove(TItem item);
    method RemoveRange (line 16) | void RemoveRange(IEnumerable<TItem> items);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs
  type ILyricPropertyAutoGenerateChangeHandler (line 10) | public interface ILyricPropertyAutoGenerateChangeHandler : ILyricPropert...
    method GetGeneratorNotSupportedLyrics (line 12) | IDictionary<Lyric, LocalisableString> GetGeneratorNotSupportedLyrics(A...
  type AutoGenerateType (line 15) | public enum AutoGenerateType

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyChangeHandler.cs
  type ILyricPropertyChangeHandler (line 6) | public interface ILyricPropertyChangeHandler : IHitObjectPropertyChangeH...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricReferenceChangeHandler.cs
  type ILyricReferenceChangeHandler (line 10) | public interface ILyricReferenceChangeHandler : ILyricPropertyChangeHandler
    method UpdateReferenceLyric (line 12) | void UpdateReferenceLyric(Lyric? referenceLyric);
    method SwitchToReferenceLyricConfig (line 14) | void SwitchToReferenceLyricConfig();
    method SwitchToSyncLyricConfig (line 16) | void SwitchToSyncLyricConfig();
    method AdjustLyricConfig (line 18) | void AdjustLyricConfig<TConfig>(Action<TConfig> action) where TConfig ...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricRubyTagsChangeHandler.cs
  type ILyricRubyTagsChangeHandler (line 9) | public interface ILyricRubyTagsChangeHandler : ILyricListPropertyChangeH...
    method SetIndex (line 11) | void SetIndex(RubyTag rubyTag, int? startIndex, int? endIndex);
    method ShiftingIndex (line 13) | void ShiftingIndex(IEnumerable<RubyTag> rubyTags, int offset);
    method SetText (line 15) | void SetText(RubyTag rubyTag, string text);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricSingerChangeHandler.cs
  type ILyricSingerChangeHandler (line 8) | public interface ILyricSingerChangeHandler : ILyricListPropertyChangeHan...
    method Clear (line 10) | void Clear();

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTextChangeHandler.cs
  type ILyricTextChangeHandler (line 6) | public interface ILyricTextChangeHandler : ILyricPropertyChangeHandler
    method InsertText (line 8) | void InsertText(int charGap, string text);
    method DeleteLyricText (line 10) | void DeleteLyricText(int charGap, int count = 1);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTimeTagsChangeHandler.cs
  type ILyricTimeTagsChangeHandler (line 10) | public interface ILyricTimeTagsChangeHandler : ILyricListPropertyChangeH...
    method SetTimeTagTime (line 12) | void SetTimeTagTime(TimeTag timeTag, double time);
    method SetTimeTagFirstSyllable (line 14) | void SetTimeTagFirstSyllable(TimeTag timeTag, bool firstSyllable);
    method SetTimeTagRomanisedSyllable (line 16) | void SetTimeTagRomanisedSyllable(TimeTag timeTag, string? romanisedSyl...
    method ShiftingTimeTagTime (line 18) | void ShiftingTimeTagTime(IEnumerable<TimeTag> timeTags, double offset);
    method ClearTimeTagTime (line 20) | void ClearTimeTagTime(TimeTag timeTag);
    method ClearAllTimeTagTime (line 22) | void ClearAllTimeTagTime();
    method AddByPosition (line 24) | void AddByPosition(TextIndex index);
    method RemoveByPosition (line 26) | void RemoveByPosition(TextIndex index);
    method Shifting (line 28) | TimeTag Shifting(TimeTag timeTag, ShiftingDirection direction, Shiftin...
  type ShiftingDirection (line 31) | public enum ShiftingDirection
  type ShiftingType (line 38) | public enum ShiftingType

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTranslationChangeHandler.cs
  type ILyricTranslationChangeHandler (line 8) | public interface ILyricTranslationChangeHandler : ILyricPropertyChangeHa...
    method UpdateTranslation (line 10) | void UpdateTranslation(CultureInfo cultureInfo, string translation);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricsChangeHandler.cs
  type ILyricsChangeHandler (line 9) | public interface ILyricsChangeHandler
    method Split (line 11) | void Split(int index);
    method Combine (line 13) | void Combine();
    method CreateAtPosition (line 15) | void CreateAtPosition();
    method CreateAtLast (line 17) | void CreateAtLast();
    method AddBelowToSelection (line 19) | void AddBelowToSelection(Lyric newLyric);
    method AddRangeBelowToSelection (line 21) | void AddRangeBelowToSelection(IEnumerable<Lyric> newLyrics);
    method Remove (line 23) | void Remove();
    method ChangeOrder (line 25) | void ChangeOrder(int newOrder);

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricLanguageChangeHandler.cs
  class LyricLanguageChangeHandler (line 11) | public partial class LyricLanguageChangeHandler : LyricPropertyChangeHan...
    method SetLanguage (line 13) | public void SetLanguage(CultureInfo? language)
    method IsWritePropertyLocked (line 24) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs
  class LyricPropertyAutoGenerateChangeHandler (line 26) | public partial class LyricPropertyAutoGenerateChangeHandler : LyricPrope...
    method CanGenerate (line 35) | public bool CanGenerate(AutoGenerateType type)
    method GetGeneratorNotSupportedLyrics (line 76) | public IDictionary<Lyric, LocalisableString> GetGeneratorNotSupportedL...
    method AutoGenerate (line 127) | public void AutoGenerate(AutoGenerateType type)
    method IsSelectionsLocked (line 206) | public override bool IsSelectionsLocked()
    method IsWritePropertyLocked (line 209) | protected override bool IsWritePropertyLocked(Lyric lyric) =>
    method getDetector (line 226) | private LyricPropertyDetector<TProperty, TConfig> getDetector<TPropert...
    method getDetector (line 233) | private LyricPropertyDetector<TProperty, TConfig> getDetector<TPropert...
    method getGenerator (line 240) | private LyricPropertyGenerator<TProperty, TConfig> getGenerator<TPrope...
    method getSelector (line 247) | private LyricGeneratorSelector<TProperty, TBaseConfig> getSelector<TPr...
    method createInstance (line 253) | private static TType createInstance<TType>(params object?[]? args)
    method getGeneratorConfig (line 272) | private TConfig getGeneratorConfig<TConfig>()

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyChangeHandler.cs
  class LyricPropertyChangeHandler (line 8) | public abstract partial class LyricPropertyChangeHandler : HitObjectProp...

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricReferenceChangeHandler.cs
  class LyricReferenceChangeHandler (line 12) | public partial class LyricReferenceChangeHandler : LyricPropertyChangeHa...
    method UpdateReferenceLyric (line 14) | public void UpdateReferenceLyric(Lyric? referenceLyric)
    method SwitchToReferenceLyricConfig (line 44) | public void SwitchToReferenceLyricConfig()
    method SwitchToSyncLyricConfig (line 55) | public void SwitchToSyncLyricConfig()
    method AdjustLyricConfig (line 66) | public void AdjustLyricConfig<TConfig>(Action<TConfig> action) where T...
    method IsWritePropertyLocked (line 77) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricRubyTagsChangeHandler.cs
  class LyricRubyTagsChangeHandler (line 13) | public partial class LyricRubyTagsChangeHandler : LyricPropertyChangeHan...
    method Add (line 15) | public void Add(RubyTag item)
    method AddRange (line 29) | public void AddRange(IEnumerable<RubyTag> items)
    method Remove (line 47) | public void Remove(RubyTag item)
    method RemoveRange (line 61) | public void RemoveRange(IEnumerable<RubyTag> items)
    method SetIndex (line 79) | public void SetIndex(RubyTag rubyTag, int? startIndex, int? endIndex)
    method ShiftingIndex (line 102) | public void ShiftingIndex(IEnumerable<RubyTag> rubyTags, int offset)
    method SetText (line 122) | public void SetText(RubyTag rubyTag, string text)
    method containsInLyric (line 136) | private bool containsInLyric(Lyric lyric, RubyTag rubyTag)
    method addToLyric (line 139) | private void addToLyric(Lyric lyric, RubyTag rubyTag)
    method removeFromLyric (line 142) | private void removeFromLyric(Lyric lyric, RubyTag rubyTag)
    method IsWritePropertyLocked (line 145) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricSingerChangeHandler.cs
  class LyricSingerChangeHandler (line 12) | public partial class LyricSingerChangeHandler : LyricPropertyChangeHandl...
    method Add (line 14) | public void Add(ISinger singer)
    method AddRange (line 24) | public void AddRange(IEnumerable<ISinger> singers)
    method Remove (line 38) | public void Remove(ISinger singer)
    method RemoveRange (line 48) | public void RemoveRange(IEnumerable<ISinger> singers)
    method Clear (line 62) | public void Clear()
    method IsWritePropertyLocked (line 72) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs
  class LyricTextChangeHandler (line 11) | public partial class LyricTextChangeHandler : LyricPropertyChangeHandler...
    method InsertText (line 13) | public void InsertText(int charGap, string text)
    method DeleteLyricText (line 23) | public void DeleteLyricText(int charGap, int count = 1)
    method IsWritePropertyLocked (line 42) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs
  class LyricTimeTagsChangeHandler (line 14) | public partial class LyricTimeTagsChangeHandler : LyricPropertyChangeHan...
    method SetTimeTagTime (line 16) | public void SetTimeTagTime(TimeTag timeTag, double time)
    method SetTimeTagFirstSyllable (line 30) | public void SetTimeTagFirstSyllable(TimeTag timeTag, bool firstSyllable)
    method SetTimeTagRomanisedSyllable (line 44) | public void SetTimeTagRomanisedSyllable(TimeTag timeTag, string? roman...
    method ShiftingTimeTagTime (line 64) | public void ShiftingTimeTagTime(IEnumerable<TimeTag> timeTags, double ...
    method ClearTimeTagTime (line 82) | public void ClearTimeTagTime(TimeTag timeTag)
    method ClearAllTimeTagTime (line 96) | public void ClearAllTimeTagTime()
    method Add (line 107) | public void Add(TimeTag timeTag)
    method AddRange (line 121) | public void AddRange(IEnumerable<TimeTag> timeTags)
    method Remove (line 139) | public void Remove(TimeTag timeTag)
    method RemoveRange (line 150) | public void RemoveRange(IEnumerable<TimeTag> timeTags)
    method AddByPosition (line 166) | public void AddByPosition(TextIndex index)
    method RemoveByPosition (line 176) | public void RemoveByPosition(TextIndex index)
    method Shifting (line 192) | public TimeTag Shifting(TimeTag timeTag, ShiftingDirection direction, ...
    method insertTimeTag (line 247) | private void insertTimeTag(Lyric lyric, TimeTag timeTag, InsertDirecti...
    method IsWritePropertyLocked (line 292) | protected override bool IsWritePropertyLocked(Lyric lyric)
    type InsertDirection (line 298) | private enum InsertDirection

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslationChangeHandler.cs
  class LyricTranslationChangeHandler (line 11) | public partial class LyricTranslationChangeHandler : LyricPropertyChange...
    method UpdateTranslation (line 13) | public void UpdateTranslation(CultureInfo cultureInfo, string translat...
    method IsWritePropertyLocked (line 33) | protected override bool IsWritePropertyLocked(Lyric lyric)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs
  class LyricsChangeHandler (line 13) | public partial class LyricsChangeHandler : HitObjectsChangeHandler<Lyric...
    method Split (line 15) | public void Split(int index)
    method Combine (line 37) | public void Combine()
    method CreateAtPosition (line 61) | public void CreateAtPosition()
    method CreateAtLast (line 69) | public void CreateAtLast()
    method AddBelowToSelection (line 81) | public void AddBelowToSelection(Lyric newLyric)
    method AddRangeBelowToSelection (line 86) | public void AddRangeBelowToSelection(IEnumerable<Lyric> newLyrics)
    method Remove (line 105) | public void Remove()
    method ChangeOrder (line 115) | public void ChangeOrder(int newOrder)
    method Add (line 127) | protected override void Add<T>(T hitObject)
    method Insert (line 140) | protected override void Insert<T>(int index, T hitObject)
    method getInsertIndex (line 152) | private int getInsertIndex(int order)

FILE: osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/INotePropertyChangeHandler.cs
  type INotePropertyChangeHandler (line 8) | public interface INotePropertyChangeHandler : IHitObjectPropertyC
Condensed preview — 1273 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,761K chars).
[
  {
    "path": ".config/dotnet-tools.json",
    "chars": 503,
    "preview": "{\n  \"version\": 1,\n  \"isRoot\": true,\n  \"tools\": {\n    \"ppy.localisationanalyser.tools\": {\n      \"version\": \"2024.802.0\",\n"
  },
  {
    "path": ".editorconfig",
    "chars": 9417,
    "preview": "# EditorConfig is awesome: http://editorconfig.org\nroot = true\n\n[*.{csproj,props,targets}]\ncharset = utf-8-bom\nend_of_li"
  },
  {
    "path": ".git-blame-ignore-revs",
    "chars": 330,
    "preview": "# Partial everything\nc3d76bde9f3d78b420ab6a18b8191c00a503b2be\n# Make test project to the file-scope namespace\n3546a366f2"
  },
  {
    "path": ".gitattributes",
    "chars": 652,
    "preview": "# Autodetect text files and ensure that we normalise their\n# line endings to lf internally. When checked out they may\n# "
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 870,
    "preview": "# License related\n/CodeAnalysis/      @andy840119\n/LICENSE            @andy840119\n/README.md          @andy840119\n/osu.l"
  },
  {
    "path": ".github/labeler.yml",
    "chars": 59,
    "preview": "localization:\n  - osu.Game.Rulesets.Karaoke/Localisation/*\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 481,
    "preview": "name: .NET Core\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n    name:"
  },
  {
    "path": ".github/workflows/crowdin.yml",
    "chars": 2480,
    "preview": "name: Crowdin Action\n\non:\n  push:\n    branches: [ master ]\n    paths:\n      - 'osu.Game.Rulesets.Karaoke/Localisation/**"
  },
  {
    "path": ".github/workflows/dotnet-format.yml",
    "chars": 1773,
    "preview": "name: Format check on pull request\non: pull_request\n\njobs:\n  dotnet-format:\n    runs-on: ubuntu-latest\n    steps:\n      "
  },
  {
    "path": ".github/workflows/labeler.yml",
    "chars": 457,
    "preview": "name: Pull Request Labeler\n\non:\n  pull_request_target:\n    paths:\n      # we only add use this action for add the locali"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1699,
    "preview": "name: Tagged Release\non:\n  push:\n    tags: ['*']\n\njobs:\n  build:\n    name: Build and Create Release\n    runs-on: ubuntu-"
  },
  {
    "path": ".gitignore",
    "chars": 5950,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": ".globalconfig",
    "chars": 1472,
    "preview": "is_global = true\n\n# .NET Code Style\n# IDE styles reference: https://docs.microsoft.com/dotnet/fundamentals/code-analysis"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 7226,
    "preview": "# Contributing Guidelines\n\nThank you for showing interest in the development of karaoke ruleset. We aim to provide a goo"
  },
  {
    "path": "CodeAnalysis/BannedSymbols.txt",
    "chars": 2275,
    "preview": "M:System.Object.Equals(System.Object,System.Object)~System.Boolean;Don't use object.Equals. Use IEquatable<T> or Equalit"
  },
  {
    "path": "CodeAnalysis/osu.ruleset",
    "chars": 2434,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RuleSet Name=\"osu!karaoke Rule Set\" Description=\" \" ToolsVersion=\"16.0\">\n  <Rul"
  },
  {
    "path": "Directory.Build.props",
    "chars": 1090,
    "preview": "<!-- Contains required properties for osu!framework projects. -->\n<Project>\n  <PropertyGroup Label=\"C#\">\n    <LangVersio"
  },
  {
    "path": "LICENSE",
    "chars": 35149,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README.md",
    "chars": 4567,
    "preview": "![](assets/logo.png)\n\n# karaoke --dev\n[![CodeFactor](https://www.codefactor.io/repository/github/karaoke-dev/karaoke/bad"
  },
  {
    "path": "appveyor.yml",
    "chars": 760,
    "preview": "clone_depth: 1\nversion: '{branch}-{build}'\nimage: Visual Studio 2022\nbranches:\n  only:\n    - master\ndotnet_csproj:\n  pat"
  },
  {
    "path": "cake.config",
    "chars": 98,
    "preview": "\n[Nuget]\nSource=https://api.nuget.org/v3/index.json\nUseInProcessClient=true\nLoadDependencies=true\n"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/ElementId.cs",
    "chars": 2532,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapDecoder.cs",
    "chars": 2166,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeJsonBeatmapEncoder.cs",
    "chars": 647,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapDecoder.cs",
    "chars": 10152,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Formats/KaraokeLegacyBeatmapEncoder.cs",
    "chars": 2779,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/IHasPrimaryKey.cs",
    "chars": 764,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/IKaraokeBeatmapResourcesProvider.cs",
    "chars": 412,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmap.cs",
    "chars": 2298,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapConverter.cs",
    "chars": 1744,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapExtension.cs",
    "chars": 1138,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapProcessor.cs",
    "chars": 1673,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/KaraokeBeatmapResourcesProvider.cs",
    "chars": 1747,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/NoteInfo.cs",
    "chars": 475,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Page.cs",
    "chars": 835,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/PageInfo.cs",
    "chars": 2769,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Singer.cs",
    "chars": 2088,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerInfo.cs",
    "chars": 3219,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/SingerState.cs",
    "chars": 1432,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Metadatas/Types/ISinger.cs",
    "chars": 358,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Beatmaps/Utils/SingerUtils.cs",
    "chars": 1189,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Bindables/BindableCultureInfo.cs",
    "chars": 1894,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Bindables/BindableFontUsage.cs",
    "chars": 3463,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetConfigManager.cs",
    "chars": 5806,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditCheckerConfigManager.cs",
    "chars": 991,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditConfigManager.cs",
    "chars": 386,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetEditGeneratorConfigManager.cs",
    "chars": 5634,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeRulesetLyricEditorConfigManager.cs",
    "chars": 3682,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Configuration/KaraokeSessionStatics.cs",
    "chars": 2437,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyAttributes.cs",
    "chars": 1429,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/KaraokeDifficultyCalculator.cs",
    "chars": 3927,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceAttributes.cs",
    "chars": 1024,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/KaraokePerformanceCalculator.cs",
    "chars": 4607,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/Preprocessing/KaraokeDifficultyHitObject.cs",
    "chars": 743,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Difficulty/Skills/Strain.cs",
    "chars": 3740,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Blueprints/KaraokeSelectionBlueprint.cs",
    "chars": 577,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Blueprints/Lyrics/LyricSelectionBlueprint.cs",
    "chars": 439,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/Components/EditBodyPiece.cs",
    "chars": 900,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Blueprints/Notes/NoteSelectionBlueprint.cs",
    "chars": 3005,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapListPropertyChangeHandler.cs",
    "chars": 3022,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/BeatmapPropertyChangeHandler.cs",
    "chars": 3346,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapPagesChangeHandler.cs",
    "chars": 3826,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapSingersChangeHandler.cs",
    "chars": 3937,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/BeatmapTranslationsChangeHandler.cs",
    "chars": 1267,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapPagesChangeHandler.cs",
    "chars": 671,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapSingersChangeHandler.cs",
    "chars": 771,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Beatmaps/IBeatmapTranslationsChangeHandler.cs",
    "chars": 546,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ChangeForbiddenException.cs",
    "chars": 400,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectChangeHandler.cs",
    "chars": 6309,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectPropertyChangeHandler.cs",
    "chars": 1287,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/HitObjectsChangeHandler.cs",
    "chars": 389,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IAutoGenerateChangeHandler.cs",
    "chars": 1186,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IHitObjectPropertyChangeHandler.cs",
    "chars": 306,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/IImportBeatmapChangeHandler.cs",
    "chars": 337,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ILockChangeHandler.cs",
    "chars": 405,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/ImportBeatmapChangeHandler.cs",
    "chars": 833,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/LockChangeHandler.cs",
    "chars": 1177,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricLanguageChangeHandler.cs",
    "chars": 384,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricListPropertyChangeHandler.cs",
    "chars": 516,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyAutoGenerateChangeHandler.cs",
    "chars": 786,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricPropertyChangeHandler.cs",
    "chars": 307,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricReferenceChangeHandler.cs",
    "chars": 668,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricRubyTagsChangeHandler.cs",
    "chars": 589,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricSingerChangeHandler.cs",
    "chars": 398,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTextChangeHandler.cs",
    "chars": 408,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTimeTagsChangeHandler.cs",
    "chars": 1119,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricTranslationChangeHandler.cs",
    "chars": 415,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/ILyricsChangeHandler.cs",
    "chars": 638,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricLanguageChangeHandler.cs",
    "chars": 935,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyAutoGenerateChangeHandler.cs",
    "chars": 13034,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricPropertyChangeHandler.cs",
    "chars": 398,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricReferenceChangeHandler.cs",
    "chars": 3028,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricRubyTagsChangeHandler.cs",
    "chars": 5142,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricSingerChangeHandler.cs",
    "chars": 2106,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTextChangeHandler.cs",
    "chars": 1467,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTimeTagsChangeHandler.cs",
    "chars": 10037,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricTranslationChangeHandler.cs",
    "chars": 1346,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Lyrics/LyricsChangeHandler.cs",
    "chars": 4501,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/INotePropertyChangeHandler.cs",
    "chars": 514,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/INotesChangeHandler.cs",
    "chars": 354,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotePropertyChangeHandler.cs",
    "chars": 2203,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Notes/NotesChangeHandler.cs",
    "chars": 1841,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/ClassicStageChangeHandler.cs",
    "chars": 3242,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/IClassicStageChangeHandler.cs",
    "chars": 1025,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/IStageElementCategoryChangeHandler.cs",
    "chars": 742,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/IStagesChangeHandler.cs",
    "chars": 557,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/StageElementCategoryChangeHandler.cs",
    "chars": 2505,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/StagePropertyChangeHandler.cs",
    "chars": 789,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/ChangeHandlers/Stages/StagesChangeHandler.cs",
    "chars": 2884,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckBeatmapAvailableTranslations.cs",
    "chars": 4164,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckBeatmapNoteInfo.cs",
    "chars": 3129,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckBeatmapPageInfo.cs",
    "chars": 4968,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckBeatmapProperty.cs",
    "chars": 2370,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckClassicStageInfo.cs",
    "chars": 8788,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckHitObjectProperty.cs",
    "chars": 1034,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckHitObjectReferenceProperty.cs",
    "chars": 1437,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricLanguage.cs",
    "chars": 1190,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricReferenceLyric.cs",
    "chars": 3238,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricRubyTag.cs",
    "chars": 2881,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricSinger.cs",
    "chars": 1214,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricText.cs",
    "chars": 1226,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricTimeTag.cs",
    "chars": 8237,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckLyricTranslations.cs",
    "chars": 1476,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckNoteReferenceLyric.cs",
    "chars": 5020,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckNoteText.cs",
    "chars": 1726,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckNoteTime.cs",
    "chars": 3284,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/CheckStageInfo.cs",
    "chars": 5755,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/BeatmapClassicLyricTimingPointIssue.cs",
    "chars": 894,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/BeatmapPageIssue.cs",
    "chars": 709,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/LyricIssue.cs",
    "chars": 596,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/LyricRubyTagIssue.cs",
    "chars": 589,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/LyricTimeTagIssue.cs",
    "chars": 696,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Checks/Issues/NoteIssue.cs",
    "chars": 527,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/ContextMenu/LyricLockContextMenu.cs",
    "chars": 1260,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/ContextMenu/SingerContextMenu.cs",
    "chars": 1823,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/Cursor/TimeTagTooltip.cs",
    "chars": 3376,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/Menus/KaraokeEditorMenu.cs",
    "chars": 656,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/Menus/KaraokeSkinEditorMenu.cs",
    "chars": 708,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/Sprites/DrawableTextIndex.cs",
    "chars": 754,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Components/Sprites/DrawableTimeTag.cs",
    "chars": 2452,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Debugging/DebugBeatmapManager.cs",
    "chars": 12155,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/DrawableKaraokeEditorRuleset.cs",
    "chars": 1257,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/EditorNotePlayfield.cs",
    "chars": 2727,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Export/ExportLyricManager.cs",
    "chars": 1864,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/BeatmapPropertyDetector.cs",
    "chars": 690,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/BeatmapPropertyGenerator.cs",
    "chars": 699,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/Pages/PageGenerator.cs",
    "chars": 4664,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Beatmaps/Pages/PageGeneratorConfig.cs",
    "chars": 1110,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/ConfigCategoryAttribute.cs",
    "chars": 945,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/ConfigSourceAttribute.cs",
    "chars": 961,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/DetectorNotSupportedException.cs",
    "chars": 492,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/GeneratorConfig.cs",
    "chars": 254,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/GeneratorConfigExtension.cs",
    "chars": 1846,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/GeneratorNotSupportedException.cs",
    "chars": 496,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/GeneratorSelector.cs",
    "chars": 2112,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Language/LanguageDetector.cs",
    "chars": 1459,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Language/LanguageDetectorConfig.cs",
    "chars": 532,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/LyricGeneratorSelector.cs",
    "chars": 1879,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/LyricPropertyDetector.cs",
    "chars": 674,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/LyricPropertyGenerator.cs",
    "chars": 683,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Notes/NoteGenerator.cs",
    "chars": 2709,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Notes/NoteGeneratorConfig.cs",
    "chars": 280,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/ReferenceLyric/ReferenceLyricDetector.cs",
    "chars": 2623,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/ReferenceLyric/ReferenceLyricDetectorConfig.cs",
    "chars": 488,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/Ja/JaRomanisationGenerator.cs",
    "chars": 5905,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/Ja/JaRomanisationGeneratorConfig.cs",
    "chars": 491,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/RomanisationGenerateResult.cs",
    "chars": 380,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/RomanisationGenerator.cs",
    "chars": 1103,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/RomanisationGeneratorConfig.cs",
    "chars": 303,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/Romanisation/RomanisationGeneratorSelector.cs",
    "chars": 996,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/RubyTags/Ja/JaRubyTagGenerator.cs",
    "chars": 2963,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/RubyTags/Ja/JaRubyTagGeneratorConfig.cs",
    "chars": 822,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/RubyTags/RubyTagGenerator.cs",
    "chars": 768,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/RubyTags/RubyTagGeneratorConfig.cs",
    "chars": 295,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/RubyTags/RubyTagGeneratorSelector.cs",
    "chars": 872,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/Ja/JaTimeTagGenerator.cs",
    "chars": 4634,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/Ja/JaTimeTagGeneratorConfig.cs",
    "chars": 2531,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/TimeTagGenerator.cs",
    "chars": 1750,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/TimeTagGeneratorConfig.cs",
    "chars": 1944,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/TimeTagGeneratorSelector.cs",
    "chars": 1037,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/Zh/ZhTimeTagGenerator.cs",
    "chars": 917,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Lyrics/TimeTags/Zh/ZhTimeTagGeneratorConfig.cs",
    "chars": 298,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/PropertyDetector.cs",
    "chars": 1773,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/PropertyGenerator.cs",
    "chars": 1793,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicLyricLayoutCategoryGenerator.cs",
    "chars": 4114,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicLyricLayoutCategoryGeneratorConfig.cs",
    "chars": 1363,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicLyricTimingInfoGenerator.cs",
    "chars": 2625,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicLyricTimingInfoGeneratorConfig.cs",
    "chars": 647,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicStageInfoGenerator.cs",
    "chars": 1943,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Classic/ClassicStageInfoGeneratorConfig.cs",
    "chars": 650,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Preview/PreviewStageInfoGenerator.cs",
    "chars": 882,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/Preview/PreviewStageInfoGeneratorConfig.cs",
    "chars": 302,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/StageInfoGenerator.cs",
    "chars": 602,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/StageInfoGeneratorConfig.cs",
    "chars": 278,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/StageInfoGeneratorSelector.cs",
    "chars": 2011,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/Generator/Stages/StageInfoPropertyGenerator.cs",
    "chars": 701,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the repo"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/KaraokeBeatmapVerifier.cs",
    "chars": 1143,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/KaraokeBlueprintContainer.cs",
    "chars": 1402,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/KaraokeEditorPlayfield.cs",
    "chars": 486,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  },
  {
    "path": "osu.Game.Rulesets.Karaoke/Edit/KaraokeHitObjectComposer.cs",
    "chars": 7162,
    "preview": "// Copyright (c) andy840119 <andy840119@gmail.com>. Licensed under the GPL Licence.\r\n// See the LICENCE file in the rep"
  }
]

// ... and 1073 more files (download for full content)

About this extraction

This page contains the full source code of the karaoke-dev/karaoke GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1273 files (3.3 MB), approximately 937.1k tokens, and a symbol index with 6689 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!