torkell: (Default)
So apparently, the way to sell games these days is to supply maybe a dozen copies for the entire country and let everyone fight it out with eBay scalpers. Because of course being perpetually out of stock is an excellent indicator of how popular a game is - look, it's so popular we sold out within 5 minutes it's the fastest selling game ever!!!1111!!111!11one.

I can quite understand why some posters online are rage quitting franchises and consoles over this. What's the point of buying a console if the games you want are never available for it, or even more aggravating when the game is available but the extras (*cough*amiibo*cough*) aren't?

The special edition of Metroid: Samus Returns is a good example of this - judging by Reddit, not only did Amazon run out of stock within a minute of opening pre-orders they then cancelled a whole slew of accepted orders. Meanwhile Nintendo's website lasted less than an hour before taunting everyone with an "Out Of Stock" button, and the official line from them is "we don't currently have details on whether we will be getting more of these in stock" (I emailed and asked). The result: if you want the special edition, you have to pay an eBay scalper a minimum of a 50% premium for it. Funnily enough I don't feel like supporting scalpers... and in the meantime I've not bought the standard one because if Nintendo does release more of the special edition I'd feel very silly having two copies of the game. So Nintendo, a direct result of your failing at pre-orders (and lack of indication as to if there will be another run) is right now a lost sale of either edition.

Sigh. Well, if publishers aren't actually interested in selling products, then it's their loss.


Edit: between writing and getting round to posting this rant, I got an email from a stock notification I'd left on alza.co.uk (who actually understand the concept of subscribing for updates, unlike Nintendo, who merely suggested that I "keep an eye on the website for any information on future incoming stock"). A short while later I managed to successfully order their one (!) leftover copy of Metroid: Samus Returns Legacy Edition, and a parcel is now on its way from Prague of all places.

Dear Tories: please don't destroy the common market, I like being able to just buy stuff from Europe without faffing around with customs and import duties (then again, the last couple of CDs I ordered from outside the EU survived customs unchallenged despite being marked "gift, £1"...).

I also managed another rare find: a boxed, unused Amiibo (Fox from the Smash Bros collection) on sale for only £8 - that's less than the official retail price - at the local second-hand games shop. That was very surprising given that they were selling unboxed Ocarina of Time Link Amiibos for £45 each!
torkell: (Default)
I've voted, and not for you!

And you know what? I might even have not voted for the same party as you. I might have voted for the Tories while opposing their NHS plans. I might have voted for Labour while disagreeing with their transport policies. I might have voted Lib Dem while opposing their political reforms. I could even have voted Green while disagreeing with their energy proposals.

I looked at the options and considered the policies. I voted based on what I agreed with and what I disagreed with.

And most importantly, not based on how my Facebook feed was screaming at me about how I absolutely must vote a particular way because anyone who doesn't vote that way is obviously an evil person who obviously hates the poor/rich/healthy/ill/young/old/homeless/homeowners/privatisation/nationalisation/community/companies/locals/immigrants/dolphins/foxes.

jFLAC rant

Jun. 4th, 2017 08:46 pm
torkell: (Default)
So my latest bonkers programming project is a tool to detect if a collection of audio files are gapless or lot. Now, before anyone gives the obvious answer of "check the CD the files came from", I should point out that these are free albums from the like of OCRemix and so there is no source CD.

Anyway, I had the idea to check if the last second of each track was similar to the first second of the next one, perhaps by running it through a Fourier Transform and looking to see if there's similar peaks in the output. To do that I need to do two things: decode the audio track (these are in FLAC format), and run a FFT over the output.

Surprisingly, it's the first part that's proving to be the hard one. Java-based FLAC decoders are a bit thin on the ground and the only one I've found is jFLAC, last released in 2008. It looks suspiciously like a port of some C-based code with chunks commented out until it compiled... but it does at least open the stream and parse the header with what's not the most terrible API I've come across. Having got that far I then spent the past hour bashing out code to seek to a probable location, search for the start of the last second of audio, and then pull all the data out.

Does my sample-munging code work? Well, I don't know, because jFLAC just spat a STREAM_DECODER_UNPARSEABLE_STREAM exception out at me which turns out to be because it's actually an incomplete implementation and doesn't support a slightly newer encoding added to the spec in 2007. Sigh.

