';
jNode.closest(".audio-stream-box").append( mdbPlayerAndToolkit );
jNode.hide();
}
if( playerUrl ) {
// toolkit output
waitForKeyElements(".mdb-player-audiostream:not(.mdb-processed-toolkit)", function( jNode ) {
logVar( "titleText toolkit", titleText );
getToolkit( playerUrl, "playerUrl", "detail page", jNode, "after", titleText, "link", 1 );
jNode.addClass("mdb-processed-toolkit");
});
}
}
// embed player
waitForKeyElements(".request-summary img.artwork", function( jNode ) {
var playerUrl = jNode.closest("a").attr("href"),
heading = $(".MuiGrid-root h1"),
titleText = normalizeTitleForSearch( heading.text() );
logVar( "playerUrl (in artwork as given)", playerUrl );
// Remove dots from hearthis slugs (So marking as integrated works)
// https://trackid.net/audiostreams/subfader-house
// > https://hearthis.at/subfader/h.o.u.s.e./ >> https://hearthis.at/subfader/house/
var playerUrl_domain = getDomain_fromUrlStr( playerUrl );
logVar( "playerUrl_domain", playerUrl_domain );
if( playerUrl_domain == "hearthis.at" ) {
playerUrl = playerUrl.removeDotsFromUrlSlug();
logVar( "playerUrl (after removeDotsFromUrlSlug() for hearthis.at)", playerUrl );
// change URL in artwork as well
jNode.closest("a").attr("href", playerUrl);
}
if( url != "" ) {
funcTidPlayers( jNode, playerUrl, titleText );
}
});
/*
* Compare page creation date to MixesDB last edit date
* only on positive usage results
*/
waitForKeyElements(".mdb-mixesdbLink.lastEdit", function( jNode ) {
var pageCreationTimestamp = $(".audio-stream-box > div > div > .MuiBox-root:nth-of-type(5) div + div p.MuiTypography-body1").text()
.trim()
// d/M/yyyy
// 1/3/2025, 9:54:50 AM
.replace(/ (AM|PM)$/i, "" )
.replace(/(\d+)\/(\d+)\/(\d+), (\d+:\d+:\d+)$/, "$3-$1-$2T$4Z" )
// m+d.M.yyyy
// 21.1.2025, 13:05:04
.replace(/(\d+)\.(\d+)\.(\d+), (\d+:\d+:\d+)$/, "$3-$2-$1T$4Z" ) // 18.1.2025, 10:43:21
// pad M-d
// 2025-1-3T9:54:50Z
.replace(/(\d{4})-(\d)-/, "$1-0$2-" )
.replace(/(\d{4})-(\d{2})-(\d)T/, "$1-$2-0$3T" )
;
var lastEditTimestamp = jNode.attr("data-lastedittimestamp"); // 2025-01-28T20:26:13Z
pageCreated_vs_lastEdit( pageCreationTimestamp, lastEditTimestamp );
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Tables
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Tracklist table
* via table .mdb-tid-table
*/
// waitForKeyElements
waitForKeyElements(".mdb-tid-table:not('.tlEditor-processed')", function( jNode ) {
logFunc( "funcTidTracklist" );
var tlWrapper = jNode;
tlWrapper.addClass("tlEditor-processed");
// hide banner
$(".MuiAlert-root.MuiAlert-standardInfo").hide();
$(".MuiGrid-container.request-summary").css("margin-top", "0");
var heading = $(".MuiGrid-container .MuiGrid-grid-xs-12 p.MuiTypography-body1").first(),
mixTitle = heading.text(),
totalDur = $("p.MuiTypography-body1:contains('Duration')").closest("div").next(".MuiGrid-item").text(),
totalDur_Sec = durToSec(totalDur);
log(mixTitle);
logVar( "totalDur", totalDur);
// iterate
var tl = "",
li = $("tr", tlWrapper),
i = 1;
logVar("li.length", li.length);
li.each(function () {
var thisTrack = "";
var thisTitle = $(".title", this).text().replace(/\s*\n\s*/g, ' ').trim();
logVar( "title before replacing", thisTitle );
var artist = $(".artist", this).text()
.replace(/\s*\n\s*/g, ' ') // https://trackid.net/audiostreams/nature-one-2024-opening-gayphoriastage
.replace(/([A-Z0-9]),([A-Z0-9])/i, "$1, $2") // https://trackid.net/audiostreams/calvo-at-nature-one-2o17-we-call-it-home
.removeDuplicateNames()
,
title = thisTitle
.replace(")[", ") [") // normalize ")[" in title for futther treatment (removal) https://trackid.net/audiostreams/subfader-subfreaquence-house-tech-house-20100208
.replace(/\s*-\s*(?:feat(?:\.|uring)?)\s+(.+?)(?=$|\s*\()/i, ' (featuring $1)') // Scared Of My Heart - featuring E.R. Thorpe (Andre Lodemann Remix) https://trackid.net/audiostreams/balance-selections-215-james-harcourt#google_vignette
.replace(/ \(\d+ - Remaster\)$/, "") // Foo (Nutt Mix - Remastered 2021)
.replace(/^(.+) [\(\[](.+) - (?:\d+ )?Remaster(?:ed|ing)?(?: \d+)?[\)\]]/g, "$1 ($2)") // All Night (I Can Do It Right) (2016 - Remaster) https://trackid.net/audiostreams/subfader-the-ghetto-funk-show-20090216-mix-2 | Run before below stuff
.replace(/\s*[\(\[][^\(\[\)]*(Digital\s+Remaster|Mastering)[^\)\]]*[\)\]]/gi, "") // Title (2002 Digital Remaster / 24-Bit Mastering) https://trackid.net/audiostreams/dr-packer-live-in-ibiza-august-2025-hard-rock-hotel
.replace(/^(.+) [\(\[]Re-?master(ed|ing|is[ée])?( En)?(?:\s'?\d{2,4})?[\)\]]/gi, "$1") // (Remasterisé En 2002), also [Remaster] https://trackid.net/audiostreams/xmix3-1994-richie-hawtin-john-acquaviva-enter-the-digital-reality
.replace(/(.+) - (.+ (?:Remix|Mix|Version))/g, "$1 ($2)")
.replace(/^\((.+)\)$/g, "$1") // avoid "[000] Inland [Systemscan]" https://trackid.net/audiostreams/shed-josey-rebelle-sven-von-thulen-txl-berlin-recordings-chapter-7-arte-concert
.replace(/^(.+)-\d{4,5}$/g, "$1") // numbers as suffix, e.g. "Track Title-24070" https://trackid.net/audiostreams/alex-kvitta-sonderspur-pod-011281213
.replace(/^(.+) - (.+)$/g, "$1 ($2)") // "Track Title - Some Version" https://trackid.net/audiostreams/dj-hell-mayday-1999-soundtropolis
.replace(/(.+) \((\d+ )?Remaster(ed|ing)?( \d+)?\)$/g, "$1") // "Track Title - (Remaster)" etc
.replace(/(.+) \((\d+ )?([A-Za-z]+ )?(\s*Re-?master(ed|ing|;)?)(\s*(Mix|Version|Edition))?\)$/gi, "$1") // "Track Title - (2013 Japan Remaster; Remastered)"
.replace(/\s+\(Mixed\)/i, "") // remove " (Mixed)" https://trackid.net/audiostreams/balance-selections-234-sinca
.replace(/\s*\((?=Original)[^()]*?(?:\([^()]*\)[^()]*)*\)/gi, "") // (Original Mix (Digital Only)) and variants https://trackid.net/audiostreams/sirarthur-chris-liebing-umek-gayle-san-live-u60311-19991105-1of9
;
let label = "";
let $label = $(".label", this);
if ($label.length && $label.text().trim() !== "") {
logVar( "label before fixing", $label.text() );
label = $label.text()
.replace(/\s*\n\s*/g, " ")
.replace("Records (Distribution)", "Records")
.replace(/[\[\]]/g, "")
.fixTidLabelnames()
.removeMajorLabels()
.removeArtistLabels(artist)
;
logVar( "label after fixing", label );
}
var startTime = $(".startTime", this).text(),
startTime_Sec = durToSec(startTime),
endTime = $(".endTime", this).text(),
endTime_Sec = durToSec(endTime),
previousTrack = $(".MuiDataGrid-row:eq(" + (i - 2) + ")"), // eq starts at 0
endTimePrevious = $(".MuiDataGrid-cell[data-field='endTime']", previousTrack).text(),
endTimePrevious_Sec = durToSec(endTimePrevious),
nextTrack = $(".MuiDataGrid-row:eq(" + (i) + ")"), // eq starts at 0
startTimeNext = $(".MuiDataGrid-cell[data-field='startTime']", nextTrack).text(),
startTimeNext_Sec = durToSec(startTimeNext);
artist = stripCountryCodes( artist );
title = removePointlessVersions( title );
title = removeDuplicateBracketedText( title );
//logVar( "artist", artist );
//logVar( "title", title );
// remove label when its actually the artist repeated
if (label == artist) {
label = "";
}
// dur
if (startTime !== "") {
// first track is gap?
if (i == 1) {
// start tl with gap when first dur is larger than 120(?)
if (startTime_Sec > 120) {
tl += '[0:00:00] ?\n...\n';
}
}
thisTrack += '[' + startTime + '] ';
}
// catch title (feat. artist2) and add to artist
// should actually be catched by TLE (issue#525)
var match = title.match(/\s*\(feat\. [^)]+\)/i);
if (match) {
var featPart = match[0].trim(); // e.g., "(feat. Foo)"
title = title.replace(match[0], '').trim();
artist += ' ' + featPart;
}
// artist - title
if (artist && title !== "") {
var artist_title = artist + ' - ' + title;
// last checks
// if found track is title of Mix CD
// https://trackid.net/audiostreams/groove-podcast-481-bossy-doll-bina
if (/\(Continuous DJ Mix\)\s*$/i.test(title)) {
artist_title = "?";
label = "";
}
thisTrack += artist_title;
}
// fixes on "Artist - Title"
thisTrack = thisTrack.removeDuplicatedVersionArtist();
// label
if (label !== "") {
thisTrack += ' [' + label + ']';
}
tl += thisTrack;
//logVar( "thisTrack", thisTrack );
// gaps
// add "..." row if gap is too laarge
if( !$(this).is(':last-child') ) {
// not last track
var gapSec = startTimeNext_Sec - endTime_Sec;
//log( "-------------------------------" );
//log( "> startTime: " + startTime );
//log( "> startTime_Sec: " + startTime_Sec );
//log( "> endTime: " + endTime );
//log( "> next startTime: " + startTimeNext );
//log( "> gapSec: " + gapSec );
// TID end times sometimes before start time
// https://trackid.net/audiostreams/b5096745-56ad-4d4d-af61-8d16e32e0521
// don't create next "[dur] ?" tracks then
if( endTime_Sec < startTime_Sec ) {
log( "Negative gapSec!" );
tl += "\n...";
} else {
if( gapSec > 30 ) {
tl += "\n[" + endTime + "] ?";
if (gapSec > 180) {
tl += "\n...";
}
}
}
tl += "\n";
} else {
// last track
//log( "> last track" );
//log( "> lastTrack_gap: " + lastTrack_gap );
var lastTrack_gap = totalDur_Sec - endTime_Sec;
//log( "> lastTrack_gap: " + lastTrack_gap );
// is the last track close to end or possible gap?
if (lastTrack_gap > 70) {
tl += "\n[" + endTime + "] ?";
}
if (lastTrack_gap > 240) {
tl += "\n...";
}
}
i++;
});
// API
tl = tl.trim();
log("tl before API:\n" + tl);
if (tl !== "") {
var res = apiTracklist( tl, "trackidNet" ),
tlApi = res.text;
log( 'tlApi ("trackidNet"):\n' + tlApi );
if( tlApi ) {
var tl_arr = make_tlArr( tlApi ),
tl_arr_fixedCues = tidMarkFalseCues( addCueDiffs( tl_arr ) ),
tl_arr_noDupes = removeAdjacentDuplicateTracks( tl_arr_fixedCues ),
tl_fixedCues = arr_toTlText( tl_arr_noDupes );
log( "tl_fixedCues:\n" + tl_fixedCues );
var res_fixedCues = apiTracklist( tl_fixedCues, "trackidNet" ),
tlApi_fixedCues = res_fixedCues.text;
if( tlApi_fixedCues ) {
tlWrapper.before( ta );
$("#mixesdb-TLbox").addClass("mixesdb-TLbox")
.val( tlApi_fixedCues )
.attr( "data-tlcandidate", tlApi );
fixTLbox( res.feedback );
}
if( tlApi.split("\n").length != tlApi_fixedCues.split("\n").length ) {
var info_cuesRemoved = '
Possibly false "?" tracks have been removed due to short cue differences.';
info_cuesRemoved += ' ';
//info_cuesRemoved += ' Max gap: minutes';
info_cuesRemoved += '