Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playback speed not working anymore #1856

Open
killthe3vil opened this issue Nov 28, 2023 · 39 comments
Open

Playback speed not working anymore #1856

killthe3vil opened this issue Nov 28, 2023 · 39 comments
Assignees
Labels
Completion / Revision Rethink, complete, improve, tweak our feature or structure. good first issue A GitHub standard for inviting (new) contributors *Congratulations in advance!* help wanted Just an old github standard we add automatically. (The team can remove it when working on it.) Open! Not to forget. Unfinished (or waiting for a requirement) (unless combined with label: riddle) Riddle up-for-grabs (a github standard for inviting new contributors) - Welcome! ♥

Comments

@killthe3vil
Copy link

it been few days the playback speed not working anymore.

@killthe3vil killthe3vil added Bug Bug or required update after YouTube changes good first issue A GitHub standard for inviting (new) contributors *Congratulations in advance!* help wanted Just an old github standard we add automatically. (The team can remove it when working on it.) up-for-grabs (a github standard for inviting new contributors) - Welcome! ♥ labels Nov 28, 2023
@shadow-ryu
Copy link

I'm interested in tackling this task, but I would appreciate it if additional information could be provided. :)

@ImprovedTube
Copy link
Member

hi @killthe3vil what version?

@shadow-ryu Awesome!!

cant say much. some of our stuff needs maintenance when youtube's DOM / CSS changes, but html5 browser standard playback features shouldnt break and youtube player's functions are well known / might not change.

in the repo a complex enhancement deciding what's music (no speed up) was just added a few days ago. This will only reach stores today or tomorrow.

@killthe3vil
Copy link
Author

im not sure what info you want, i will just show everything i can
Window 10
Chrome Version 119.0.6045.160 (Official Build) (64-bit)
ImproveTube Version 4.408

@shadow-ryu
Copy link

ok

@killthe3vil
Copy link
Author

@shadow-ryu Appreciated for the help!~

@shadow-ryu
Copy link

shadow-ryu commented Nov 28, 2023

@killthe3vil can u share the local setup guide as I cant find the same.

@killthe3vil
Copy link
Author

@shadow-ryu local setup guide? i'm not sure what it is.
but somehow it fixed today, are you doing something already?

@ImprovedTube
Copy link
Member

ImprovedTube commented Nov 29, 2023

hi! @killthe3vil, i should have asked if you did anything differently when it didn't work and for how long.

(the update(v4.443) was only approved for our chrome webstore beta testing version yet)


setup guide