Ironically enough I'd been considering writing my own Java FLAC decoder because of how unfriendly the API was in places - looks like I will be doing that after all... (yes, I could raise a bug and/or try to fix jFLAC, but that's not been touched since 2011 and appears abandoned...)

jFLAC woes

May. 20th, 2017 10:02 pm
torkell: (Default)
In today's instance of "it's all terrible", I'm trying to decode a bunch of FLAC audio from Java (I've got a half-baked idea for trying to determine if a sequence of files should be gapless or not by comparing the end of one with the start of the next - and no, I can't just check the original CD because these are online albums). A quick search threw up jFLAC which is a port of libflac (the reference decoder) to Java. Unfortunately there's not much documentation - well, the classes are somewhat JavaDoc'd but there's no overall "how do I use it" documentation - so I'm left puzzling through the source and the demos to try and work out how it all fits together.

The answer is, not well.

FLAC files start with a bunch of metadata records. jFLAC has a bunch of corresponding classes that implement the different metadata records, along with a method in FlacDecoder to read them. Now, there's several standard ways to implement polymorphic record classes but they generally involve having a superclass with an overloaded method to work out what your subclass is. Sadly the jFLAC Metadata class has no such method so I'm left doing a bunch of sequential "if (record instanceof ThisThing) {} else if (record instanceof ThatThing) {}..." tests. That's annoying but I can cope with that. Then I discover that half the metadata classes provide no way to read the values from them. Sigh.

The next puzzle is seeking. Now, what I want is the first second and the last second of a file and preferably without decoding everything inbetween. Fortunately there's a handy decode() overload that takes a pair of SeekPoint objects. Unfortunately this requires me to know the stream byte offset to seek to. Fortunately I can guess and it'll search for the next valid frame so I could do my own binary search through the stream to find the frame I want. I then just have to handle potentially decoding multiple frames and joining them together, trimming off unwanted leading/trailing data to get the audio samples I want (and recombining bytes into samples and de-interleaving the audio, because jFLAC just gives me a stream of bytes rather than samples...).

I'm seriously tempted to just write my own FLAC decoder...
torkell: (Default)
Can you spot the problem with this screenshot?

Schrödinger's question )

Apparently I've simultaneously asked and not asked a question.

As to why I'm wandering through Facebook "Help" Community... well, when I created an event a couple of weeks ago I'm sure there was an option to message all guests. I now can't find it, despite Facebook's official help claiming there should be a nice obvious "Message Guests" link. And the Help Community is a complete joke because the answers are either epically out-of-date, say you can't do whatever it is you're trying to do, answer the wrong question, or are just plain wrong ("How do I message all guests?", "You click the Message Guests link", "There's no link").

Fine, I'll just manually create a group message and send it out. And then badger everyone in-person because Facebook is terrible for timely communication.
torkell: (Default)
I think I've cracked Facebook's approach to deciding what to show in the laughably-named News Feed...


A friend liked a bunch of photos uploaded by someone you've never heard of: OMG THE MOST IMPORTANT THING IN YOUR LIFE EVER IT'S SO IMPORTANT THAT IT MUST APPEAR MULTIPLE TIMES

A friend posted that they're moving house: whatevs, no-one cares, let's just pretend that post never happened


Trying to sort by Most Recent is in some ways worse because while things are sorted correctly, Facebook then picks a different random selection of important posts to hide and pointless likes to show. And then after a couple of refreshes reverts back to Top Stories without telling you, because obviously something that happened a week ago is far more important than what your friends just posted.

It doesn't help that Facebook randomly change the interface every few months and so all the advice online is woefully out of date. It's almost as if Facebook don't actually want to make a useful service...
torkell: (Default)
You would have thought putting together an audio CD complete with labels and tray inserts would be an easy job, no?


Pitfalls so far:

The CD labels from Staples have the wrong dimensions on the guide sheet. And for added laughs, the sheet is ever so slightly not symmetric (the labels are offset 16mm from one end but 15.5mm from the other).

Nero CoverDesigner doesn't have any native support for printing CD booklets/inlay inserts with double-sided printing. That's annoying but can be worked around with carefully crafted paper stock definitions (and whatever other failings it has, it allows very precise positioning of the separate elements). Except...