the repo is also the extension. no building required.
(more: https://github.com/code-charity/youtube/wiki/Contributing#Development )
hi @shadow-ryu how are you?

@ImprovedTube ImprovedTube added Open! Not to forget. Unfinished (or waiting for a requirement) (unless combined with label: riddle) Riddle and removed Open! Not to forget. Unfinished (or waiting for a requirement) (unless combined with label: riddle) labels Nov 29, 2023
@killthe3vil
Copy link
Author

Hi @ImprovedTube
nop, i did nothing on setting after i done all the customize, it didn't work like 1 weeks ago until today.

@shadow-ryu
Copy link

Hey @killthe3vil its working on my side too

@killthe3vil
Copy link
Author

@shadow-ryu ya it weird that it fixed itself by today

@shadow-ryu
Copy link

shadow-ryu commented Nov 29, 2023

we can keep this issue on monitoring?

@killthe3vil
Copy link
Author

it is me only or the function not working again?

@ImprovedTube
Copy link
Member

hi @killthe3vil thanks, we can just assuming it works for most people most of the time and we just had a bug with applying it to embedded youtube players before. ( assumably you werent confused by the music exclusion either. )

cant say much. some of our stuff needs maintenance when youtube's DOM / CSS changes, but html5 browser standard playback features shouldnt break and youtube player's functions are well known / might not change.

(didnt mean to say there is no bug, just that we should fix it already if any.)

@shadow-ryu

yes, looking forward to whatever we might discuss next.

@xeophyte
Copy link

xeophyte commented Dec 2, 2023

I just want to add that with these settings on v4.443:
image
music recognizing doesn't work very well, or maybe I don't understand some functions.
When I open a video with some talking, I get 1.25 (as I want), but then when I go to music video, it stays at 1.25 (I want 1.0).
Shouldn't there be an option/function "Don't force playback speed for music"?

@Anoaxx
Copy link

Anoaxx commented Dec 2, 2023

tried reinstall?

@xeophyte
Copy link

xeophyte commented Dec 3, 2023

Yes, I reinstalled and restored settings and still got 1.25 on music.

@ImprovedTube
Copy link
Member

ImprovedTube commented Dec 3, 2023

@xeophyte how many examples did you try? please share all or look for the reason they were missed

@xeophyte
Copy link

xeophyte commented Dec 3, 2023

On at least 15 videos. Actually the 1.25 speed often doesn't work even on talking movies, like https://www.youtube.com/watch?v=lRvXAU9_sfc or https://www.youtube.com/watch?v=DKBxkrUPCbs even after many refreshes. Sometimes it works, but then music doesn't, like I play music video, get 1.0, then go directly to talking, get 1.25, then go back to music and 1.25 stays.
But maybe it's connected to my other bugs - Autoplay never works - I have to play manually every new video (besides playlists) and Show description - set to Always sometimes doesn't work.

@ImprovedTube
Copy link
Member

@xeophyte so it worked better for you before? (v4.408, v4.404, ... ?)

back

with browser nagivation back arrow?

maybe this code doesnt always run for you when a video starts? do all these other features, such as the permanent volume, also work - or fail at the same times?

ImprovedTube.forcedPlayVideoFromTheBeginning();
ImprovedTube.playerPlaybackSpeed();
ImprovedTube.subtitles();
ImprovedTube.subtitlesLanguage();
ImprovedTube.subtitlesFontFamily();
ImprovedTube.subtitlesFontColor();
ImprovedTube.subtitlesFontSize();
ImprovedTube.subtitlesBackgroundColor();
ImprovedTube.subtitlesWindowColor();
ImprovedTube.subtitlesWindowOpacity();
ImprovedTube.subtitlesCharacterEdgeStyle();
ImprovedTube.subtitlesFontOpacity();
ImprovedTube.subtitlesBackgroundOpacity();
ImprovedTube.playerQuality();
ImprovedTube.playerVolume();
ImprovedTube.playerScreenshotButton();
ImprovedTube.playerRepeatButton();
ImprovedTube.playerRotateButton();
ImprovedTube.playerPopupButton();
ImprovedTube.playerFitToWinButton();
ImprovedTube.playerHamburgerButton();
ImprovedTube.playerControls();

@ImprovedTube
Copy link
Member

ImprovedTube commented Dec 4, 2023

@xeophyte forgot some of the code about music is disabled, so that's an explanation.



to confirm this please check if everytime it fails, the browser console sais 5 times: Error: Invidious API: ... and eventually (~10s later) Error parsing id="scriptTag"\'s JSON: .....

@xeophyte
Copy link

xeophyte commented Dec 4, 2023

so it worked better for you before? (v4.408, v4.404, ... ?)

I test this feature only for few days, don't know how it was earlier.

with browser nagivation back arrow?

Yes, and also when I click music video directly from the right related list.

Similar test: I play talking video (sets itself on 1.25), go to music from related (stays at 1.25), set it to 1.75, go to another talking (sets itself on 1.25), go to some music (stays at 1.25), set it to 2.0, go to some music (stays at 2.0).

It doesn't matter if the next video is opened by click or using the previous/next page button, the effect is the same.
In other words: the speed setting for a music video is set to the one that was last set, regardless of whether the last page was a video with talking or music. On the current browser tab of course.

Maybe it's somehow related to YT itself remembering the speed setting of a given video?

maybe this code doesnt always run for you when a video starts? do all these other features, such as the permanent volume, also work - or fail at the same times?

I don't know how to test it.

image

But I still feel it's connected to my Autoplay sometimes not working. When I open some YT tab in the background and go to that tab, the video doesn't play, have to run manually.

@ImprovedTube
Copy link
Member

thank you! @xeophyte you can watch the browser console live to see what happens when. (busy seconds. Can also enable top view timestamps..)

  • Every time we show the paragraphs "Genre:...", then we also try to set the speed accordingly, which should just work if the timing isnt wrong.
    • (Previously an issue was, that the keywords would stay the same as the previous video or missing. But that's solved just before you started)

@mrlinuxfish
Copy link

I found some videos get the automatic speed and some do not. I am guessing this has to do with the category but I can't find where to see what categories a video belongs to

@killthe3vil
Copy link
Author

@mrlinuxfish yup that how the situation to me as well, could not figure out what the issue

@ImprovedTube
Copy link
Member

thanks! @mrlinuxfish @killthe3vil

maybe it happens only when excluding music and only after clicking a related video only?
(then to see the tags efficiently we ask a random invidious API node but some may be down and it is retried for a few seconds. should be robust 🤔)

category

hoped we'd have an easy bug, that always excludes education videos as the switch is new, but maybe not

you can see the category called genre in the browser console log as in the screenshot above our comments
using the word genre as it is the same one youtube used (even though it is about 1/3 as common and more seasonal (summer lows) https://trends.google.com/trends/explore?date=all&q=genre,category&hl=en

@ImprovedTube ImprovedTube added Completion / Revision Rethink, complete, improve, tweak our feature or structure. and removed Bug Bug or required update after YouTube changes labels Feb 22, 2024
@ImprovedTube
Copy link
Member

let us know your further experience? @mrlinuxfish @killthe3vil @shadow-ryu @xeophyte

@killthe3vil
Copy link
Author

let us know your further experience? @mrlinuxfish @killthe3vil @shadow-ryu @xeophyte

i think so far so good now, but sometime will not working like 10 out of 1 time.

@xeophyte
Copy link

xeophyte commented Feb 22, 2024

Looks like it's working for me on 4.700 (maybe one out of 10 times it doesn't work), although sometimes switching to the appropriate speed takes up to 10 seconds.
Also, I found new bug related.
I set the default speed to 1.25, so non-music is at that speed and music is at 1.0. When I play a playlist (e.g. with music) and go to for example subscription page or the home page, the playback speed in the miniplayer is changed to the default one, i.e. in my case the music speeds up to 1.25.

@Anoaxx
Copy link

Anoaxx commented Feb 24, 2024

Looks like it's working for me on 4.700 (maybe one out of 10 times it doesn't work), although sometimes switching to the appropriate speed takes up to 10 seconds. Also, I found new bug related. I set the default speed to 1.25, so non-music is at that speed and music is at 1.0. When I play a playlist (e.g. with music) and go to for example subscription page or the home page, the playback speed in the miniplayer is changed to the default one, i.e. in my case the music speeds up to 1.25.

Try open video in a new tab and wait that 10 second before tuning into it. It should work from a strat. Some things need some time to load.

@xeophyte
Copy link

It doesn't make sense when the playlist is playing, after all, that's why it's there so that you don't have to open every video in a new tab.
I would prefer to be able to set the default speed to 1.0, and for IYT to switch the music to a my different value.

@Anoaxx
Copy link

Anoaxx commented Feb 24, 2024

Option to control speed on playlist or exclude playlist from other vieos could be cool option. Remember @ImprovedTube WE DON JUST HAVE PLAYLISTS, there are queues, mixes and probably something more.

@xeophyte
Copy link

xeophyte commented Mar 12, 2024

@ImprovedTube
This option seems to work in such a way that each video is first set to a given speed and then its speed is changed depending on whether it is, for example, a musical video or not.
Could it be modified so that the user's speed is switched on AFTER the type of video is detected?
Maybe this would eliminate the problem of changing the speed during playback at the beginning of the video.

@ImprovedTube
Copy link
Member

hi! @xeophyte yes, when music only is indicated as in youtube's catalogue /buyable, below the video-descriptions. How often?

yes, inversely (and originally for us), these few music videos can start slow instead. But the feature is used for speed-watching mostly and the music sub-option enabled by default for this feature. So @Eyevou thought of the current order And maybe hurried users like it like now.

As of the edit history anyone and chatgpt (next to me) can can now add a sub-sub-option to allow both detection orders. ( long before/easier before ultimately one day our music detection should even be immediate always, if ever. )

@xeophyte
Copy link

I didn't understand any of it. I just want to play music videos at 1.0 when the Playback speed is set to 1.25. Now it starts playing at 1.25 or it is set like that all the time.

@ImprovedTube
Copy link
Member

all time time

really? @xeophyte:
in other & shorter words:
It is supposed to:

  • take below 1 second most of them time,
    • rarely up to 5 seconds,
  • (+very very rarely completely miss what is music or not) .

And here you suggest to not undo speeding up already in the first second before noticing music.. - This order was only introduced in January as per @Eyevou's suggestion and can be undone or we can easily-enough have both options. you will succeed soon if you try.

@ImprovedTube
Copy link
Member

just fixed something: 3809d3b

  • does the bug appear only with new tabs or new sessions? (not after navigating related videos within youtube)
    @xeophyte

@xeophyte
Copy link

just fixed something: 3809d3b

  • does the bug appear only with new tabs or new sessions? (not after navigating related videos within youtube)
    @xeophyte

both

@raszpl
Copy link
Contributor

raszpl commented Jun 16, 2024

this

ImprovedTube.playerPlaybackSpeed = function () { if (this.storage.player_forced_playback_speed === true) {
var player = this.elements.player,
video = player.querySelector('video'),
option = this.storage.player_playback_speed;
if (this.isset(option) === false) { option = 1; }
else if ( option !== 1 && video.playbackRate !== option && (video.playbackRate > 1 || video.playbackRate < 1) )
{ console.log("skipping permanent speed, since speed was manually set differently for this video to:" + video.playbackRate); return; }
if ( !player.getVideoData().isLive || player.getVideoData().isLive === false)
{ player.setPlaybackRate(Number(option)); video.playbackRate = Number(option); // #1729 q2 // hi! @raszpl
if ( (this.storage.player_force_speed_on_music !== true || this.storage.player_dont_speed_education === true)
&& option !== 1) {
ImprovedTube.speedException = function () {
if (this.storage.player_dont_speed_education === true && DATA.genre === 'Education')
{player.setPlaybackRate(Number(1)); video.playbackRate = Number(1); return;}
if (this.storage.player_force_speed_on_music === true)
{ //player.setPlaybackRate(Number(option)); video.playbackRate = Number(option);
return;}
if (DATA.keywords && !keywords) { keywords = DATA.keywords.join(', ') || ''; }
if (keywords === 'video, sharing, camera phone, video phone, free, upload') { keywords = ''; }
var musicIdentifiers = /(official|music|lyrics?)[ -]video|(cover|studio|radio|album|alternate)[- ]version|soundtrack|unplugged|\bmedley\b|\blo-fi\b|\blofi\b|a(lla)? cappella|feat\.|(piano|guitar|jazz|ukulele|violin|reggae)[- ](version|cover)|karaok|backing[- ]track|instrumental|(sing|play)[- ]?along|卡拉OK|卡拉OK|الكاريوكي|караоке|カラオケ|노래방|bootleg|mashup|Radio edit|Guest (vocals|musician)|(title|opening|closing|bonus|hidden)[ -]track|live acoustic|interlude|featuring|recorded (at|live)/i;
var musicIdentifiersTitleOnly = /lyrics|theme song|\bremix|\bAMV ?[^a-z0-9]|[^a-z0-9] ?AMV\b|\bfull song\b|\bsong:|\bsong[\!$]|^song\b|( - .*\bSong\b|\bSong\b.* - )|cover ?[^a-z0-9]|[^a-z0-9] ?cover|\bconcert\b/i;
var musicIdentifiersTitle = new RegExp(musicIdentifiersTitleOnly.source + '|' + musicIdentifiers.source, "i");
var musicRegexMatch = musicIdentifiersTitle.test(DATA.title);
if (!musicRegexMatch) {
var musicIdentifiersTagsOnly = /, (lyrics|remix|song|music|AMV|theme song|full song),|\(Musical Genre\)|, jazz|, reggae/i;
var musicIdentifiersTags = new RegExp(musicIdentifiersTagsOnly.source + '|' + musicIdentifiers.source, "i");
keywordsAmount = 1 + ((keywords || '').match(/,/) || []).length;
if ( ((keywords || '').match(musicIdentifiersTags) || []).length / keywordsAmount > 0.08) {
musicRegexMatch = true}}
notMusicRegexMatch = /\bdo[ck]u|interv[iyj]|back[- ]?stage|インタビュー|entrevista|面试|面試|회견|wawancara|مقابلة|интервью|entretien|기록한 것|记录|記錄|ドキュメンタリ|وثائقي|документальный/i.test(DATA.title + " " + keywords);
// (Tags/keywords shouldnt lie & very few songs titles might have these words)
if (DATA.duration) {
function parseDuration(duration) { const [_, h = 0, m = 0, s = 0] = duration.match(/PT(?:(\d+)?H)?(?:(\d+)?M)?(\d+)?S?/).map(part => parseInt(part) || 0);
return h * 3600 + m * 60 + s; }
DATA.lengthSeconds = parseDuration(DATA.duration); }
function testSongDuration(s, ytMusic) {
if (135 <= s && s <= 260) {return 'veryCommon';}
if (105 <= s && s <= 420) {return 'common';}
if (420 <= s && s <= 720) {return 'long';}
if (45 <= s && s <= 105) {return 'short';}
if (ytMusic && ytMusic > 1 && (85 <= s / ytMusic && (s / ytMusic <= 375 || ytMusic == 10))) {return 'multiple';}
//does Youtube ever show more than 10 songs below the description?
}
var songDurationType = testSongDuration(DATA.lengthSeconds);
console.log("genre: " + DATA.genre + "//title: " + DATA.title + "//keywords: " + keywords + "//music word match: " + musicRegexMatch + "// not music word match:" + notMusicRegexMatch + "//duration: " + DATA.lengthSeconds + "//song duration type: " + songDurationType);
// check if the video is PROBABLY MUSIC:
if ( ( DATA.genre === 'Music' && (!notMusicRegexMatch || songDurationType === 'veryCommon'))
|| ( musicRegexMatch && !notMusicRegexMatch && (typeof songDurationType !== 'undefined'
|| (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test(DATA.title + " " + keywords)
&& 1150 <= DATA.lengthSeconds && DATA.lengthSeconds <= 5000)) )
|| ( DATA.genre === 'Music' && musicRegexMatch && (typeof songDurationType !== 'undefined'
|| (/album|Álbum|专辑|專輯|एलबम|البوم|アルバム|альбом|앨범|mixtape|concert|playlist|\b(live|cd|vinyl|lp|ep|compilation|collection|symphony|suite|medley)\b/i.test(DATA.title + " " + keywords)
&& 1150 <= DATA.lengthSeconds && DATA.lengthSeconds <= 5000)) )
|| (amountOfSongs && testSongDuration(DATA.lengthSeconds, amountOfSongs ) !== 'undefined')
// || location.href.indexOf('music.') !== -1 // (=currently we are only running on www.youtube.com anyways)
) { player.setPlaybackRate(1); video.playbackRate = 1; console.log ("...,thus must be music?"); }
else { // Now this video might rarely be music
// - however we can make extra-sure after waiting for the video descripion to load... (#1539)
var tries = 0; var intervalMs = 210; if (location.href.indexOf('/watch?') !== -1) {var maxTries = 10;} else {var maxTries = 0;}
// ...except when it is an embedded player?
var waitForDescription = setInterval(() => {
if (++tries >= maxTries) {
subtitle = document.querySelector('#title + #subtitle:last-of-type')
if ( subtitle && 1 <= Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) // indicates buyable/registered music (amount of songs)
&& typeof testSongDuration(DATA.lengthSeconds, Number((subtitle?.innerHTML?.match(/^\d+/) || [])[0]) ) !== 'undefined' ) // resonable duration
{player.setPlaybackRate(1); video.playbackRate = 1; console.log("...but YouTube shows music below the description!"); clearInterval(waitForDescription); }
intervalMs *= 1.11; }}, intervalMs);
window.addEventListener('load', () => { setTimeout(() => { clearInterval(waitForDescription); }, 1234); });
}
}
//DATA (TO-DO: make the Data available to more/all features? #1452 #1763 (Then can replace ImprovedTube.elements.category === 'music', VideoID is also used elsewhere)
DATA = {};
defaultKeywords = "video,sharing,camera,phone,video phone,free,upload";
DATA.keywords = false; keywords = false; amountOfSongs = false;
DATA.videoID = ImprovedTube.videoId() || false;
ImprovedTube.fetchDOMData = function () {
// if (history.length > 1 && history.state.endpoint.watchEndpoint) {
try { DATA = JSON.parse(document.querySelector('#microformat script')?.textContent) ?? false; DATA.title = DATA.name;}
catch { DATA.genre = false; DATA.keywords = false; DATA.lengthSeconds = false;
try {
DATA.title = document.getElementsByTagName('meta')?.title?.content || false;
DATA.genre = document.querySelector('meta[itemprop=genre]')?.content || false;
DATA.duration = document.querySelector('meta[itemprop=duration]')?.content || false;
} catch {}} if ( DATA.title === ImprovedTube.videoTitle() )
{ keywords = document.getElementsByTagName('meta')?.keywords?.content || false; if(!keywords){keyword=''} ImprovedTube.speedException(); }
else { keywords = ''; (async function () { try { const response = await fetch(`https://www.youtube.com/watch?v=${DATA.videoID}`);
const htmlContent = await response.text();
const metaRegex = /<meta[^>]+name=["'](keywords|genre|duration)["'][^>]+content=["']([^"']+)["'][^>]*>/gi;
let match; while ((match = metaRegex.exec(htmlContent)) !== null) {
const [, property, value] = match;
if (property === 'keywords') { keywords = value;} else {DATA[property] = value;}
}
amountOfSongs = (htmlContent.slice(-80000).match(/},"subtitle":{"simpleText":"(\d*)\s/) || [])[1] || false;
if (keywords) { ImprovedTube.speedException(); }
} catch (error) { console.error('Error: fetching from https://Youtube.com/watch?v=${DATA.videoID}', error); keywords = ''; }
})();
}
};
if ( (history && history.length === 1) || !history?.state?.endpoint?.watchEndpoint) { ImprovedTube.fetchDOMData();}
else {
//Invidious instances. Should be updated automatically!...
const invidiousInstances = ['iv.datura.network', 'vid.puffyan.us', 'iv.melmac.space', 'inv.in.projectsegfau.lt', 'invidious.asir.dev', 'inv.zzls.xyz', 'invidious.io.lol', 'onion.tube', 'yewtu.be', 'invidious.protokolla.fi', 'inv.citw.lgbt', 'anontube.lvkaszus.pl', 'iv.nboeck.de', 'invidious.no-logs.com', 'vid.priv.au', 'yt.cdaut.de', 'invidious.slipfox.xyz', 'yt.artemislena.eu', 'invidious.drgns.space', 'invidious.einfachzocken.eu', 'invidious.projectsegfau.lt', 'invidious.nerdvpn.de', 'invidious.private.coffee', 'invidious.lunar.icu', 'invidious.privacydev.net', 'invidious.fdn.fr', 'yt.oelrichsgarcia.de', 'iv.ggtyler.dev', 'inv.tux.pizza', 'yt.drgnz.club', 'inv.us.projectsegfau.lt'];
function getRandomInvidiousInstance() { return invidiousInstances[Math.floor(Math.random() * invidiousInstances.length)];}
(async function () { let retries = 5; let invidiousFetched = false;
async function fetchInvidiousData() {
try {const response = await fetch(`https://${getRandomInvidiousInstance()}/api/v1/videos/${DATA.videoID}?fields=genre,title,lengthSeconds,keywords`);
DATA = await response.json();
if (DATA.genre && DATA.title && DATA.keywords && DATA.lengthSeconds) { if (DATA.keywords.toString() === defaultKeywords ) {DATA.keywords = ''}
ImprovedTube.speedException(); invidiousFetched = true; }
} catch (error) { console.error('Error: Invidious API: ', error); }
}
while (retries > 0 && !invidiousFetched) { await fetchInvidiousData();
if (!invidiousFetched) { await new Promise(resolve => setTimeout(resolve, retries === 5 ? 1234 : 432)); retries--; } }
if(!invidiousFetched){ if (document.readyState === 'loading') {document.addEventListener('DOMContentLoaded', ImprovedTube.fetchDOMData())}
else { ImprovedTube.fetchDOMData();} }
})();
}
} // else { }
}
}
}

really needs refactoring, reformatting and cleaning up

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Completion / Revision Rethink, complete, improve, tweak our feature or structure. good first issue A GitHub standard for inviting (new) contributors *Congratulations in advance!* help wanted Just an old github standard we add automatically. (The team can remove it when working on it.) Open! Not to forget. Unfinished (or waiting for a requirement) (unless combined with label: riddle) Riddle up-for-grabs (a github standard for inviting new contributors) - Welcome! ♥
Projects
None yet
Development

No branches or pull requests

7 participants