Some interaction between Nero and Canon's printer driver is screwing with the co-ordinates when printing. It appears to have applied a rotation to the co-ordinates, but not to the images on the actual page, so a template intended to print in the top-left corner as [P1|P2] actually prints in the bottom-right corner as [P2|P1]. I'm fairly sure this is Canon's fault as using a PDF "printer" doesn't show this problem - though it may also be because I've crafted a paper stock with landscape-orientated but portrait-fed A4 to get the correct layout for a 4-page booklet. Still, that can be worked around with increasingly insane paper stock templates.

Oh, and Nero sometimes doesn't quite get the concept of print bleed area right and seems to not bother with any bleed area for the CD booklet. Instead it looks like it scales the label which is not helpful. It also prints circle crop marks on the CD labels which is pointless as those are printed on precut label paper.

And that's all before I try to actually add the images to the labels, and discover such fun things as whoever put the artwork together has added random amounts of padding on the images (especially annoying for CD labels as that means I can't just centre the image on the template), used the wrong aspect ratio for booklet and inlay inserts, and created two-page spreads that need to be carefully carved up into a front and a back image (after removing padding, cropping to the correct size, and adjusting for the now asymmetric bleed offset).

Then comes the fun of burning the CD. There's surprisingly little in the way of CD-burning software that still works in Windows 7 - Nero used to be the CD-burning package, but the version I've got merely implodes half-way through setting up the project. PlexTools fares a bit better but is full of annoyances, like drag'n'drop not working, and inserting tracks in reverse order when selecting multiple files. And then when it comes to actually burning the disc it just spat the blank back out and sat there at 5% forever (apparently because when it claims to support FLAC files what it really means is it only supports 16-bit sample depth. Because of course ejecting the CD means "File format not supported", nevermind that it does show a sensible error when faced with a 24-bit WAV file...).


I swear, this all used to be easier to do even back in the terrible Windows 95 days of ASPI layers and EasyCD.


Then again I suppose we have made some progress - these days, when PlexTools finally decides that yes, it will deign to burn a disc, it can do so at 20x while decompressing a FLAC source on-the-fly and without having to worry about buffer underruns. That's something you couldn't do in the Windows 95 days.
torkell: (Default)
Today's discovery is a whole pile of messages in Facebook Messenger that various people have sent me over the years, which Facebook has "helpfully" hidden because the senders aren't FB friends. That's all very well except several of the senders are real-life friends who needed to get in touch with time-critical messages. Such as trying to arrange a worship group practice at church - discovering that message 6 months after it was sent is not useful.

The useful thing to do would be to display a notification (that's not hidden) saying someone wants to get in touch, which I can then accept or reject. Like, oh, how MSN Messenger or Yahoo Messenger used to handle this back around 2004 when instant messengers were actually user-friendly.

Possibly the answer is to use something else. WhatsApp seems to be the current cool one, but is terrible in its own way because it only works on your mobile (and yes, I know WhatsApp Web exists - except that only works if your phone is on and connected to the internet, because it's basically a remote control for your phone. And WhatsApp Desktop is a remote control for WhatsApp Web because why do something sensible when you can do that instead). Skype is basically MSN Messenger with all the features removed, the current Yahoo Messenger has likewise been stripped down to the bare bones and then some more (it doesn't even do online/offline status!)... and I'm not sure if any of the other classic ones (ICQ, AIM) still exist. Or have any features left.


Last-minute update: just I was about to post this, the tab for the Facebook website flashed a "(1)" in the title showing that there was some sort of update. It then completely failed to open the chat window, highlight the messenger icon, or do anything at all to show me that I'd just received a message from a FB friend. Because doing any of those would be a useful thing to do, and FB seems determined to not do anything useful. Sigh.
torkell: (Default)
Okay, so some of this is my own fault for not placing the order sooner, but still that's no excuse for the sheer amount of fail on some online stores.

Argos get particular bonus fail points for teasing me with the appearance of it actually being available - yes, on the item page it comes up as out of stock for home delivery but that's an ambiguous message as this is for a pre-order and in any case the site will happily let me add it to the virtual trolley. So far so good, right? Well, on the trolley page it lists two options: store collection which comes up as "not available" (again, unsurprising), or home delivery which says - wait for it - "Pre-order to be delivered on 3rd March 2017". Complete with a green tick! Except, the Continue with Delivery button underneath the table is greyed out and doesn't do anything, so apparently the delivery options given are blatant lies and it's not available at all. But it get weirder - if I add a random unrelated widget that is definitely in stock, then suddenly I can continue with the order! So is it available or not?

On to Game's website. Searching for the item didn't list the variant I want, which is odd as I know it was on there a week ago. So I pulled the URL out of the browser history and it loaded up the correct page with all the right details and the message "1 Day to Release - Preorder Now"... and a total lack of any button or link to actually pre-order it. I suppose that does explain why it didn't appear in the search results.

I could try Game-the-physical-store, except what they have on display bears absolutely no relation to what they actually have in stock and last time I pre-ordered something from them (a good few weeks in advance!) they "ran out" of the pre-order bonus, because apparently how much stock they get shipped bears absolutely no relation to how many pre-orders they've actually taken.

Amazon... they list it in the search results, complete with price and the message "Available for pre-order". Cool! And then I actually go to the page for the item, and instead it says "Currently unavailable. We don't know when or if this item will be back in stock". So that bit on the search result was another blatant lie, then.

At least Nintendo have the grace to actually say "Out of stock" on their website. Well, on the item page - the search results has a "More info" link rather than "Out of stock", but that's instead of the usual "Add to basket" and so at no point does their website pretend it's in stock when it isn't. Congratulations, Nintendo, you've created an online store that doesn't lie to the customer!
torkell: (Default)
Riddle me this...

What's the point of having a footer on a webpage with infinite scrolling? You can't scroll to the end to click on any links in the footer, because whenever you do the page loads some more stuff and the footer disappears off the bottom of the screen!
torkell: (Default)
Okay, how do likes work on LiveJournal? All I get is an email saying:

"1 user(s) likes this - http://boggyb.livejournal.com/488309.html"

As best as I can tell that's it. I can't see how many likes I have on an entry (for that matter I don't even have a like button), and the like statistics page is empty.

The FAQ does say that this needs the new design and one of the new styles - but I still don't see like buttons even after switching to the new site design (which I'd prefer not to use as it's fallen into the trap of assuming that everything has to be designed for mobile - Vertigo is a far more useful scheme with the left-hand link bar and the smaller journal banner) and previewing my journal in the Air style.

Oh, wait, but if I try the Expressive style then it does appear (so much for that FAQ claiming that Air supports this). Interesting. It seems like there's an entirely new function to generate the likes button:

var int likus_journal_id = $.journal.userid;
var int likus_post_id = $.itemid;
var string likus_url = $.permalink_url;

print get_lj_entry_likus("li", "asset-meta-likus item", $likus_journal_id, $likus_post_id, $likus_url);


And that looks is implemented in the base layer as:

function get_lj_entry_likus(string tag, string class, int journal_id, int post_id, string post_uri) : string {

    # LJSUP-24066
    if( not is_likes_display() ) {
        return "";
    }

    # for js LJSUP-18559
    return """<""" + $tag + """ class="$class" lj-likus lj-likus-journal="$journal_id" lj-likus-item="$post_id" lj-likus-uri="$post_uri"></""" + $tag + """>""";

}


Hmm... I wonder if I can hack it into my S2 style? All this does is add a placeholder HTML element so it would seem the actual like button is generated with Javascript - which is a bit annoying as that makes it hard to customise. I might be able to do something with suitably crazy CSS hackery.

Not that such a feature should need a new journal style anyway. S2 is designed to cope with new features without needing all styles to be redesigned - for example, the way the per-entry links work ("Edit Entry", "Add to Memories", "Share" and so on) is that the S2 engine provides a list of actions and a function to generate each link. So adding a new one is straightforward, and unless the style writer has gone for an entirely custom layout ignoring this list then it will Just Work.

Sigh. It does annoy me that the current trend in, well, everything computing-related is to remove open-ended customisability because maintaining it requires effort, and that sounds too much like actual work compared to rewriting everything in the latest shiny framework.
torkell: (Default)
So I was chatting with [livejournal.com profile] pleaseremove as he was on his way home, and the call dropped. This is not unexpected - his route goes through an area of patchy signal that regularly eats phone calls (Devon is a bit like that).

What was unexpected is that when he called me back, he commented that at the same time as the call dropped his phone received an email. So mobile operators have solved the non-problem of being able to send/receive emails from anywhere, but have in the process broken phone calls. Isn't the future wonderful?

The hilarity is in the past I've worked on phone networks, and so I have some idea of why everything is so broken. The short answer is 4G is awesome for data... and terrible for everything else. And the hilarious answer is there's no need for it to be terrible - voice over 4G should be a straightforward SIP call except that appears to be too much like hard work and so until I think late last year a 4G phone would fallback to 2G/3G to make a phone call. While SMS over 4G is just terrible by design (I should know, I once wrote a IP-SM-GW gateway to deal with it) - there was a wonderful opportunity to remove the 160-character length limit and the crazy 7-bit-packed encoding, and instead the solution is to take the radio-level packets from a 2G phone and tunnel them over SIP.


xkcd #1760


Anyway, after that [livejournal.com profile] pleaseremove had the bright idea of trying Skype instead since data seemed bizarrely more reliable than voice calls. Let's see how well that worked...

*** Call from [livejournal.com profile] pleaseremove ***
*** Call dropped, duration 01:39 ***
[livejournal.com profile] pleaseremove: I give up
[livejournal.com profile] pleaseremove: Speak to you whenever

We're not sure what happened. Our best guess is that as he got home his phone picked up his wifi signal, tried to switch to using wifi for data, and ate the call. Because migrating a Skype call from one internet connection to another is Hard... except funnily enough I'm currently working with VoIP tech, and modern VoIP protocols can do this. Theoretically. If whatever WebRTC stack you're using has actually bothered to support it.
torkell: (Default)
Today's discovery is that the National Trust have redesigned their website, and it's a shiny new tablet-friendly one that amazingly is somewhat usable on a desktop. Of course trying to read anything requires crazy amounts of scrolling and waiting while bits of the page are dynamically loaded and fade into view, but at least it's not a complete guessing game trying to work out which parts of the website can be clicked on to do stuff.

This usefulness lasted up until I decided to search for nearby places. Now, every location-based site since, oh, the turn of the century has both list and map views for such results, because maps are an incredibly useful way to show an overview of the results but lists are better for details. Except the National Trust site, which contains no maps whatsoever and displays a grid of tiles that may or may not be sorted in any useful fashion (certainly there's no way to control the sort order). So it's impossible to see which places are actually nearby and which aren't at all (like anything on the Isle of Wight, because that involves crossing the Solent). It's also very hard once you've found a place to work out where it is - the directions page has a link to Google Maps, which drops a pushpin with an unhelpful name (like "1 Church Cottages" for "Hinton Ampner").

And finally because that's not enough fail, searching for events lists the results sorted by location. Not date. And there's no filtering, so I actually can't search for events during a specific time range - instead I have to scroll through pages of irrelevant events that don't start until the middle of next year. Sigh.
torkell: (Default)
Today's important road safety lesson comes courtesy of a pair of chavs who don't understand the Green Cross Code.

If you're waiting to cross the road, the lane of traffic nearest you is stationary, and the light showing for traffic is still green (implying that the light for crossing is still a red man)... then do not assume that it is safe to cross. Because cars in the next lane cannot see you and will be approaching.

This was demonstrated by the chavs at the Quay Street Roundabout - this particular crossing has three lanes entering the roundabout, the right-most lane was waiting behind the stop line because their lane on the roundabout was full (not because they were giving way to pedestrians or because of the lights), the lights were green, and the other two lanes were empty. So the chavs decided to cross the road right in front of me as I was approaching in the middle lane. Fortunately we all stopped in time to avoid a collision.

Of course, the chavs then yelled at me because "the other cars stopped", despite the light still being on green for me and red for them. Congratulations, you fail at crossing the road.
torkell: (Default)
It's rather crazy that despite Flash being completely the wrong tool for playing videos, it does a better job than whatever Firefox uses for HTML5 video.

It's very crazy that on the modern Internet the state-of-the-art for video playback is so much worse than what any half-decent media player could do 15 years ago. Seriously, are DXVA and video overlays still a thing, or does everything just throw all the pixels at the CPU and hope that it's fast enough?
torkell: (Default)
Today's discovery is that if the "mv" command can't simply rename a directory due to permissions, then it'll copy the directory structure. Then attempt to delete the old directory structure, fail because of the aforementioned permissions, and spew umpteen bajillion lines of error messages on the console.

Now, a sensible program would have just said that the file permissions didn't permit renaming and stopped there.

Sigh. Now to unpick the mess and check if it did actually copy everything or not.
torkell: (Default)
You know the current state of desktop email is bad when you're seriously considering writing your own email client...

Though really, it's not the email side of things that's the problem - it's the complete worthlessness of the address book in just about every desktop email client. Back when I first upgraded to Windows 7 I tried several programs to find that they all have ridiculous limitations, broken import/export, or broken multiple account support.

All I want is an email client that can handle multiple email addresses per contacts (and I don't mean just a "work" and "home" address, I mean multiple), has an importer that actually works, and can speak to more than one IMAP account. Oh, and I want something that's current and nice-to-use - running Outlook Express in XP Mode is tempting, but a poor solution as it's woefully out of date. All of these are not only long-solved problems, but also used to work perfectly in Outlook Express. So why is it nothing today can do this?

This rant brought to you by starting to write an email and discovering that the Windows Live Mail contact importermangler had thrown away half the addresses in a group. Then having to play the "which of these identically named contacts contains this person's current email address" game to try and repair it. Sigh.
torkell: (Default)
Today's random discovery is that, on Linux, carriage returns are valid characters in directory names.

How did I find this out? Because Bash is stupid and doesn't understand that a carriage return is a line delimiter. Instead it thinks the character is a literal character (like a letter or number), and so turns mkdir /foo/barCRLF into mkdir /foo/barCR. This creates a directory named "bar" followed by a carriage return. Which of course appears as merely "foo" in a web page, leading to all sorts of fun questions as to why a listing of /foo claims "bar" exists when listing /foo/bar returns an error.

But surely we can get around this with quoting? Surely mkdir "/foo/bar"CRLF will work?

Nope! See, Bash tries to be clever, and moves the CR inside the quote marks. Seriously. It then runs mkdir "/foo/barCR".

I eventually resorted to putting a comment at the end of every line to get this to work (and no, the obvious fix of using Linux line endings was not possible because this script was being entered in a web page, and line endings in web page forms are always normalised to CRLF). Sigh.

A bit of background for non-techies: computers these days generally use one of two sets of control characters to end a line of text. Windows uses a carriage-return/line-feed pair (CRLF), while Linux uses just a line-feed (LF). Most of the time this isn't an issue as any text editor smarter than Notepad understands either style.
torkell: (Default)
How to develop software:

1. Pick a popular, useful program.
2. Rewrite it from scratch with only half the features the old one had.
3. Add a couple of shiny new buzzword-compliant features.
4. Give it a completely new user interface using the UI toolkit of the month.
5. Add an import feature that doesn't actually import everything.
6. Launch the new version with great fanfare.
7. Discontinue the old version. For bonus credit, erase all mention of the old version from your website.
8. Whenever someone asks why the new version doesn't do something useful that the old one did, claim that the change is "by design" and then ignore them.
9. Go to step 2.

Today's particular rant is directed at Windows Live Mail, which is the replacement for Outlook Express. And is missing such fundamental features as a purge command for IMAP folders (without which it is actually impossible to delete emails).

Microsoft has also decided that instead of integrating with Windows Contacts (itself the replacement for the Windows Address Book), Windows Live Mail will instead use its own contacts directory. Which doesn't store anywhere near as much information as Windows Contacts does. So after importing the contacts I've ended up with email addresses arbitrarily (and usually wrongly) assigned as being the "personal", "work" or "other" addresses, except when a contact had more than 3 email addresses in which case it's actually created multiple contacts. With the additional contacts containing only the email address and not the person's name.

Except when it randomly chooses to import just an email address and not the name of a contact.

I'm close to just giving up on the whole thing and firing up Outlook Express in XP Mode, which despite all the hassle of essentially running a Windows XP virtual machine purely for email has the massive advantage of actually working.
torkell: (Default)
We've completely forgotten how to make user interfaces, haven't we?

Today's example is the permanent link for a tumblr post, which is the cute little maybe 16x16 pixels folded-corner-of-paper icon that only appears when you mouseover a post, and has absolutely nothing to suggest that it might even be a link. Let alone the link to the current post.

Compare with, I don't know, just about any other blogging platform where the post title is the permanent link. And even if there is no title (such as on this post), then it's usually something like the post date or even something saying "link", and in any case it looks like a hyperlink.

May 2025

S M T W T F S
    123
45678910
111213141516 17
18192021222324
25262728293031

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 8th, 2025 06:06 pm
Powered by Dreamwidth Studios