<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://karaoke.kjams.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Deusexmachina</id>
	<title>kJams Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://karaoke.kjams.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Deusexmachina"/>
	<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/wiki/Special:Contributions/Deusexmachina"/>
	<updated>2026-06-09T10:51:02Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/karaokeArchiver&amp;diff=11113</id>
		<title>Code/karaokeArchiver</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/karaokeArchiver&amp;diff=11113"/>
		<updated>2016-10-23T05:18:05Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A number of people have asked for a utility to automatically create zip files of their CD+G/MP3 file sets. I did too, so I decided to write my own. I made a BASH script that scans a list of files for files and zips them together. I wrapped it all up in an Automator workflow, so you can just stick in in ~/Library/Services/ and it will then be available via right click for any folder in the Finder. (In anticipation of the flood of Windows users, you&#039;ll have to cook something up in Python.)&lt;br /&gt;
Here is the script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for f in &amp;quot;$@&amp;quot;&lt;br /&gt;
do&lt;br /&gt;
	FILETYPE=`basename &amp;quot;$f&amp;quot;|cut -d&amp;quot;.&amp;quot; -f2`&lt;br /&gt;
MP=mp3&lt;br /&gt;
CDG=cdg&lt;br /&gt;
	if ( [ &amp;quot;$FILETYPE&amp;quot; = &amp;quot;$MP&amp;quot; ] || [ &amp;quot;$FILETYPE&amp;quot; = &amp;quot;$CDG&amp;quot; ] );&lt;br /&gt;
	then&lt;br /&gt;
		FILEPATH=`dirname &amp;quot;$f&amp;quot;`&amp;quot;/&amp;quot;`basename &amp;quot;$f&amp;quot;|cut -d&amp;quot;.&amp;quot; -f1`&lt;br /&gt;
		echo &amp;quot;$FILEPATH&amp;quot;&lt;br /&gt;
		echo &amp;quot;$f&amp;quot;&lt;br /&gt;
		zip -j -m &amp;quot;$FILEPATH&amp;quot; &amp;quot;$f&amp;quot;;&lt;br /&gt;
	fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The easiest way is simply to wrap it in an Automator workflow. Here is how I did it: Just launch automator and drag the appropriate actions from the library to the stage. First go to &amp;quot;files and folders&amp;quot; and drag &amp;quot;Get Selected Finder Items&amp;quot; onto the stage. Next, drag &amp;quot;Get Folder Contents&amp;quot;, selecting &amp;quot;Repeat for each subfolder found&amp;quot; if desired. Next drag Rename Finder items, and change it to &amp;quot;change case,&amp;quot; with &amp;quot;extension only&amp;quot; set to &amp;quot;lowercase.&amp;quot; Finally switch from &amp;quot;Files &amp;amp; Folders&amp;quot; to &amp;quot;Utilities&amp;quot; and drag &amp;quot;Run Shell Script&amp;quot; over. Paste the above code into the appropriate field, and select &amp;quot;usr/bin/BASH&amp;quot; from the pop up menu. If you want you can also drag over &amp;quot;Show Growl Notification&amp;quot; and or &amp;quot;Speak Text&amp;quot; to add a little finesse!&lt;br /&gt;
&lt;br /&gt;
Save as an application, or a Server plugin, or both, and you should be set.&lt;br /&gt;
&lt;br /&gt;
There are two caveats:&lt;br /&gt;
1) SL has a bug (I think) that throws up an error if you do not run this from inside Automator (it runs fine inside) and&lt;br /&gt;
2) if you have mp3s without a matching CDG file, or vice versa, it will zip the single file by itself. There are ways around this, but I&#039;ll leave that to you all as an exercise! :)&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=History/1.0.1beta&amp;diff=10522</id>
		<title>History/1.0.1beta</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=History/1.0.1beta&amp;diff=10522"/>
		<updated>2015-04-24T21:20:18Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
==The &#039;&#039;&#039;Ohlone&#039;&#039;&#039; Version==&lt;br /&gt;
Note: [[History/2.0d0|We have forked]]!  I&#039;m now working on both 1.0.1 and 2.0 at the same time&amp;lt;br&amp;gt;&lt;br /&gt;
This page is in in &#039;&#039;&#039;REVERSE&#039;&#039;&#039; chronological order (latest at &#039;&#039;&#039;TOP&#039;&#039;&#039;)&amp;lt;br&amp;gt;&lt;br /&gt;
* [[History/1.0beta|Previous Version]]&lt;br /&gt;
&lt;br /&gt;
Please follow me on [https://twitter.com/#!/kjams_karaoke the twitters!]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Change_Notification|Get Notified]] when this page changes!&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b78&#039;&#039;&#039; not out yet but you can [[downloads/Rogues|get the Rogue]]==&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLite.dmg|Lite Mac|/downloads/Lite&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsPro.dmg|Pro Mac|/downloads/Pro&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2.dmg|2 Mac|/downloads/2&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsProWin.exe|Pro Win|/downloads/Pro_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2Win.exe|2 Win|/downloads/2_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
the [http://en.wikipedia.org/wiki/Mistborn_series &#039;&#039;&#039;&amp;quot;Mistborn&amp;quot;&#039;&#039;&#039;] version&lt;br /&gt;
&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* fixed some issues with Manual Rotation:&lt;br /&gt;
** no longer bothers updating &amp;quot;Rotation&amp;quot; and &amp;quot;KJ Rotation&amp;quot;&lt;br /&gt;
** marks a singer as &amp;quot;Here&amp;quot; when you drop a song into the singer&lt;br /&gt;
** marks a singer as &amp;quot;Here&amp;quot; when you switch a song to be sung by a new singer&lt;br /&gt;
** on startup, properly marks singers as &amp;quot;here&amp;quot; or &amp;quot;not here&amp;quot;&lt;br /&gt;
* fixed a major slowdown WRT serving up the &amp;quot;Rotation&amp;quot; playlist from the server. now it should all take place on the background thread instead of hogging the main thread&lt;br /&gt;
* saving playlist is serialized (one won&#039;t start saving until the one already saving finishes) to prevent them from interrupting each other&lt;br /&gt;
* fixed a crash on quit (not the python one)&lt;br /&gt;
* we now no longer check for updates for the Burning &amp;amp; Producer &amp;quot;plugins&amp;quot;, since they&#039;re not plugins any more&lt;br /&gt;
* Mac: having Silverlight installed will no longer crash you if you go to purchase.  kJams will actually REMOVE it ahead of time, then put it back after the purchase.&lt;br /&gt;
* Sorting by &amp;quot;File: XYZ&amp;quot; will now actually sort correctly&lt;br /&gt;
* fixed yet ANOTHER crash on quit (not the above one)&lt;br /&gt;
* fixed the PYTHON crash on quit!  YES!&lt;br /&gt;
* fixed it so &amp;quot;maximum simultaneous downloads&amp;quot; will ignore any number above 2 x (number of CPU cores)&lt;br /&gt;
* fixed crash when duplicating playlists if no sort column info was set&lt;br /&gt;
* finally fully fixed the problem of importing a song file whose name has a dot in it (eg: &amp;quot;Mr. Bojangles&amp;quot;), it would remove everything after the dot&lt;br /&gt;
* Win: clicking the &amp;quot;Time Elapsed&amp;quot; text in the LCD display now switches to showing &amp;quot;Time Remaining&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b77&#039;&#039;&#039; April 6, 2014, the [http://en.wikipedia.org/wiki/List_of_spells_in_Harry_Potter#Expecto_Patronum_.28Patronus_Charm.29 &#039;&#039;&#039;&amp;quot;Patronus&amp;quot;&#039;&#039;&#039;] version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLite.dmg|Lite Mac|/downloads/Lite&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsPro.dmg|Pro Mac|/downloads/Pro&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2.dmg|2 Mac|/downloads/2&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsProWin.exe|Pro Win|/downloads/Pro_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2Win.exe|2 Win|/downloads/2_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* v76 had all these fixes except the last, so i&#039;m not bothering putting that one up&lt;br /&gt;
* fixed crash if you quit before a music store has a chance to ask if it needs an update&lt;br /&gt;
* fixed crash related to double clicking an item in a Rotation playlist&lt;br /&gt;
* fixed crash in web server&lt;br /&gt;
* fixed crash with &amp;quot;add to library&amp;quot; (Windows only)&lt;br /&gt;
* fixed the web server to &#039;&#039;&#039;actually work&#039;&#039;&#039; again (it was serving up all playlists instead of the singer&#039;s playlists, and didn&#039;t let singers add songs)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b75&#039;&#039;&#039; March 27, 2015, the [https://yourlogicalfallacyis.com/assets/FallaciesPosterHigherRes.jpg &#039;&#039;&#039;&amp;quot;Logical Fallacies&amp;quot;&#039;&#039;&#039;] version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b75r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b75/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d75/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b75r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** Can now address 4GB (up from 2GB)&lt;br /&gt;
** fixed a crash when attempting to export a QT movie (crash when you select a folder to export to)&lt;br /&gt;
** fixed ability to select a folder in the first place.&lt;br /&gt;
** if you select a file when it was asking for a folder, the Open dialog would stop working properly, fixed.&lt;br /&gt;
* fixed an assert if you mark a song &amp;quot;sung&amp;quot; while in the &amp;quot;Rotation&amp;quot; playlist&lt;br /&gt;
* checking for NULL in the server in a place that MAY have been crashing.  we&#039;ll see&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b74&#039;&#039;&#039; March 21, 2015==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b74/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b74r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b74/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b74r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d74/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b74r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b74/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b74r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b74/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b74r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d74/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b74r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed a crash any time the database saves(!)&lt;br /&gt;
* you can now set a secret pref to organize your &amp;quot;kJams Music&amp;quot; folder by Album, instead of by Artist then Album&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b73&#039;&#039;&#039; March 20, 2015, the [http://hpmor.com/ &#039;&#039;&#039;&amp;quot;Harry Potter and the Methods of Rationality&amp;quot;&#039;&#039;&#039;] version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b73/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b73r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b73/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b73r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d73/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b73r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b73/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b73r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b73/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b73r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d73/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b73r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** fixed long standing bug! when you go to burn a disc, the assembly would halt part way through, no error, no message, no reason why.  you&#039;d have to repeatedly press burn to get it to finish.  FIXED!!!!  HAHAAA!  Thank you to &amp;quot;Rob D.&amp;quot; for your patience and diligence in helping me find this vexing bug!!&lt;br /&gt;
** &amp;quot;spooler&amp;quot; threads are now prioritized a little lower than the main thread, to give more CPU time to the user interface&lt;br /&gt;
** no longer logging that it could not find the trash folder&lt;br /&gt;
** some files that could not be found will now be found (eg: when burning a playlist that has a SPACE as the last character in the name)&lt;br /&gt;
* now supports zipped KMA files&lt;br /&gt;
* no longer sometimes hangs when attempting to push AND pull meta on a file at the same time&lt;br /&gt;
* now logging just before push or pull MP3 tags, so if it crashes we know what file was the culprit&lt;br /&gt;
* the &amp;quot;pipe&amp;quot; character (&amp;quot;|&amp;quot;) is now a valid delimiter for &amp;quot;reinterpret names&amp;quot;, so you can fix names like &amp;quot;0001|U2|All Because of You&amp;quot;&lt;br /&gt;
* fixed a crasher when reading malformed MP3 ID3 tags&lt;br /&gt;
* no longer including extra erroneous &amp;quot;auto crossfader&amp;quot; script (mac only)&lt;br /&gt;
* you can now cause a &amp;quot;Hang&amp;quot; (for debugging purposes) doing the normal thing to cause a &amp;quot;crash&amp;quot; (which is holding &amp;quot;cmd (ctrl), opt (alt), and shift&amp;quot; while picking anything from the &amp;quot;Help&amp;quot; menu), but then in the &amp;quot;You are about to crash&amp;quot; dialog, hold down &amp;quot;opt (alt)&amp;quot; while clicking &amp;quot;crash&amp;quot;.  kJams will go into &amp;quot;not responding&amp;quot; mode&lt;br /&gt;
* if you cancel a disc burn during the &amp;quot;assembling disc image&amp;quot; activity phase, kJams no longer leaves a song file open (the one it was currently copying into the disc image) &lt;br /&gt;
* when burning a disc, it&#039;s year (in the playlist meta data) is now set to the current year, instead of 2007&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b72&#039;&#039;&#039; March 13, 2015, the &#039;&#039;&#039;&amp;quot;[http://tron.wikia.com/wiki/TRON_3 TR3N]&amp;quot;&#039;&#039;&#039; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b72/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b72r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b72/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b72r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d72/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b72r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b72/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b72r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b72/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b72r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d72/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b72r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* when you [[Deactivate]] kJams, it will now deactivate your plugins&lt;br /&gt;
* after you deactivate, if you had KaraokeCloud, you no longer get a warning that KC does not work in tryout mode when you quit&lt;br /&gt;
* fixed crash if you do a keyboard shortcut when a dialog is up&lt;br /&gt;
* fixed crasher updating some music stores (JSON interpreter error)&lt;br /&gt;
* Pro/2: you can now edit any Singer related meta data in the Venue or Rotation playlists&lt;br /&gt;
* if you &amp;quot;Sync Previous Purchases&amp;quot; on &amp;quot;Karaoke Locker&amp;quot;, you don&#039;t crash, you&#039;re just told that you can&#039;t.&lt;br /&gt;
* the &amp;quot;Saving Database…&amp;quot; activity is now localized&lt;br /&gt;
* when a singer creates a new &amp;quot;Singer&amp;quot; login, white spaces are trimmed, so you can&#039;t create a singer with a leading or trailing space (fixes a crasher too!)&lt;br /&gt;
* possibly fixed yet another server crash (a seemingly endless supply of bugs) related to the timeout causing the session to disappear out from under kJams&lt;br /&gt;
* added more detailed logging to &amp;quot;Add to Library&amp;quot; to catch a bug. &#039;&#039;&#039;Update:&#039;&#039;&#039; Fixed, see next entry&lt;br /&gt;
* fixed: Windows: if you had &amp;quot;hide file extensions of known types&amp;quot; and you go to add to library, select a file(s), and click &amp;quot;open&amp;quot;, it would ignore you&lt;br /&gt;
* fixed a crash when pulling meta data (!)&lt;br /&gt;
* fixed another crash on quit&lt;br /&gt;
* FEATURE: added a &amp;quot;Custom Number&amp;quot; meta data per song.  now you have a numeric field you can edit, and use &amp;quot;numeric search&amp;quot; on (which is very fast)&lt;br /&gt;
* the KaraokeCloud store would sometimes ASSERT about &amp;quot;IsPreemptiveThread()&amp;quot; when logging in, fixed&lt;br /&gt;
* fixed a severe stall in the user interface during server requests for songs (gathering &amp;quot;switchable songs&amp;quot; data)&lt;br /&gt;
* fixed error message when you try to use &amp;quot;Switchable Albums&amp;quot; to switch to a song that already exists in a Singer&#039;s Playlist&lt;br /&gt;
* kJams server can now write JSON instead of PLIST if you know what you&#039;re doing&lt;br /&gt;
* the &amp;quot;You&#039;re about to crash&amp;quot; dialog now goes into the serialize queue, so it won&#039;t overlap another serialized dialog&lt;br /&gt;
* &#039;&#039;&#039;FIXED:&#039;&#039;&#039; another server bug (deref bad pointer check)&lt;br /&gt;
* PowerPC: fixed kJams Lite and Pro so it will run again for you.  why didn&#039;t any of you tell me that it broke?&lt;br /&gt;
* Mac: The &amp;quot;Version&amp;quot; number in the &amp;quot;Get Info&amp;quot; window now just shows the number, no longer showing the name of the app as PART of the version number&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b71&#039;&#039;&#039; Feb 12, 2015 The &amp;quot;[http://en.wikipedia.org/wiki/Star_Trek:_Voyager Voyager]&amp;quot; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b71/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b71r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b71/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b71r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d71/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b71r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b71/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b71r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b71/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b71r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d71/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b71r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** Every time you start kJams, you&#039;d get a &amp;quot;the server resources have changed&amp;quot;.  why did nobody tell me this?  anyway, one last time, and it&#039;s fixed forever.&lt;br /&gt;
** on startup, if kJams needs to log into a music store, it used to just hang there forever.  Now, the &amp;quot;indeterminate&amp;quot; progress bar will cycle during login, showing you that something is actually happening, so you&#039;re not like &amp;quot;is it stuck?&amp;quot;, bonus: it no longer hangs forever!&lt;br /&gt;
** after reloading a music store, the &amp;quot;Stores&amp;quot; folder will remain open if it was before&lt;br /&gt;
** modifier keys could sometimes seem to be stuck down when they should not be, fixed!!  (old bug!)&lt;br /&gt;
* startup is a wee bit faster since i&#039;m not creating tasks for the activity window for each playlist i read in&lt;br /&gt;
* FIXED a crasher related to networking on 10.7!&lt;br /&gt;
* fixed, then broke, then re-fixed ability to load older Singer playlists and previously gotten CD meta data&lt;br /&gt;
* fixed a bug found when stopping a song playing off a CD&lt;br /&gt;
* if KayJayPro is not available when you pick it, it will tell you how to turn it on, rather than silently ignoring you&lt;br /&gt;
* when you stop a song, kJams no longer auto selects the next song in the playlist, unless you&#039;re more than 60% through the song and you&#039;ve got the pref turned on &amp;quot;Stopping a song marks it sung&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b70&#039;&#039;&#039; Feb 4, 2015, the &amp;quot;[https://itunes.apple.com/us/app/brave/id517734835?mt=12 Brave]&amp;quot; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b70/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b70r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b70/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b70r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d70/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b70r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b70/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b70r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b70/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b70r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d70/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b70r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* the new pref &amp;quot;Stopping a song marks it as sung&amp;quot; now ALSO works when you just double click a new song to interrupt a currently playing song&lt;br /&gt;
* fixed a crash on startup&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b68&#039;&#039;&#039; Feb 3, 2015==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b68/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b68r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b68/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b68r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d68/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b68r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b68/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b68r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b68/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b68r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d68/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b68r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac:&lt;br /&gt;
** removed &amp;quot;command-M&amp;quot; to minimize window, since that shortcut was used elsewhere&lt;br /&gt;
** &amp;quot;App Nap&amp;quot; is permanently disabled, regardless of what the checkbox says in the Finder&#039;s &amp;quot;Get Info&amp;quot; window&lt;br /&gt;
* Windows:&lt;br /&gt;
** file dialogs will now open to the proper location, instead of always opening to the kJams folder&lt;br /&gt;
** you can now select multiple items in the file dialog&lt;br /&gt;
** in prefs-&amp;gt;importing, the &amp;quot;QuickTime&amp;quot; encoder now has new / updated presets&lt;br /&gt;
* Server&lt;br /&gt;
** better logging of Sessions&lt;br /&gt;
** fewer leaks of Sessions (there are still some)&lt;br /&gt;
** temp files (playlists) served will now never be deleted out from under the server by the cache cleaner&lt;br /&gt;
* certain errors related to networking will now be reported more specifically, rather than just getting an unuseful &amp;quot;network error&amp;quot; message&lt;br /&gt;
* fixed the ability for kJams to read CDs that have data tracks (this had never worked!)&lt;br /&gt;
* FEATURE: in the Venue menu, you can now &amp;quot;add singer from other venue&amp;quot;.&lt;br /&gt;
* if the same song is in a playlist twice, one right after the other, it will still work!&lt;br /&gt;
* when adding a song file to the library, it will no longer show the file name extension as part of the song name&lt;br /&gt;
* i have had SO MANY people buy kJams and the Burning plugin only to discover their drive is not even compatible.  I&#039;m now actively preventing this from happening by forcing prospective buyers to do a burn test before buying.&lt;br /&gt;
* BUG fixed: if you changing the pitch of a song, and that song HAPPENS to be the one that&#039;s playing, then the playing song&#039;s pitch will NOT change unless you changed it for that particular singer&lt;br /&gt;
* on startup, if you hold SHIFT, then the music stores will NOT be logged into, nor added to your Library playlist (which only happens if you have &amp;quot;Show Store songs in main Library&amp;quot; turned on in Store prefs)&lt;br /&gt;
* Switchable Songs and Albums should now be thread safe&lt;br /&gt;
* more logging during startup to find a stall bug&lt;br /&gt;
* attempting video flash / stutter / stall bug fix: drawing the graphics window is no longer allowed to be recursive&lt;br /&gt;
* if the CDDA &amp;quot;lead in&amp;quot; is NOT 2 seconds (as the spec SAYS it should be), you&#039;ll get one warning per bad disc per launch, not a dozen.&lt;br /&gt;
* when logging &amp;quot;dates don&#039;t match&amp;quot; for when a music store needs to be updated, you&#039;ll only get that log line when the dates ACTUALLY don&#039;t match&lt;br /&gt;
* kjams will now make a playlist called &amp;quot;* Corrupted ID3 Tags&amp;quot; for files that have bad tags.&lt;br /&gt;
* added a bit of crash protection if reordering a song goes south&lt;br /&gt;
* &amp;quot;Stopping&amp;quot; a song (as opposed to pressing the &amp;quot;next&amp;quot; button) when it is more than 60% done will now mark the song as &amp;quot;Sung&amp;quot;&lt;br /&gt;
* logged time intervals will now work with unicode characters, rather than converting them to garbage&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b67&#039;&#039;&#039; Jan 7, 2015==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b67/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b67r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b67/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b67r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d67/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b67r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b67/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b67r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b67/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b67r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d67/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b67r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed yet another progress bar problem (activities not finishing)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b66&#039;&#039;&#039; Jan 7, 2015, the &amp;quot;iPhone 6+&amp;quot; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b66/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b66r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b66/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b66r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d66/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b66r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b66/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b66r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b66/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b66r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d66/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b66r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Windows: fixed ability to purchase Burning plugin (!)&lt;br /&gt;
* fixed an error loading XML files.  would leak resources, fail to gracefully exit, causing problems later on&lt;br /&gt;
* fixed bug where &amp;quot;Ring buffer&amp;quot; tasks would sometimes never complete, leading to the CPU running hot, and also failing to quit (aborting background activities)&lt;br /&gt;
* Fixed TriceraSoft initial creation of &amp;quot;streaming time&amp;quot; menu (was missing &amp;quot;full&amp;quot; and &amp;quot;upgrade&amp;quot; options)&lt;br /&gt;
* if you go to burn a song, and a file is missing, kJams now tells you this, rather than complaining that it&#039;s in the wrong format&lt;br /&gt;
* Sort column that used to be called &amp;quot;Pitch&amp;quot; is now called &amp;quot;Key Adjust&amp;quot; (because &amp;quot;Key Changes&amp;quot; and &amp;quot;Key&amp;quot; were taken)&lt;br /&gt;
* when deactivating kJams, it won&#039;t copy the file to the desktop if the deactivation is not successful&lt;br /&gt;
* the Server bug may still be lurking, perhaps i fixed it.  better logging anyway.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b65&#039;&#039;&#039; Dec 23, 2014 ==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b65/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b65r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b65/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b65r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d65/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b65r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b65/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b65r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b65/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b65r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d65/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b65r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Lite: fixed ability to use Preferences without the window closing&lt;br /&gt;
* fixed keyboard shortcuts for changing Key (pitch)&lt;br /&gt;
* more Server logging, so i can catch a bug. grrr.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b64&#039;&#039;&#039; Dec 19, 2014: the &amp;quot;[https://www.google.com/search?q=skylanders+spyro%27s+adventure+%22hidden+treasure+item%22&amp;amp;safe=active&amp;amp;source=lnms&amp;amp;tbm=isch&amp;amp;sa=X&amp;amp;ei=EImUVNbMFIvkoATUtYC4DA&amp;amp;ved=0CAoQ_AUoAw&amp;amp;biw=1084&amp;amp;bih=1064#facrc=_&amp;amp;imgdii=_&amp;amp;imgrc=AlvIRmGExFVuzM%253A%3Bl5plEafDQl8WFM%3Bhttp%253A%252F%252Fecx.images-amazon.com%252Fimages%252FI%252F51ukJnL4B-L._SY300_.jpg%3Bhttp%253A%252F%252Fwww.amazon.com%252FSkylanders-Spyros-Adventure-Figure-Treasure-Includes%252Fdp%252FB0068S09WC%3B289%3B300 Hidden Treasure]&amp;quot; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b64/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b64r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b64/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b64r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d64/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b64r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b64/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b64r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b64/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b64r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d64/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b64r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* yikes my previous &amp;quot;fix&amp;quot; for the audio ring buffer actually caused a greater problem: all the progress bars never went away!  fixed.&lt;br /&gt;
* mac: better memory management (less crashes) around handling apple events&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b63&#039;&#039;&#039; Dec 18, 2014: the &amp;quot;[https://www.google.com/search?q=skylanders+spyro%27s+adventure&amp;amp;safe=active&amp;amp;source=lnms&amp;amp;tbm=isch&amp;amp;sa=X&amp;amp;ei=TomUVOH1O8WuogTWk4C4DQ&amp;amp;ved=0CAoQ_AUoAw&amp;amp;biw=1084&amp;amp;bih=1064 Spyro&#039;s Adventure!]&amp;quot; version==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b63/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b63r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b63/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b63r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d63/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b63r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b63/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b63r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b63/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b63r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d63/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b63r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed lots of missing &amp;quot;virtual destructors&amp;quot;, which could have caused random headaches&lt;br /&gt;
* Mac: AppleEvents (including AppleScripts) will now continue to be processed (but slower) even when the mouse is down in a control (eg: browsing the menu bar)&lt;br /&gt;
* fixed a long standing bug (since the start!) where: when the audio ring buffer&#039;s &amp;quot;leading edge&amp;quot; got to the end, the Task in the Activity window would &amp;quot;complete&amp;quot;, and it would disappear, leaving you with no way to press the stop sign, even tho the song may still be playing.  The bug had the unfortunate side effect that if you, at that very moment, go to scrub the playhead, you&#039;d now get silence, since the input buffer had already been closed.  This problem becomes MUCH more noticeable now with the advent of the &amp;quot;Half Ring buffer size (in megabytes)&amp;quot; secret pref, if you set that to very large (like 8 MB), half the song may be still left, but you can&#039;t scrub it (or it will go silent), and you can&#039;t click the stop sign to stop it.  all this is now fixed&lt;br /&gt;
* fixed an error displaying &amp;quot;star ratings&amp;quot; from very old database files&lt;br /&gt;
* &#039;&#039;&#039;FIXED SERVER CRASHER!&#039;&#039;&#039;: when wtkJams would request the Rotation playlist just at the moment it was being re-built, it would crash.  Thought i had fixed that last may, but i hadn&#039;t.&lt;br /&gt;
* &#039;&#039;&#039;FIXED MAJOR SERVER PROBLEM!&#039;&#039;&#039;: &amp;quot;sessions&amp;quot; were NOT being reset sometimes when new users logged in.  that means a new singer may have been in the session of another singer!  this would cause crashes, and problems with singers accidentally modifying the session of a different singer!  holy cats!&lt;br /&gt;
* &#039;&#039;&#039;FEATURE:&#039;&#039;&#039; kJams Pro and 2: Setting the &amp;quot;Rotation ShowScreen&amp;quot;: In preferences-&amp;gt;Advanced, you can now just pick from a menu instead of having to magically &amp;quot;know&amp;quot; what to type there!  sorry that took so long!&lt;br /&gt;
* i&#039;ve changed the terminology of &amp;quot;Pitch&amp;quot; to be &amp;quot;Key&amp;quot;, since that&#039;s the more correct term (controls menu)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b62&#039;&#039;&#039; Dec 5, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b62/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b62r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b62/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b62r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d62/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b62r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b62/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b62r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b62/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b62r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d62/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b62r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* PowerPC: be sure to update to this version or later.  This version will keep you on the PowerPC build updates.&lt;br /&gt;
* when you have &amp;quot;pause between tracks&amp;quot; and &amp;quot;warn on interrupt&amp;quot; turned on, and near the end of a song you pressed &amp;quot;right-arrow, return, space&amp;quot; in rapid succession, there were these bugs (fixed)&lt;br /&gt;
** with &amp;quot;skip silence&amp;quot; on, the &amp;quot;Who&#039;s up next&amp;quot; rotation screen would stay up, and not go away&lt;br /&gt;
** without it on, you&#039;d loop forever on the first 2 seconds of the song&lt;br /&gt;
* SingStar (UltraStar) files now support &amp;quot;freestyle&amp;quot; lyrics&lt;br /&gt;
* flickering on Yosemite when playing MediaStream files is reduced a bit&lt;br /&gt;
* KaraokeCloud: you can now go monthly on the $99 option&lt;br /&gt;
* a singer&#039;s &amp;quot;here&amp;quot; status is not set to &amp;quot;here&amp;quot; unless you touch the &amp;quot;Tonight&amp;quot; list.  Touching &amp;quot;History&amp;quot; or &amp;quot;Favorites&amp;quot; no longer marks a singer as &amp;quot;here&amp;quot;&lt;br /&gt;
* possibly fixed another crashing bug in the Server.&lt;br /&gt;
* Better error message if you&#039;re offline or a server can&#039;t be found&lt;br /&gt;
* you can now use a [[Secret Prefs]] to set the size of the Ring buffer: &amp;quot;Half Ring buffer size (in megabytes)&amp;quot;&lt;br /&gt;
* in Pro Tryout, if you try to add more than 3 singers, you get a nicer explanation, doesn&#039;t crash, and it doesn&#039;t leave cruft behind causing asserts the next time you start kJams&lt;br /&gt;
* the &amp;quot;Checking Version&amp;quot; activity on startup now tells you what it&#039;s checking&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b61&#039;&#039;&#039; Nov 13, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b61/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b61r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b61/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b61r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d61/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b61r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b61/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b61r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b61/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b61r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d61/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b61r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac:&lt;br /&gt;
** Yosemite: fixed the dark squares behind some controls in the Browser window&lt;br /&gt;
** app is now correctly digitally signed (it had been signed with an expired certificate temporarily)&lt;br /&gt;
** Producer is no longer a separately installed plugin, it is now built in (but still sold separately as an in-app purchase)&lt;br /&gt;
* Burner and Producer strings are now localized&lt;br /&gt;
* fixed several more ASSERTs (illegal CSI task, missing switch case, illegal value type, illegal control type)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b58&#039;&#039;&#039; Nov 11, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b58/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b58r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b58/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b58r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d58/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b58r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b58/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b58r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b58/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b58r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d58/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b58r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* you will now only be warned once per launch about &amp;quot;Tethering does not work in Tryout mode&amp;quot;, instead of like 20 times&lt;br /&gt;
* my build system: now builds using MacOS 10.9 VM, so i can switch my actual computer to Yosemite&lt;br /&gt;
* If you use Gracenote, kJams now asks for a small donation, since it now costs me money every time someone uses it&lt;br /&gt;
* upgraded to latest XCode compiler&lt;br /&gt;
* fixed some new compile warnings relating to operator precedence when adjusting volume or cancelling center channel vocals&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b57&#039;&#039;&#039; Oct 16, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b57/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b57r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b57/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b57r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d57/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b57r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b57/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b57r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b57/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b57r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d57/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b57r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* on first run, kJams won&#039;t ask for your password regarding updating the Auth tools, since they&#039;re already up to date&lt;br /&gt;
* &amp;quot;Add to Library&amp;quot; on songs who&#039;s file name contains a slash &amp;quot;/&amp;quot; works again&lt;br /&gt;
* made the default column width maximum twice as big (1000 pixels)&lt;br /&gt;
* for [[ShowScreens#Changing_the_background_picture_of_the_.22Custom_Picture.22_ShowsSreen|Custom pictures per venue:]] now works with &amp;quot;custom_picture.png&amp;quot; as well as for rotation background&lt;br /&gt;
* made some changes in log thread number reporting to be a bit more optimized, blind fix trying to avoid a crash&lt;br /&gt;
* the checkbox in the warning dialog for KayJayPro (&amp;quot;In order to use the KayJayPro meta data service...&amp;quot;) now works even if you see it just after you start kJams&lt;br /&gt;
* CD Capabilities now reliably log on both mac and windows&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b56&#039;&#039;&#039; Sept 11, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLite.dmg|Lite Mac|/downloads/Lite&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsPro.dmg|Pro Mac|/downloads/Pro&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2.dmg|2 Mac|/downloads/2&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsProWin.exe|Pro Win|/downloads/Pro_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJams2Win.exe|2 Win|/downloads/2_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
not out yet but you can [[downloads/Rogues|get the Rogue]]&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b56/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b56r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b56/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b56r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d56/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b56r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b56/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b56r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b56/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b56r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d56/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b56r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** speed up the new networking stuff (was slowing other operations down)&lt;br /&gt;
** fixed the &amp;quot;compareResult&amp;quot; asserts&lt;br /&gt;
** fixed a bug where, when updating music stores, could cause the Sources window pane to stop drawing (draw as white)&lt;br /&gt;
** on first run, kJams won&#039;t tell you that the keyboard shortcuts have changed.&lt;br /&gt;
** my build system: no longer depends on running kJams first to get the import / export codecs&lt;br /&gt;
** some dialogs had slashes prepended to button names, fixed&lt;br /&gt;
* the &amp;quot;ripping done&amp;quot; sound is no longer insanely loud&lt;br /&gt;
* the &amp;quot;Library&amp;quot; playlist is now obviously selected when you start kJams&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b55&#039;&#039;&#039; Sept 5, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b55/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b55r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b55/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b55r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d55/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b55r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b55/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b55r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b55/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b55r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d55/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b55r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: really REALLY fixed the app to work and auto-update&lt;br /&gt;
* the Python auto-installer works again&lt;br /&gt;
* the &amp;quot;Reset Warnings&amp;quot; button now also resets the RAM warning time&lt;br /&gt;
* more logging the web server&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b53&#039;&#039;&#039; Sept 2, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b53/r0/kJamsLite.dmg|Lite Mac|/downloads/Lite_Mac_101_b53r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b53/r0/kJamsPro.dmg|Pro Mac|/downloads/Pro_Mac_101_b53r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/b53/r0/kJams2.dmg|2 Mac|/downloads/2_Mac_2_b53r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b53/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b53r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b53/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b53r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/b53/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b53r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: WARNING This version won&#039;t even run on Windows&lt;br /&gt;
** fixed the auto-updater&lt;br /&gt;
** dialogs now have all their titles localized&lt;br /&gt;
* Mac will now have [{{SERVER}}/new-dmg-installer-for-mac/ a DMG installer]&lt;br /&gt;
* &amp;quot;Pitch&amp;quot; settings are now also stored with the song file, so if you rebuild your library, you get to keep the pitch changes that were set on songs in your library&lt;br /&gt;
* &amp;quot;help-&amp;gt;web form feedback&amp;quot; will now go to [{{SERVER}}/feedback/ the new page]&lt;br /&gt;
* the new default is to allow single digit track numbers when reinterpreting song names&lt;br /&gt;
* the &amp;quot;Get Info&amp;quot; and &amp;quot;reinterpret&amp;quot; dialogs now have correct name in the title bar on both mac and windows&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b52&#039;&#039;&#039; Aug 25, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b52/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b52r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b52/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b52r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d52/r0/kJams2.zip|2 Mac|/downloads/2_Mac_2_b52r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b52/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b52r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b52/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b52r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d52/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b52r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Server: when searching by &amp;quot;any&amp;quot;, you can will also search &amp;quot;genre&amp;quot;&lt;br /&gt;
* Karaoke Cloud Music Store: if you bought a &amp;quot;Starter&amp;quot; streaming tier, which has not yet expired, and you go to stream a song from the &amp;quot;Full&amp;quot; streaming tier, you will be informed of this and given the choice to upgrade, instead of being confused by a non-helpful &amp;quot;you have to set up streaming&amp;quot; message.&lt;br /&gt;
* fixed &amp;quot;sync previous purchases&amp;quot; and renaming files when editing meta data.  was causing errors and asserts and duplicate songs.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b51&#039;&#039;&#039; August 13, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b51/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b51r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b51/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b51r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d51/r0/kJams2.zip|2 Mac|/downloads/2_Mac_2_b51r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b51/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b51r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b51/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b51r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d51/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b51r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** the Menu commands &amp;quot;About kJams…&amp;quot;, &amp;quot;Preferences…&amp;quot;, and &amp;quot;Exit kJams&amp;quot; are now in their own &amp;quot;Application&amp;quot; menu called, aproprietly, &amp;quot;kJams&amp;quot;.  This makes it consistent between mac and windows, so i can tell everyone &amp;lt;&amp;lt;go to the &amp;quot;kJams&amp;quot; menu and pick &amp;quot;Preferences&amp;quot;&amp;gt;&amp;gt;.  (used to be on windows the Preferences were in a completely different location, now it&#039;s consistent)&lt;br /&gt;
* fixed crasher using &amp;quot;Next Song&amp;quot; command when no song was currently playing&lt;br /&gt;
* fixed (assert) failure when parsing a JSON file (happens with KayJayPro), when there is an entry with more than one comma in it&lt;br /&gt;
* Producer: when you &amp;quot;save over&amp;quot; a showscreen (template), it automatically assigns &amp;quot;Command-4&amp;quot; to the showscreen.  That way you can tweak it, then show it with they key shortcut to see it instantly.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b50&#039;&#039;&#039; Aug 7, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b50/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b50r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b50/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b50r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d51/r0/kJams2.zip|2 Mac|/downloads/2_Mac_2_b50r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b50/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b50r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b50/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b50r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/2.0.0/d51/r0/kJams2Win.exe|2 Win|/downloads/2_Win_2_b50r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac&lt;br /&gt;
** fixed the eSellerate engine problem on MacOS 10.5 (Leopard).  &amp;lt;strike&amp;gt;However, this breaks compatibility with MacOS 10.10 (Yosemite)&amp;lt;/strike&amp;gt; &#039;&#039;&#039;Update:&#039;&#039;&#039; No, it doesn&#039;t.&lt;br /&gt;
** if a file is locked, and kJams needs to write to the file, kJams will unlock it&lt;br /&gt;
* Pro &amp;amp; 2&lt;br /&gt;
** kJams will now shut down the server before switching venues (turning it back on afterward).  This fixes the problem of it crashing if there&#039;s a web client actively using a connection&lt;br /&gt;
** Windows: in the Server prefs, the timeout checkbox and edit text now actually work!&lt;br /&gt;
** the server web page will now grow with your window size, and has a big kJams logo in the background&lt;br /&gt;
* if you edit the meta data of a song, and kJams tried to rename it on disc and it ran into a collision (a song file with the same name), kJams will now automatically uniquify the name and continue, rather than failing&lt;br /&gt;
* label colors are now saved per singer: each singer can label the same song a different color&lt;br /&gt;
* when you paste a column layout (in the Source pane), kJams marks the playlist as dirty so it gets saved&lt;br /&gt;
* if you pause the playlist, then hit right arrow, it will load the next song but stay paused&lt;br /&gt;
* the targeted playlist will now sort above the Venue playlist&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b49&#039;&#039;&#039; July 31, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b49/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b49r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b49/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b49r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b49/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b49r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b49/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b49r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* updates to CFTest project, so i can get the [[Code/CFLite/CFNetwork|CFNetwork]] project going:&lt;br /&gt;
** fixed crash in CFBonjour: i had previously deleted the manager before all threads were terminated&lt;br /&gt;
** updated logging to be more clear&lt;br /&gt;
** updated tests for to emit &amp;quot;PASS&amp;quot; or &amp;quot;FAIL&amp;quot;&lt;br /&gt;
** ASSERT no longer crashes if there is no &amp;quot;gApp&amp;quot;&lt;br /&gt;
* fixed a few errors in the Server Resources:&lt;br /&gt;
** no longer attempting to load a &amp;quot;handheld&amp;quot; stylesheet (which never existed)&lt;br /&gt;
** no longer attempting to load &amp;quot;kjams.jpg&amp;quot;, which also never existed&lt;br /&gt;
** Windows: was not including the &amp;quot;screen.css&amp;quot; file, which was necessary for proper layout of the main singer screen!&lt;br /&gt;
** updating the server resources is now a one-button click, rather than making you [[Server/Update|do it yourself]]&lt;br /&gt;
* Mac: works on Yosemite&lt;br /&gt;
* TriceraSoft: there were several songs listed as &amp;quot;multiplex&amp;quot; in the name, but not marked as such&lt;br /&gt;
* tryout version was supposed to limit you to 10 QT exports, but it was set to 5 instead.  fixed&lt;br /&gt;
* we now fetch the &amp;quot;AirFoil&amp;quot; global slip time at startup, instead of the first time you click a menu.  in case it takes a second extra.&lt;br /&gt;
* if you have a song who&#039;s MP3 ID3 tags are corrupt, you will now be promted to re-encode the song, rather than it failing silently&lt;br /&gt;
* you are now free to edit your &amp;quot;History&amp;quot; (as if it&#039;s just another &amp;quot;Favorites&amp;quot; list)&lt;br /&gt;
* you can now mark any song in the (KJ) Rotation as &amp;quot;Sung&amp;quot; (even a group)&lt;br /&gt;
* if kjams can&#039;t even find it&#039;s own bundle resources on startup, instead of crashing, it logs the failure and exits gracefully&lt;br /&gt;
* fix crasher related to selecting a source item for rename, but the rename is only partially executed before exiting&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b48&#039;&#039;&#039; June 19, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b48/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b48r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b48/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b48r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b48/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b48r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b48/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b48r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** Fixed problem of alt-key seemingly stuck down when picking a menu item&lt;br /&gt;
** fixed assert about sorting, after you update a music store&lt;br /&gt;
** if you name a singer, playlist, or venue some &amp;quot;windows reserved word&amp;quot; it will now be okay.  eg: &amp;quot;con&amp;quot;, &amp;quot;nul&amp;quot;, &amp;quot;prn&amp;quot;, &amp;quot;aux&amp;quot;, etc&lt;br /&gt;
* TriceraSoft&lt;br /&gt;
** started work on &#039;s new &amp;quot;Full&amp;quot; set of streaming songs.  There will be 60,000 songs available for streaming!! OMG!  (of course, it will cost more)&lt;br /&gt;
** if you try to buy a song that you *could* stream, you get asked if you want to get some streaming time&lt;br /&gt;
** if you cancel out of the &amp;quot;get streaming time&amp;quot; dialog, you no longer get into an infinite loop&lt;br /&gt;
** correctly excludes the Multiplex songs when you turn off &amp;quot;Include songs with Lead or Guide Vocals&amp;quot;&lt;br /&gt;
* Mac: compatible with MacOS 10.10&lt;br /&gt;
* fixed rare error when doing any downloading of anything&lt;br /&gt;
* if you attempt to burn and it fails because you don&#039;t have a license, it will auto-open your prefs to the Burning Plugin panel&lt;br /&gt;
* when you drag and drop a set of songs into a playlist, they will now come into the playlist in the order they were from the original playlist (when you sort by #)&lt;br /&gt;
* fixed crasher in Server: when serving up the rotation at the moment that kJams is rebuilding it (eg: between songs)&lt;br /&gt;
* fixed error creating menus with disabled items&lt;br /&gt;
* fixed error when downloading (mostly on windows) where the wrong data size was calculated (could cause errors, failures, crashes)&lt;br /&gt;
* a bit more logging when updating the music stores&lt;br /&gt;
* fixed a potential crasher when failing to create new singer&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b47&#039;&#039;&#039; Cinco de Mayo==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b47/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b47r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b47/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b47r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b47/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b47r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b47/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b47r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* &amp;quot;--- summary add&amp;quot; logging works again, and is now turned off :)&lt;br /&gt;
* GraceNote works again&lt;br /&gt;
* when using any online DB that can return multiple hits, the &amp;quot;Disc Picker&amp;quot; dialog will tell you what DB you&#039;re currently querying&lt;br /&gt;
* wtkJams will no longer bring kJams to it&#039;s knees when multiple people are using it simultaneously&lt;br /&gt;
* fixed crash on windows when loading certain CD+G discs&lt;br /&gt;
* fixed video stutter when kJams must search extensively for a song file&lt;br /&gt;
* when rebuilding, kJams now uses the &amp;quot;add to library&amp;quot; code, so it&#039;s much more resilient, no longer requires the names to be in a certain format, no longer asks &amp;quot;are these two the same&amp;quot;&lt;br /&gt;
* when rebuilding, kjams no longer attempts to weed out duplicates (which takes a long time and doesn&#039;t work well anyway)&lt;br /&gt;
* no longer logging the MAC address unless you hold alt on launch&lt;br /&gt;
* when sorting by &amp;quot;Album&amp;quot; the secondary sort is by &amp;quot;Artist&amp;quot;, tertiary by &amp;quot;Name&amp;quot;&lt;br /&gt;
* CPU Type and number of Cores is now logged correctly for older mac hardware&lt;br /&gt;
* when exporting &amp;quot;playlist: all files&amp;quot;, kJams will now actually for reals export all the files, including xml and MediaStream (Project: KTP, LRC, TXT etc)&lt;br /&gt;
* when rebuilding, kJams will now sort by PLI, preventing crashing bugs that happen when you&#039;re sorted by name, artist, or album&lt;br /&gt;
* fixed Producer Prefs so they actually work.  &lt;br /&gt;
* in Producer Prefs, if you turn on &amp;quot;Don&#039;t Encode CDG&amp;quot;, then you can use a pref called &amp;quot;Producer: minimum fade duration (seconds)&amp;quot;, default is 1/2 second, which dictates just how long a page takes to &amp;quot;fade in&amp;quot;.  You can set it to zero for &amp;quot;cut&amp;quot; transition with no fade time.&lt;br /&gt;
* Exporting &amp;quot;playlist: audio only&amp;quot; is going to be removed.  it never worked anyway.  nobody used it.&lt;br /&gt;
* The following meta-data were never saved to disc: &amp;quot;Custom&amp;quot;, &amp;quot;Sort Name&amp;quot;, &amp;quot;Sort Album&amp;quot;, &amp;quot;Sort Artist&amp;quot;. This has been fixed.  Sorry for that.&lt;br /&gt;
* fixed AppleRemote for 10.9.  i hope i didn&#039;t break it for 10.8&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b46&#039;&#039;&#039; April 17, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b46/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b46r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b46/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b46r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b46/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b46r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b46/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b46r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac:&lt;br /&gt;
** Symbolic links are no longer necessary when you want to move a file / folder out from under kJams.  You can now use plain old aliases&lt;br /&gt;
* Windows:&lt;br /&gt;
** You can now move a file / folder out from under kJams as long as you create a shortcut file in it&#039;s place&lt;br /&gt;
** fixed the QuickTime -600 error when ripping discs or re-encoding or exporting more than one song at a time.  If you get the same error it will have a better explanation (timeout talking to QTServer)&lt;br /&gt;
** Log files for the QTServer are now date-stamped, each one going into it&#039;s own separate file&lt;br /&gt;
** said log files live with the kJams logs, not next to the app&lt;br /&gt;
** progress bar is back when removing lots of songs from the library&lt;br /&gt;
* when syncing music (previous purchases or KC tethering), the SyncBot will now continue to sync even if any of the songs is missing&lt;br /&gt;
* no, really, this time i really DID fix the sort column default widths&lt;br /&gt;
* start-of-string matching is now faster since it doesn&#039;t do extra allocations&lt;br /&gt;
* bonjour logging now says &amp;quot;Bonjour&amp;quot;&lt;br /&gt;
* when checking for modifier keys, we now check both the current state and the state from the event we&#039;re handling.  (fixes ability to use macro programs or UI automation)&lt;br /&gt;
* you can now [[ShowScreens#QR_Code_Messages|show a QR Code ShowScreen]] for the Server address, or for any messenger message&lt;br /&gt;
* the Server will redirect iPhone users to wtkJams instead of iJams&lt;br /&gt;
* if you had ripped a file to unzipped, then you re-rip it to zipped, you no longer lose the file (!)&lt;br /&gt;
* when using quicktime to encode with multi-pass, it should no longer occasionally fail due to the second pass collision with the first pass&lt;br /&gt;
* more logging around gathering Camera info&lt;br /&gt;
* in all xml files, anywhere we write a rectangle, we now write width and height in addition to right and bottom.  when reading, if width and height exist, we use that, else use right and bottom&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b45&#039;&#039;&#039; March 18, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b45/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b45r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b45/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b45r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b45/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b45r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b45/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b45r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** you can now rename a playlist by selecting it and hitting [enter]&lt;br /&gt;
** renaming a playlist will reliably refresh the name after you finish it&lt;br /&gt;
** fixed assert-crash on startup with &amp;quot;s_prevChainH&amp;quot;&lt;br /&gt;
* KaraokeCloud will always log CC validation check&lt;br /&gt;
* Music store update checks will happen RELIABLY now, so you should never end up with no music store or an empty music store, if a store is turned on&lt;br /&gt;
* secret pref to allow XSS&lt;br /&gt;
* Column widths are correctly set again, but you can still make them wicked small if you want&lt;br /&gt;
* Server: no longer setting .css, .js, and .xml to have &amp;quot;Content-Type&amp;quot; as &amp;quot;text/html&amp;quot;, now they are correctly set&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b44&#039;&#039;&#039; March 14, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b44/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b44r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b44/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b44r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b44/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b44r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b44/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b44r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* I had broken mounting of BIN/CUE files, fixed&lt;br /&gt;
* KaraokeCloud will now validate that your CC info got set correctly, and you&#039;ll be warned if it didn&#039;t work!&lt;br /&gt;
* Music stores will ALWAYS Show when turned on (after restart), even when empty.  So that way you can reload it if you need to.&lt;br /&gt;
* Windows: i had broken disc burning, fixed.  also, when validating the disc, i was supposed to skip over the last 8 sectors, now i&#039;m actually doing that&lt;br /&gt;
* Mac: the minimum width of columns is now 15 pixels&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b43&#039;&#039;&#039; March 6, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b43/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b43r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b43/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b43r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b43/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b43r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b43/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b43r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** Fixed Crash: when you are scrolled a bit to the right, and you remove a column, it would crash&lt;br /&gt;
* Fixed bug: sometimes when you switch to a different playlist, select a song, then press the play button, it would play a song from the first playlist&lt;br /&gt;
* Fixed ASSERT &amp;quot;cd_sourceP&amp;quot;&lt;br /&gt;
* Fixed ASSERT &amp;quot;gApp-&amp;gt;i_curScopeP == NULL&amp;quot;&lt;br /&gt;
* the &amp;quot;[stIx]&amp;quot; tag is now legal in your showscreens, but it&#039;s probably not very useful&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b42&#039;&#039;&#039; March 5, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b42/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b42r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b42/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b42r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b42/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b42r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b42/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b42r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** OMG: fixed a major resource leak!  Windows would get progressively slower and eventually crash.  fixed.&lt;br /&gt;
** fixed crash when rendering MediaStream files (KTP, LRC etc)&lt;br /&gt;
** When playing MediaStream files, if the font gets too small and turned to NOT anti-aliased, it used to be invisible when the playing on transparent background, or the sweep text did not sweep properly when not.  both fixed.&lt;br /&gt;
** producer prefs (which you can get to via by holding the alt key and opening preferences) is now complete&lt;br /&gt;
** fixed a crash when progress dialogs come up (which is a lot)&lt;br /&gt;
* OMG2 i broke the saving of singer&#039;s meta data (pitch / tempo etc)  fixed.&lt;br /&gt;
* ShowScreens: when encountering a name with square brackets and four chars in between them, and that resolves to an empty string, kJams no longer loses it&#039;s mind and shows the same singer for the rest of all rotations all night&lt;br /&gt;
* added some more server logging, i think there&#039;s another bug in there&lt;br /&gt;
* Syncing the KaraokeCloud no longer says it&#039;s TriceraSoft (!)&lt;br /&gt;
* Syncing is a bit faster&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b41&#039;&#039;&#039; Feb 26, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b41/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b41r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b41/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b41r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b41/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b41r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b41/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b41r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac: discs work again&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b40&#039;&#039;&#039; Feb 25, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b40/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b40r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b40/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b40r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b40/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b40r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b40/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b40r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** disc reader now works much more reliably on poorly mastered discs that have a fake &amp;quot;last track&amp;quot; and the totally wrong track length of the real last track.  kJams now gets it right where iTunes and WindowsMediaPlayer get it wrong(!)&lt;br /&gt;
** create more correct &amp;quot;fake&amp;quot; TOC (table of contents) for &amp;quot;disks&amp;quot; that are actually playlists or BIN disc images&lt;br /&gt;
** when quitting, during the &amp;quot;Waiting for cache purging to complete&amp;quot; phase, i now check to see if it&#039;s done every 1/16th second, instead of every 1/2 second, should feel more responsive&lt;br /&gt;
** the &amp;quot;Disc Picker&amp;quot; dialog (when you&#039;re getting meta data from an online database) now shows a normal popup menu, rather than a space-limited dropdown list&lt;br /&gt;
** KayJayPro password now actually works&lt;br /&gt;
** When you are playing back a transparent video at larger than 1:1 size (Which is probably always) there is now a bit of a shadow on things, for contrast.  used to be purple, was gone for a minute, back now and it is black.&lt;br /&gt;
** CDG Playback is imperceptibly faster&lt;br /&gt;
* fixed some more possible hangs on shutdown&lt;br /&gt;
* avoids doing some unnecessary stuff on startup&lt;br /&gt;
* fixed possible crash on startup related to setting menu of non-existant item in browser window&lt;br /&gt;
* i had turned off TOC validation (which checks TOC entries against the track entries) turned back on now for both platforms&lt;br /&gt;
* KayJayPro will work better with those discs that have a &amp;quot;fake track&amp;quot; on the end.  however, i think i have fixed kJams such that a &amp;quot;fake track&amp;quot; is never seen anyway (due to TOC validation)&lt;br /&gt;
* couple more logging of shutdown phases, during quit* no longer throwing exceptions as &amp;quot;flow control&amp;quot; in the &amp;quot;path modder&amp;quot; object (exceptions should be exceptional!)&lt;br /&gt;
* OMG this bug fix is just for me: in the debugger on Windows under Parallels desktop, no longer hang whenever i am paused and i use copy and paste!  [[Blog/Parallels|FOUR YEARS I LIVED WITH THIS]]!&lt;br /&gt;
* if you go to burn a song and there&#039;s a problem, the message dialog will show the song&#039;s name without funny characters&lt;br /&gt;
* fixed major instability (causing crashes) related to how i was handling updates to the viewer when the model changed&lt;br /&gt;
* I *might* have broken the sorting in the Sources list.  Or i might have just made it such that it no longer throws an exception for no reason&lt;br /&gt;
* Mac Producer: if you &amp;quot;down arrow&amp;quot; to the end of the song, and you were paused before, it used to start playing.  fixed.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b39&#039;&#039;&#039; Feb 19, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b39/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b39r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b39/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b39r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b39/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b39r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b39/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b39r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* when doing &amp;quot;add to library&amp;quot;, if a song has a dot in it, like &amp;quot;Mr. Bojangles&amp;quot;, kJams would accidentally remove everything after the (last) dot, so the song name would be come &amp;quot;Mr&amp;quot;.  fixed.&lt;br /&gt;
* fixed crash, usually right at startup, that would happen in response to any two network activities happening at the same time&lt;br /&gt;
* fixed potential crash creating a task for the activity window, one which was created with no initial task name&lt;br /&gt;
* when exporting HD *and* with &amp;quot;High Quality Upscale&amp;quot; turned on, it would work but would halt the user interface.  now some time is given to the UI&lt;br /&gt;
* sleeping thread que items are tickled every 1/8th second instead of every 1/4th, this should make them feel more responsive&lt;br /&gt;
* you can now set the pref &amp;quot;audio fade duration&amp;quot; to zero and have it stick on the next startup&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b38&#039;&#039;&#039; Feb 17, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b38/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b38r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b38/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b38r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b38/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b38r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b38/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b38r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: the auto-updater will work starting now.  ie: it&#039;s probably broken for you right now, so download this (or later) version, and then when the NEXT update happens it will &amp;quot;just work&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b37&#039;&#039;&#039; Feb 17, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b37/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b37r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b37/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b37r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b37/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b37r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b37/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b37r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: QT Export&lt;br /&gt;
** now allows transparency (QuickTime / Animation only)&lt;br /&gt;
** last frame is no longer white* When syncing KaraokeCloud (tethering), if it&#039;a all synced already it no longer says &amp;quot;All songs were already downloaded&amp;quot;&lt;br /&gt;
* Windows&lt;br /&gt;
** MediaStream files displaying small fonts no longer use &amp;quot;ClearType&amp;quot; (which ironically look muddy)&lt;br /&gt;
** got rid of purple halo around transparent video, but i need to put it back&lt;br /&gt;
* Exporting / Encoding task in the activity window no longer says &amp;quot;with QuickTime&amp;quot; cuz we know that already&lt;br /&gt;
* When syncing (Tether or purchases) no longer takes forever doing &amp;quot;preflight&amp;quot;&lt;br /&gt;
* when you do a search (that would produce no results) and while the search is going on, you switch to another playlist, the search used to loop infinitiely.  fixed.&lt;br /&gt;
* fixed crashes when you attempt to open producer and there&#039;s a problem loading the song&lt;br /&gt;
* you are now informed of said problem, rather than it being swept under the rug&lt;br /&gt;
* when you do a drag-and-drop reorder in the browser window (regular playlist OR &amp;quot;KJ Rotation&amp;quot;), the reorder gets posted to the event que, rather than being handled *during* the drag and drop handler.  this is less crashy.&lt;br /&gt;
* you can now set the *sample* export name template in the export prefs&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b36&#039;&#039;&#039; Feb 16, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLite.zip|Lite Mac|/downloads/Lite&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsPro.zip|Pro Mac|/downloads/Pro&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://dl.dropbox.com/u/195957/kJams/kJamsProWin.exe|Pro Win|/downloads/Pro_Win&amp;lt;/googa&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
not out yet but you can [[downloads/Rogues|get the Rogue]]&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b36/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b36r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b36/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b36r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b36/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b36r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b36/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b36r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* QuickTime Export&lt;br /&gt;
** significantly re-written&lt;br /&gt;
** a &amp;quot;snapshot&amp;quot; of all &amp;quot;export preferences&amp;quot; is taken at the moment the song is sent to the export queue.  This means you are free to change your preferences during the export and the changes will not affect any exports already queued up&lt;br /&gt;
** now honors &amp;quot;High Quality CDG Video Upscale&amp;quot; when exporting to an HD preset (Including AppleTV)&lt;br /&gt;
** things like high quality, padding, HD, MediaStream, transparency etc. no longer cancel each other out.  Previously, turning on some settings would cause others to turn off when it didn&#039;t make sense to do so.  The ones that make sense remain: eg: if you exporting to other than Animation trumps transparency.  exporting to HD trumps padding, exporting to NOT HD trumps high quality.&lt;br /&gt;
** errors reported during scripting come as notifications instead of dialogs&lt;br /&gt;
** when exporting thru scripting, you can specify a (single level of) subfolder that does not exist as the destination&lt;br /&gt;
** now writes an Alpha label on QuickTime files with Animation compresser, when it&#039;s transparent.  That way, all 2 of you who use After Effects or Premiere no longer have to set the alpha when importing.&lt;br /&gt;
* Windows&lt;br /&gt;
** if you crash or force quit while exporting quicktime, the background app will also quit (after 10 seconds)&lt;br /&gt;
** switching venues no longer leaves ghost playlists around&lt;br /&gt;
** playing MediaStream files was pretty hosed.  it works better now, including transparency. more to come.&lt;br /&gt;
** if you set your video to transparent, it looks sharper when zoomed in since we no longer &amp;quot;smooth&amp;quot; the edges of the graphics&lt;br /&gt;
** while in the &amp;quot;open file or folder&amp;quot; dialog, if a sub-dialog came up (like &amp;quot;new folder&amp;quot; or a warning that you selected a file not a folder), then you would get an assert fail.  fixed.&lt;br /&gt;
* Music Stores: General&lt;br /&gt;
** KaraokeCloud: you will get the &amp;quot;ready&amp;quot; signal after the login has completed, rather than BEFORE.&lt;br /&gt;
** the &amp;quot;Store Name&amp;quot; of purchased songs should be remembered now (not tested?)&lt;br /&gt;
** quitting right away after launch will no longer hang due to Tricera store being only partially birthed&lt;br /&gt;
** The TriceraSoft music store now includes song durations, so the feature of showing singers when they will sing now works (wtkJams rotation)&lt;br /&gt;
** there is a new menu item to reload the current venue, which you can use if you add an alias to a singer&lt;br /&gt;
* Music Stores: Re-syncing previously purchased songs&lt;br /&gt;
** &amp;quot;Sunc purchases&amp;quot; is now spelled correctly&lt;br /&gt;
** now shows dialog progress bar when necessary so you&#039;re not wondering why you can&#039;t click on stuff&lt;br /&gt;
** there is now a menu item for this in the right-click context menu for the store &amp;quot;Sync Previous Purchases…&amp;quot;&lt;br /&gt;
** Will now work if the *file* exists in your hard drive but the reference got deleted&lt;br /&gt;
** no longer takes forever sorting songs while the sync is happening (it&#039;s much faster)&lt;br /&gt;
** FIXED: duplicate entries and assert-fails&lt;br /&gt;
* FIXED: CDs that were &amp;quot;multiple session&amp;quot; discs would calculate the duration of the last track incorrectly in two different ways, causing errors when mounting or when ripping&lt;br /&gt;
* Tasks in the activity window: you&#039;ll see more, with better descriptions, and they won&#039;t accumulate and stay there forever, causing a hang on quit&lt;br /&gt;
* when scripting the volume, you no longer see a message in the video window about volume&lt;br /&gt;
* FIXED: crash on quit: when GraceNote had pending tasks&lt;br /&gt;
* fixed assert fail and/or crash when using freedb or the other two&lt;br /&gt;
* fixed crash in KayJayPro when it should just return an error&lt;br /&gt;
* fixed asserts and/or crashes when switching venues&lt;br /&gt;
* fixed a bug where at the very end of a Producer / MediaStream (eg: LRC) song, it would revert to low-rez or go blank&lt;br /&gt;
* the Rotation ShowScreen is NOT shown after you play a &amp;quot;Slide (ShowScreen Song)&amp;quot; even when the pref is on&lt;br /&gt;
* Saving playlists for reals this time is really on a background thread.  I said it before but i was wrong.  That way, the video window won&#039;t stutter when saving eg: the TriceraSoft playlist&lt;br /&gt;
* there was a major bug in kjams where it would lose track of procedure calls and simply drop them on the floor if more than one came in at once.  this had the symptom of the computer getting slower and slower over time, eating more memory over time, inability to quit etc.  fixed.&lt;br /&gt;
* fixed crash when clicking in menu bar and no playlist is selected&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b35&#039;&#039;&#039; January 19, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b35/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b35r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b35/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b35r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b35/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b35r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b35/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b35r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* KayJayPro&lt;br /&gt;
** if you didn&#039;t enter user name and password, it now sends you to the kjp web site (it should send you to prefs! will fix next time)&lt;br /&gt;
** if your un/pw is *wrong* it sends you to prefs&lt;br /&gt;
** prefs: manage button now goes to the right plac&lt;br /&gt;
* FIXED CRASH on startup on (Windows)&lt;br /&gt;
* Tethering KaraokeCloud Pro data now detects bad file (Show and sort by &amp;quot;comment&amp;quot;)&lt;br /&gt;
* fixed some indecipherable task names&lt;br /&gt;
* if on first run you have the &amp;quot;enter your email&amp;quot; dialog up, and you quit, you get into an infinite loop.  fixed.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b34&#039;&#039;&#039; January 18, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b34/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b34r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b34/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b34r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b34/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b34r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b34/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b34r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed crash on startup if you had music stores turned off&lt;br /&gt;
* These items now have Activity Window Tasks:&lt;br /&gt;
** check for updates&lt;br /&gt;
** lots of music store things&lt;br /&gt;
** almost all networking things&lt;br /&gt;
* the KaraokeCloud store inadvertently used the TriceraSoft preferences for when it needed to sync, causing one or the other to not work when you expected it to&lt;br /&gt;
* Sync que now names the music store it&#039;s operating on&lt;br /&gt;
* when syncing previous purchases, you get a Task, and will tell you if it already was done&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b33&#039;&#039;&#039; January 17, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b33/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b33r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b33/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b33r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b33/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b33r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b33/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b33r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixes KayJayPro so you can search on a track title and have it work&lt;br /&gt;
* when you listen to a sample in the TriceraSoft library, it now optionally warns you that you&#039;re going to an external web site&lt;br /&gt;
* at first startup, kJams will no longer attempt to load the same music stores twice&lt;br /&gt;
* the first time you try to buy or stream a song from KaraokeCloud, instead of just asking for your CC number (which doesn&#039;t sign you up), it will now walk you thru the whole signup process&lt;br /&gt;
* the &amp;quot;Main&amp;quot; thread is now named&lt;br /&gt;
* the &amp;quot;date of last check&amp;quot; now has SEPARATE prefs for &amp;quot;app (on startup)&amp;quot;, &amp;quot;music stores&amp;quot; and &amp;quot;running (app while running, if you leave it on for days at a time)&amp;quot;&lt;br /&gt;
* kJams now has the ability to run without eSellerate for those pesky computers on which eSellerate just up and crashes.  technically this means i could support MacOS 10.3 again, but that ain&#039;t gonna happen.&lt;br /&gt;
* if you need [[Flip4Mac]], the warning dialog will now have an &amp;quot;Explain…&amp;quot; button instead of a &amp;quot;Get It…&amp;quot; button, which makes more sense anyway&lt;br /&gt;
* if you have an OLD version of Flip4Mac, you&#039;re sent to the above link instead of the confusing link at telestream.net&lt;br /&gt;
* that one song in the TriceraSoft music store that has a hashtag in it&#039;s name?  you can now actually play the audio preview.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b32&#039;&#039;&#039; January 12, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b32/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b32r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b32/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b32r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b32/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b32r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b32/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b32r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* When you get metadata from a database, the disc name will refresh automatically&lt;br /&gt;
* burning a CD again allows you to burn audio only files&lt;br /&gt;
* PowerPC Mac users: the time has come to upgrade.  sorry, blame apple.&lt;br /&gt;
* if you mount disc images on startup, it no longer aborts all mounting if one fails&lt;br /&gt;
* switching venues no longer crashes&lt;br /&gt;
* the new [[KayJayPro]] is now built into kJams, however there is currently no way to subscribe.  the ball is in their court.&lt;br /&gt;
* Updated KayJayPro to point to final domain&lt;br /&gt;
* you can now horizontally shrink the &amp;quot;Store Name&amp;quot; sort column so only the icon is showing&lt;br /&gt;
* Getting meta data from freedb and friends is less likely to crash (there is one known outstanding crash.  the moment i get a valid crash report on this, i&#039;ll fix it!)&lt;br /&gt;
* When you &amp;quot;Enter Serial Number&amp;quot;, if you don&#039;t enter the whole thing, kJams will now say &amp;quot;hey!  you didn&#039;t enter the whole thing&amp;quot; rather than tell you [You&#039;re entering a serial number for &amp;quot;&amp;quot;, when you&#039;re trying to activate &amp;quot;kJams&amp;quot;], which was not helpful.&lt;br /&gt;
* FIXED SERVER CRASHER!  If a client was operating (eg: doing a search) at the moment you turn off the server, you could crash (eg: when switching venues or quitting)&lt;br /&gt;
* when you &amp;quot;trash original files&amp;quot; on a song, kJams now correctly deletes it&#039;s cached files&lt;br /&gt;
* Producer:&lt;br /&gt;
** you can, if you know how, create &amp;quot;ShowScreen Songs&amp;quot; by hand, tho they don&#039;t all work (eg: rotation)&lt;br /&gt;
** when you turn on/off Dither, the current blob CDG is recalculated&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b31&#039;&#039;&#039; Jan 3, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b31/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b31r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b31/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b31r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b31/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b31r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b31/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b31r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* changing meta data works now even when the only change is adding or removing diacritical marks&lt;br /&gt;
* fixed lots of bugs with GraceNote database (eg: it now actually works more than once)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b30&#039;&#039;&#039; Jan 2, 2014==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b30/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b30r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b30/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b30r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b30/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b30r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b30/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b30r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Intel-Only FEATURE: OMG [[GraceNote]]!  Less Typing!!  (Sorry, PowerPC users)&lt;br /&gt;
* more work on the new &amp;quot;KayJayPro&amp;quot; (like GraceNote except JUST for Karaoke CD+G discs)&lt;br /&gt;
* copy-paste of playlist sort-column data is fixed ([[Edit#Copy_and_Paste|When the Source list is focused]])&lt;br /&gt;
* &amp;quot;reveal in finder / explorer&amp;quot; again works on the Rotation playlists&lt;br /&gt;
* support for CAVS meta data where the text file is the name of the folder&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b29&#039;&#039;&#039; December 29, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b29/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b29r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b29/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b29r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b29/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b29r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b29/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b29r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* well crap i broke the CD disc stuff (table of contents calculation), okay fixed.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b28&#039;&#039;&#039; December 29, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b28/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b28r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b28/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b28r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b28/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b28r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b28/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b28r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* When attempting to burn a disc, you will now get an actual error message if:&lt;br /&gt;
** a song is missing&lt;br /&gt;
** a song is from a music store&lt;br /&gt;
** a song is not an Audio+G file&lt;br /&gt;
* KaraokeCloud&lt;br /&gt;
** if you&#039;re not logged in, kJams won&#039;t ask for your password anyway&lt;br /&gt;
** sometimes takes some time to log in.  You will now be notified when login is successful, you&#039;ll see &amp;quot;KC Ready!&amp;quot; in the LCD panel (top of browser)&lt;br /&gt;
** If you attempt to use the Tethering tier on kJams Tryout, you will be notified of WHY that won&#039;t work (in addition to being sent to the web site)&lt;br /&gt;
* Windows: &lt;br /&gt;
** if you attempt to play a WMV or AVI file on windows, you&#039;re notified that it&#039;s not supported&lt;br /&gt;
** burn disc dialog is ready for localization.  spanish has temp strings already!&lt;br /&gt;
* Add to Library&lt;br /&gt;
** Your choices now are &amp;quot;Reference&amp;quot; and &amp;quot;Copy&amp;quot;.  &amp;quot;Move&amp;quot; is no longer an option&lt;br /&gt;
** If you pick &amp;quot;Copy&amp;quot;, kjams will now ALWAYS copy the file, even if it is on the same volume.  it will NOT move it.&lt;br /&gt;
** it now will copy ALL components (it was previously sometimes MISSING some song components, so you&#039;d wonder why your song doesn&#039;t play!)&lt;br /&gt;
* Mac:&lt;br /&gt;
** When unpacking WMA or KMA files, the progress bars work again&lt;br /&gt;
** now setting thread name on cooperative threads&lt;br /&gt;
** even if you have a bunch of nested dialogs showing, if you request to quit, all dialogs will be canceled and kjams will quit.  (eg: right click the dock icon and quit, or restart, or shut down)&lt;br /&gt;
* you can now set the text pref: &amp;quot;Percent complete after which song is considered sung (0 to 100)&amp;quot;&lt;br /&gt;
* when reading the Table of Contents (TOC) for an AudioCD, if there are any song durations that are Zero, you are notified, rather than having confusing behavior later&lt;br /&gt;
* if there is ANY error mounting a CD, you now GET the error rather than it being ignored&lt;br /&gt;
* FIXED: Hiccups and stutters in songs, when saving Large playlists (eg: TriceraSoft).  Saving was SUPPOSED to be on a back thread but was accidentally on the front thread.  &lt;br /&gt;
* email addresses are now allowed to have only 2 chars in the domain name&lt;br /&gt;
* you can now copy/paste to/from excel on the mac (maybe on windows too?  try it?)&lt;br /&gt;
* no longer crash when you stop playing a song who&#039;s video is already stopped&lt;br /&gt;
* enabled [[Searching#Exact_Searches|exact searches]]&lt;br /&gt;
* fixed a bug where a song would get stuck in a loop playing the last 1 second&lt;br /&gt;
* did some work getting the new &amp;quot;[[KJ_Pro|Kay Jay Pro]]&amp;quot; working&lt;br /&gt;
* blind-fix attempt when a mutex deletes but is still in use (hope to fix a crash)&lt;br /&gt;
* restored the Romanian translation which had been messed up&lt;br /&gt;
* my CNetHTTP class can now send &amp;quot;application/x-www-form-urlencoded&amp;quot; data (not that you care, much)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b27&#039;&#039;&#039; Nov 7, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b27/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b27r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b27/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b27r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b27/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b27r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b27/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b27r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* when you delete a singer from a venue that happens to be an alias (shortcut) to that singer from another venue, the alias is deleted, not the original singer&lt;br /&gt;
* Fixed bug of the Karaoke Cloud dialog getting stuck on &amp;quot;Please wait a few moments and this screen will refresh&amp;quot;, and then it would never refresh&lt;br /&gt;
* if you crazily set your KaraokeCloud preference: &amp;quot;Maximum Simultaneous Downloads&amp;quot; to less than 1, you crazy person, i will ignore you and set it to 1&lt;br /&gt;
* when you sort a playlist in DESCENDING (reverse) order, then go to another playlist that happens to be sorted by that same column but in ASCENDING order, then back to the first, it now remembers to go back to DESCENDING&lt;br /&gt;
* you can now choose to fade your audio in a linear way, rather than by the default (logarithmic) way, with the text pref &amp;quot;Use Linear audio fade (vs: log)&amp;quot; set to TRUE&lt;br /&gt;
* you can now specify the duration of the initial delay of the built-in messenger messages, with text pref &amp;quot;Messenger initial delay (seconds)&amp;quot;.  You could already set the duration of custom messages with the pref &amp;quot;Long messenger duration&amp;quot; (i know, dumb name)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b26&#039;&#039;&#039; Oct 26, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b26/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b26r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b26/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b26r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b26/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b26r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b26/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b26r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* KaraokeCloud songs labeled as being from &amp;quot;M&amp;quot; are now properly labeled as being from &amp;quot;Music Maestro&amp;quot;&lt;br /&gt;
* if you hold down the option/alt key when &amp;quot;pushing meta data&amp;quot;, any zip files will have their content&#039;s file names be encoded in UTF8 instead of WindowsLatin1&lt;br /&gt;
* fixed rare crashing bug: when last person in rotation&#039;s song starts, kJams will pre-cache the next song, which belongs to the first person.  If that next song (of the first person) was an un-purchased music-store song (not a streaming song), then kJams would crash.  fixed.&lt;br /&gt;
* fixed the bug of if you start a song and there&#039;s an error starting it that is then fixed (eg: could not find it and you hit cancel, or it asked you to purchase and you hit cancel), the next time you go to start the song it would never start at all.  fixed.&lt;br /&gt;
* completed feature: finally added text pref &amp;quot;Messenger Rotation size&amp;quot; controls how many singers / songs are listed in the Messenger&lt;br /&gt;
* Mavericks: Singer &amp;quot;face&amp;quot; icons would draw insanely slow and cause general slowdown.  fixed.&lt;br /&gt;
* accidentally left a &amp;quot;separator&amp;quot; in the Help menu, fixed&lt;br /&gt;
* Producer: turning on / off &amp;quot;Don&#039;t encode CDG&amp;quot; takes effect immediately, even if Producer is currently open&lt;br /&gt;
* Producer: will warn you if you have &amp;quot;Don&#039;t encode CDG&amp;quot; turned on and you try to do some CDG editing&lt;br /&gt;
* tweaked a draw browser text edit routine in the hopes of catching a crasher&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b25&#039;&#039;&#039; Oct 22, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b25/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b25r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b25/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b25r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b25/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b25r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b25/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b25r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Completed Feature&#039;&#039;&#039;: In Music &#039;&#039;&#039;Store&#039;&#039;&#039; preferences, in the &amp;lt;&amp;lt;&#039;&#039;&#039;Include Store songs in “Library”:&#039;&#039;&#039;&amp;gt;&amp;gt; popup, you can now choose to have &amp;quot;Only Subscribed Songs&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Completed Feature&#039;&#039;&#039;: the &amp;quot;Duet&amp;quot; checkbox and &amp;quot;Duet Comment&amp;quot; text can now be edited in the Rotation playlists.  The data lives with the singer only with respect to that song (ie: a different singer with the same song will not get that data)&lt;br /&gt;
* Fixed crash in Help and Advanced menus&lt;br /&gt;
* Fixed Bug: in KaraokeCloud, your credit card type was always set incorrectly!  Sorry about that!  To fix: go to prefs-&amp;gt;stores-&amp;gt;edit CC settings, then click OK.  The data will be re-sent to KC.&lt;br /&gt;
* Fixed Mac Problem: My code-signing was busted and i didn&#039;t know it.  fixed.&lt;br /&gt;
* Added ability to use new Rotation ShowScreen: &amp;quot;Rotation (only singer names)&amp;quot; in prefs-&amp;gt;advanced&lt;br /&gt;
* When &amp;quot;deactivating&amp;quot; your serial number, there is now a (indeterminate) progress dialog&lt;br /&gt;
* with Transparent Video, there used to be a thin, one-pixel line around the 4:3 aspect ratio zone, this has been fixed&lt;br /&gt;
* in the DataBrowser, non-existant data that has a default value will now draw with that default value, rather than with &amp;quot;-&amp;quot; (eg: tempo, when not set, now always shows as &amp;quot;1.0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b24&#039;&#039;&#039; Oct 15, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b24/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b24r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b24/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b24r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b24/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b24r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b24/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b24r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* when using a TriceraSoft Gift Pack:&lt;br /&gt;
** if your name / email is missing, you get a warning, and the warning tells you it&#039;s about the gift pack, so you don&#039;t think it&#039;s about a credit card&lt;br /&gt;
** the gift pack credits are updated so you can see how many you have in the prefs dialog&lt;br /&gt;
** it won&#039;t let you try if you have 0 credits&lt;br /&gt;
* if you have auto-updates set to something that is NOT &amp;quot;always&amp;quot;, and your music stores have somehow disappeared, it&#039;s still going to check for them so you are not wondering where are your music stores&lt;br /&gt;
* you are now allowed to create a singer with no password&lt;br /&gt;
* Launch files work again (Whupps!)&lt;br /&gt;
* LRC files now support the &amp;quot;unicode&amp;quot; tag, and will ignore &amp;quot;utf8&amp;quot; if it&#039;s known to be &amp;quot;utf16&amp;quot;&lt;br /&gt;
* no longer get an alert about &amp;quot;Retain Count: 2&amp;quot; on Mavericks&lt;br /&gt;
* brought back the &amp;quot;Ignore CDG Ripping Errors&amp;quot; pref.  now, you don&#039;t get black video for everything, just for sectors that can&#039;t be read&lt;br /&gt;
* fixed ability to play KMA files that are internally zipped&lt;br /&gt;
* if you play a song in a playlist that is very very big and sorted by &amp;quot;Name&amp;quot;, there used to be a short delay (maybe a few seconds).  fixed.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b23&#039;&#039;&#039; Oct 3, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b23/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b23r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b23/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b23r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b23/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b23r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b23/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b23r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* turned off logging for &amp;quot;Getting meta dictionary&amp;quot;, i think we fixed that&lt;br /&gt;
* Pro: when no song is playing (and i don&#039;t mean loaded but paused) the default playlist for the ShowScreen Rotation will be, the &amp;quot;Rotation&amp;quot; playlist, and not the most-recently-played playlist.  It was too confusing for folks otherwise.&lt;br /&gt;
* [[Launch Files]]&lt;br /&gt;
** will now only launch after the song is loaded for playing.  It will NOT launch if the song is just being cached, or if the song for some reason has an error when trying to load.&lt;br /&gt;
** now has a secret pref &amp;quot;Open launch file only when un-paused&amp;quot;, defaulting to &amp;quot;true&amp;quot;, so if you have &amp;quot;pause between tracks&amp;quot; turned on, it will only run the launch file when you un-pause the song.  that way it won&#039;t open if you never un-pause the next song.&lt;br /&gt;
* fixed Karaoke Cloud assert warning when you&#039;re in tryout and not logged in&lt;br /&gt;
* fixed CRASH if kJams says &amp;quot;can&#039;t find this song do you want to find it?&amp;quot; and you hit Cancel&lt;br /&gt;
* LRC files now support unicode (&amp;quot;utf-8&amp;quot;)&lt;br /&gt;
* the &amp;quot;repeat&amp;quot; button appeared to be disabled when showing a Rotation playlist, however behind the scenes it WAS still doing it&#039;s thing.  Fixed such that Rotation playlists act as if it is always disabled, as it should.&lt;br /&gt;
* when reading in the database, all singers marked with &amp;quot;sort me to the top&amp;quot; are un-marked.  This should fix any weird sorting problems in the Sources list for Singers&lt;br /&gt;
* kJams Lite no longer includes Pro resources for the Server&lt;br /&gt;
* Lite and Pro no longer include 2 resources for Python&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b22&#039;&#039;&#039; Sept 10, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b22/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b22r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b22/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b22r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b22/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b22r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b22/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b22r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: fixed rare crash on shutdown&lt;br /&gt;
* minimum cache size is now 5&lt;br /&gt;
* tweaked some logging to have correct &amp;quot;carriage returns&amp;quot;&lt;br /&gt;
* changed the way kjams creates temp folders *again* such that they no longer have a minus sign on them&lt;br /&gt;
* fixed another potential crash on when you clear a large cache and immediately close the prefs window&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b21&#039;&#039;&#039; Sept 7, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b21/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b21r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b21/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b21r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b21/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b21r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b21/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b21r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* older Mac OSs (including 10.6) were reporting the wrong number of cores.  this would then incorrectly set the max number of QT exports and auto-re-encode tasks to infinity, leading to serious bogging down, asserts about file not found, and crashes&lt;br /&gt;
* pro version: custom set keyboard shortcuts work properly for Venu, Video, and Python sub-menus&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b20&#039;&#039;&#039; Sept 2, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b20/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b20r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b20/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b20r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b20/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b20r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b20/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b20r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** Growl notifications are now unicode and have a nice, large kJams icon&lt;br /&gt;
* threads are named now even in release builds, cuz why not?  then i can see thread names in the crash reports, duh&lt;br /&gt;
* when you select a NEO+G or a SuperCDG, then go to the file menu, it no longer enables &amp;quot;Rip to BIN/CUE&amp;quot;, cuz first of all that&#039;s not even possible, second, if you picked that, it would crash.&lt;br /&gt;
* revealing the &amp;quot;logs&amp;quot; will now reveal the current log file directly, rather than just the containing folder&lt;br /&gt;
* fixed eSellerate AGAIN grrrrr&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b19&#039;&#039;&#039; Aug 29, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b19/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b19r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b19/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b19r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b19/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b19r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b19/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b19r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** took a real stab at fixing that crasher&lt;br /&gt;
** removed the logging that i used to find the crash, should be back to normal speed now.  let me know if the video window stutters when switching playlists&lt;br /&gt;
* kJams 2.0&lt;br /&gt;
** when upgrading to or updating kJams 2, you now get the correct binary (was getting Pro!)&lt;br /&gt;
** activation resetting is finally working again.  you should be able to activate on another computer&lt;br /&gt;
* accidentally enabled &amp;quot;manual activation&amp;quot;, which will be gone in the next update&lt;br /&gt;
* when quitting, back to normal speed (no longer attempting to remove every song from the song que)&lt;br /&gt;
* if you have a network error during update, you now get told, rather than something about &amp;quot;couldn&#039;t find plugin&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b17&#039;&#039;&#039; Aug 28, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b17/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b17r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b17/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b17r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b17/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b17r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b17/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b17r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** fixed crash on startup&lt;br /&gt;
** added lots more logging to help find the other crash that i was TRYING to fix&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b16&#039;&#039;&#039; Aug 28, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b16/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b16r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b16/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b16r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b16/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b16r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b16/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b16r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** got rid of the locale logging on startup&lt;br /&gt;
** temp folders created using the current time (bunch of numbers) *should* no longer collide, as i&#039;m putting the least significant bits at the front instead of the back&lt;br /&gt;
** added some code jiggle around that bug that&#039;s crashing windows very consistently, i&#039;m coming for YOU!&lt;br /&gt;
* &amp;quot;Browser Selected Source&amp;quot; messages will now show the one you clicked on, not the one you&#039;re clicking AWAY from&lt;br /&gt;
* if you get a &amp;quot;bad recursion&amp;quot; you now crash, instead of trying to keep going, so i can fix the bug&lt;br /&gt;
* ReportFolderErr() shows the path more correctly&lt;br /&gt;
* no longer logging &amp;quot;Local Meta Retain&amp;quot; etc&lt;br /&gt;
* fixed a crash in CFreeDB::ParseResult() when there was no result&lt;br /&gt;
* fixed a crash when asking to see if a playlist can repeat, but there is no playlist&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b15&#039;&#039;&#039; Aug 27, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b15/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b15r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b15/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b15r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b15/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b15r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b15/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b15r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* [[kJams 2]] is ready for you!  YEAH!&lt;br /&gt;
* fixed crash when you go to play a song, it&#039;s not there, you delete the song, then go to play another song&lt;br /&gt;
* in [[Switchable Songs]] menu, song that has open parenthesis (&amp;quot;(&amp;quot;) as first character in name will no longer be disabled&lt;br /&gt;
* fixed ability to upgrade&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b13&#039;&#039;&#039; Aug 22, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b13/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b13r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b13/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b13r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b13/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b13r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b13/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b13r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** Lite: hides the &amp;quot;new singer&amp;quot; and &amp;quot;artwork&amp;quot; buttons, that never should have been showing&lt;br /&gt;
** fixed crasher related to updating meta&lt;br /&gt;
* &#039;&#039;&#039;OMG fixed ability to purchase Pro (!!)&#039;&#039;&#039;&lt;br /&gt;
* TriceraSoft: when re-syncing, if there&#039;s a problem you can see the error message&lt;br /&gt;
* new general pref &amp;quot;reset warnings&amp;quot;, turns back on all the &amp;quot;don&#039;t warn me again&amp;quot; things&lt;br /&gt;
* when you Target a playlist for the first time, you get a message explaining what targeting is&lt;br /&gt;
* creating a new singer no longer auto-turns on &amp;quot;Target Mode&amp;quot;&lt;br /&gt;
* fixed crash if you use key shortcuts for cut/copy/paste while in a modal dialog that should not allow it&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b12&#039;&#039;&#039; Aug 18, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b12/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b12r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b12/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b12r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b12/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b12r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b12/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b12r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Server:&lt;br /&gt;
** if you ask for playlists when a singer is not logged in, you get the list of Sources&lt;br /&gt;
** if you ask for SONGS and supply the &amp;quot;Server Search&amp;quot; playlist id, you&#039;ll get all the songs.  yep, all of them&lt;br /&gt;
** allows client to log a singer in by name now (no longer must be by ID)&lt;br /&gt;
** when the server creates a singer, kjams does NOT scroll to reveal it&lt;br /&gt;
* Windows&lt;br /&gt;
** Karaoke Cloud login dialog no longer says &amp;quot;TriceraSoft Gift Pack&amp;quot;&lt;br /&gt;
** lite: if you somehow click &amp;quot;new singer&amp;quot; you no longer get an assert&lt;br /&gt;
* Producer (Mac only)&lt;br /&gt;
** Fixed ability to run Producer&lt;br /&gt;
** in the Tryout version, dragging a blob no longer removes the red X&#039;s&lt;br /&gt;
* Tryout:&lt;br /&gt;
** wow, the  version always limited you to 2 songs per playlist, i MEANT to have it be three.  wow.&lt;br /&gt;
** used to be you could get a &amp;quot;the tryout limits you to 3 songs per playlist, do you want to enter a sn?&amp;quot; dialog, then you would enter the SN, then you&#039;d get the same dialog AGAIN!  fixed.&lt;br /&gt;
** when you successfully activate, it now tells you which thing you just activated&lt;br /&gt;
* dialog / alert info is logged in a consistent way&lt;br /&gt;
* CFNumbers now distinguish between doubles and ints&lt;br /&gt;
* fixed the ability to set key shortcuts on the Video menu and on the Webcam underlay menu&lt;br /&gt;
* eSellerate errors are reported more consistently&lt;br /&gt;
* fixed a bug where: if the same song comes in the playlist twice in a row, the song would fail to play the second time, and get stuck in &amp;quot;can&#039;t play&amp;quot; mode.  there were several other permutations of this problem, i think they&#039;re all fixed&lt;br /&gt;
* FEATURE: kjams now remembers your pitch corrections in the music stores!  (if you turn off music stores, you lose that data however)&lt;br /&gt;
* re-worded the &amp;quot;Delete Singer&amp;quot; to &amp;quot;Remove Singer&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b11&#039;&#039;&#039; Aug 4, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b11/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b11r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b11/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b11r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b11/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b11r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b11/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b11r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows: fixed broken dll linkage problem (python27.dll)&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b10&#039;&#039;&#039; Aug 3, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b10/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b10r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b10/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b10r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b10/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b10r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b10/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b10r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Win: fixed ability to switch Venues&lt;br /&gt;
* Mac: The Burning &amp;quot;Plugin&amp;quot; (sold separately) is now installed as part of the application.  It is still an in-app purchase, but you no longer need to run the plugin installer to see it in the preferences (Windows was always like that)&lt;br /&gt;
* fixed long-standing memory leak: &amp;quot;unceremoniously killed preemptive threads&amp;quot; and also &amp;quot;unkillable timer threads&amp;quot; never got their d&#039;tor called (this was not serious as the only time that happened previously was on shutdown)&lt;br /&gt;
* timer thread name strings can now be a member variable of the timer (used to be required to be static)&lt;br /&gt;
* Support for &#039;Droid version of wtkJams&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b9&#039;&#039;&#039; July 26, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b9/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b9r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b9/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b9r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b9/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b9r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b9/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b9r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed crash when switching venues when you have a targeted singer&lt;br /&gt;
* after switching venues, Singer sorting still works without having to twirl the venue up and down&lt;br /&gt;
* you can no longer delete Music Store songs that are listed in the library.  If you try, you get told you can&#039;t do that, and instead just turn it off in the prefs&lt;br /&gt;
* New General pref: you can tell kJams just how often to check for updates, instead of just &amp;quot;always&amp;quot; vs. &amp;quot;never&amp;quot;&lt;br /&gt;
* fixed bug where the background color of a video had stopped being applied to the borders of the Video window&lt;br /&gt;
* Mavericks: fixed window positioning to be a bit less flickery&lt;br /&gt;
* fixed crash if you delete a song you had just played&lt;br /&gt;
* Windows: you finally get the &amp;quot;rip done&amp;quot; sound (import pref had never worked: play sound when finished ripping)&lt;br /&gt;
* fixed yet another crash on startup when checking for updates&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b8&#039;&#039;&#039; July 22, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b8/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b8r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b8/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b8r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b8/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b8r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b8/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b8r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed potential crash when searching&lt;br /&gt;
* fixed that ASSERT(str.GetIndChar() == &#039;r&#039;)&lt;br /&gt;
* Win: cleaned up some code regarding selecting items in the sources list, hunting a bug there&lt;br /&gt;
* my GetSystemVers() routine now uses symbolic values in stead of actual values (aren&#039;t you siked?)&lt;br /&gt;
* if a song is paused, you can un-pause it by double clicking on it&lt;br /&gt;
* fixed a HANG!  if you have &amp;quot;pause between tracks&amp;quot; on, and you are paused at the beginning of a song in the rotation, and you go to the &amp;quot;Rotation&amp;quot; playlist (not the &amp;quot;KJ Rotation&amp;quot;) and you un-pause by double clicking the song&lt;br /&gt;
* Added &amp;quot;Sort Name&amp;quot;, &amp;quot;Sort Artist&amp;quot;, and &amp;quot;Sort Album&amp;quot; meta-data columns&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b7&#039;&#039;&#039; July 18, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b7/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b7r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b7/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b7r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b7/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b7r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b7/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b7r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** CoreFoundation again can actually log to the kJams log file (was working before, but busted a few years ago)&lt;br /&gt;
** Updated to [http://code.google.com/p/crashrpt/ latest CrashRpt]&lt;br /&gt;
** can now recover if a localized CrashRpt believes the strings file is bad: we just revert to english (used to just fail to launch)&lt;br /&gt;
* Mavericks:&lt;br /&gt;
** full screen mode mostly works now.  Remember: To get the video above the menu bar, in General Prefs turn on &amp;quot;Video Window floats above all system windows&amp;quot;.  But note that if you get an alert or assert or any dialog that comes up, you won&#039;t see it because it&#039;s under the video window!&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b6&#039;&#039;&#039; July 14, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b6/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b6r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b6/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b6r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b6/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b6r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b6/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b6r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* not actually used yet: for later I added a &amp;quot;Full Screen&amp;quot; internal API for full screen apps, this will be used in the future for when kJams has a &amp;quot;Full Screen&amp;quot; mode&lt;br /&gt;
* Singer selection in the Sources list has always been a bit busted.  When you select a Singer (which is a playlist of 3 playlists), it actually shows the &amp;quot;Tonight&amp;quot; playlist (a playlist of &amp;quot;playlist items&amp;quot;, where each of those is a song) in the Tracks list.  This is a &amp;quot;what you see is what you expect&amp;quot;, rather than WYSIWYG kind of thing.  And it was a bit wonky under the hood, sometimes i&#039;d treat a singer AS the tonight list and vice versa, leaving the selection state confused at times.  This has all been fixed now.  it fixes the ability to reliably select a singer programatically, which is necessary to get right for when you create a new singer, which leads to:&lt;br /&gt;
* When you create a new singer, it gets created at the TOP of the list, and it is properly scrolled to so you can see it, then when you name it and press enter, it sorts into place, still selected, and it is again properly scrolled to&lt;br /&gt;
* a targeted playlist (or singer) will now always sort to the top, so you can always see it&lt;br /&gt;
* When QT Exporting a Producer file (LRC, KTP etc), it will now honor the &amp;quot;Use 16 x 9 Aspect Ratio&amp;quot;: if it&#039;s on you get HD like you always have, but if it&#039;s off, you get 4:3 at 300 x 216 to match other CDG exports&lt;br /&gt;
* fixed a bug where you export a producer file and it would come out black&lt;br /&gt;
* FEATURE: in [[Searching#Targeted_Searches|targeted searching]], you can now use the shortcut &amp;quot;s:&amp;quot; to indicate &amp;quot;song name&amp;quot;, and &amp;quot;a:&amp;quot; to indicate &amp;quot;artist name&amp;quot;&lt;br /&gt;
* fixed bug: in the Rotation, when the last person&#039;s song ended, it would not leave the rotation, nor be marked as sung, nor be added to the singer history.  all fixed&lt;br /&gt;
* fixed a bit of getting the Video Window to correctly go full screen on Mavericks.  Wow they so busted that :(  To get it above the menu bar, in General Prefs turn on &amp;quot;Video Window floats above all system windows&amp;quot;.  But note that if you get an alert or assert or any dialog that comes up, you won&#039;t see it because it&#039;s under the video window!&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b5&#039;&#039;&#039; July 5, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b5/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b5r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b5/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b5r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b5/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b5r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b5/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b5r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows&lt;br /&gt;
** When quitting, the &amp;quot;progress bar&amp;quot; no longer gets stuck at zero (it now correctly goes back to &amp;quot;indeterminate&amp;quot; barber-pole)&lt;br /&gt;
** Quitting is very slightly faster&lt;br /&gt;
** When quitting: the browser window really REALLY no longer re-appears for a second&lt;br /&gt;
** on startup, if your Sources list has a scroll bar, it&#039;s now scrolled to the top, not to the Singers list or Music Store list&lt;br /&gt;
** creating singer no longer crashes&lt;br /&gt;
** deleting singer no longer leaves the browser window &amp;quot;invisible to clicks&amp;quot;&lt;br /&gt;
** when you rename a playlist (or singer) the browser window no longer draws a large blank area on the left&lt;br /&gt;
** the Purple Focus Ring now draws with the bottom and right edges correct&lt;br /&gt;
* turned off CPW_TaskRec loggging since it&#039;s fixed&lt;br /&gt;
* turned off Sources list sort comparison results logging&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b4&#039;&#039;&#039; July 4, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b4/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b4r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b4/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b4r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b4/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b4r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b4/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b4r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed the task manager moar korrektly&lt;br /&gt;
* Windows: made some tweaks to hopefully fix the crashing&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b3&#039;&#039;&#039; July 3, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b3/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b3r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b3/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b3r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b3/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b3r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b3/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b3r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Windows:&lt;br /&gt;
** fixed crash when making a new singer&lt;br /&gt;
** during quit, the browser window won&#039;t show up again for a second after it has been closed&lt;br /&gt;
* making a new singer will no longer sort the new singer to the top of the list, but it should now scroll into view so you can easily see it.  i *may* revisit this cuz i think people liked that they sorted to the stop&lt;br /&gt;
* fixed ALL crashes related to the task (activity window) manager (!)&lt;br /&gt;
* turned on logging for the task manager, since there seems to be a bug&lt;br /&gt;
* fixed a producer bug that would produce completely eff&#039;d up timelines from the source file (theoretically could happen to any TunePrompter, UltraStar, SunFly, KaraokeBuilder, or LRC) only when the lyrics are so tight that they&#039;d push the start time of the page back by a tiny bit in order to fit.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b2&#039;&#039;&#039; June 27, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b2/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b2r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b2/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b2r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b2/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b2r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b2/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b2r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* fixed crash when songs change&lt;br /&gt;
* added another [[Scripting]] command&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0.1b1&#039;&#039;&#039; June 26, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b1/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_101_b1r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b1/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_101_b1r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b1/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_101_b1r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0.1/b1/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_101_b1r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac&lt;br /&gt;
** fixed ability to resolve symbolic links&lt;br /&gt;
** now has kScriptCommandStr_GetNextSongCachePath for scripting&lt;br /&gt;
* the &amp;quot;Messenger&amp;quot; layer is now above the &amp;quot;ShowScreens&amp;quot; layer, where it was always meant to be&lt;br /&gt;
* fixed a bug where you&#039;d get asserts about &amp;quot;foundB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0&#039;&#039;&#039; June 22, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/release0/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_release0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/release0/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_release0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/release0/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_release0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/release0/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_release0r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac&lt;br /&gt;
** searching and sometimes sorting would cause the scroll bar to go into outer space.  the result is that it SEEMED like searching always produced zero results (actually, just the scroll bar was off the bottom, and scrolling up would fix it)&lt;br /&gt;
** you can now use the scripting command kScriptCommandStr_GetCurSongCachePath&lt;br /&gt;
* Windows&lt;br /&gt;
** quits gracefully without crashing&lt;br /&gt;
* certain KMA files could cause kJams to crash.  fixed.  note they still won&#039;t play cuz they&#039;re bad files.&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;1.0f0&#039;&#039;&#039; June 20, 2013==&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/f0/r0/kJamsLite.zip|Lite Mac|/downloads/Lite_Mac_f0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/f0/r0/kJamsPro.zip|Pro Mac|/downloads/Pro_Mac_f0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/f0/r0/kJamsLiteWin.exe|Lite Win|/downloads/Lite_Win_f0r0&amp;lt;/googa&amp;gt;,&lt;br /&gt;
&amp;lt;googa&amp;gt;http://www.kjams.com/downloads/old/1.0/f0/r0/kJamsProWin.exe|Pro Win|/downloads/Pro_Win_f0r0&amp;lt;/googa&amp;gt;&lt;br /&gt;
* Mac&lt;br /&gt;
** if kJams can&#039;t load the &amp;quot;progress bar&amp;quot; resources, it tells you so and quits, rather than crash&lt;br /&gt;
** on 10.8, Apple introduced a bug where if you make an alias to a file/folder that is on a disk image, then when resolving that alias it would give you the disk image file instead of the alias target.  This is fixed by using CFURLBookmark APIs.  Important because some people use disk images (ie: me) for their KaraokeCloud data, and just make an alias to it in the kJams folder&lt;br /&gt;
* Windows&lt;br /&gt;
** deleting singers is faster&lt;br /&gt;
** quitting is faster&lt;br /&gt;
** some operations could cause video stutter, these have been fixed!  (let me know if you still see it)&lt;br /&gt;
* fixed a data-loss bug where if you duplicate &amp;quot;song&amp;quot; and it becomes &amp;quot;song *001&amp;quot; (same name on disk), if you then went back to &amp;quot;song&amp;quot; and duplicated it again, you&#039;d end up with ANOTHER &amp;quot;song *001&amp;quot;, which would overwrite the previous one.  Now, the new files on disk use a separate &amp;quot;unique&amp;quot; number scheme, so the first &amp;quot;song *001&amp;quot; is &amp;quot;song 1&amp;quot; on disk, and the second &amp;quot;song *001&amp;quot; is &amp;quot;song 2&amp;quot; on disk.  now, the &amp;quot;duplicate name&amp;quot; is merely cosmetic and doesn&#039;t overwrite files on disk&lt;br /&gt;
* you can now turn on Looping for the Messenger Rotation.  There is a checkmark next to &amp;quot;Messenger Rotation&amp;quot; when it is looping.&lt;br /&gt;
* when you enter a coupon before the purchase process begins, kjams would ignore it.  fixed.&lt;br /&gt;
* hey you, the guy on Windows who refuses to use a real email address?  i&#039;m onto you.&lt;br /&gt;
* Producer: fixed curly quotes around error message after &amp;quot;There was an error loading the song for editing&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Previous Version==&lt;br /&gt;
[[History/1.0beta|go here]]&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Meta_Data_Files&amp;diff=10482</id>
		<title>Meta Data Files</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Meta_Data_Files&amp;diff=10482"/>
		<updated>2015-03-21T18:31:18Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;kJams creates &amp;quot;.xml&amp;quot; files next to the media files in order to store the meta data related to that file.  (Inside the xml file, the data have the same tags as used in the [[Xattr]] format.)  Meta data includes song name, artist, album, track, but it also includes kJams specific data like whether there are backing vocals, beats per minute, comment, composer, date, duet, genre, key, color label, pitch, tempo, rating, rendition, sync-slip, trim start and end, volume, etc etc.  Some file formats, like MP3, Ogg/Vorbis and QuickTime &amp;quot;.mov&amp;quot;,  allow you to store some meta data WITHIN the media file itself, but many simply don&#039;t, so the data must be stored elsewhere.  Plus, even with those that allow meta data within the file, many don&#039;t let you put JUST ANY data in there, they only allow certain kinds. kJams needs to store ANYTHING it wants as meta data, even pictures, whole biographies (for singers), and lyrics with timing (for obvious reasons).&lt;br /&gt;
&lt;br /&gt;
kJams does store a small subset of the meta data in it&#039;s own &amp;quot;Songs.ktd&amp;quot; database file, just enough to get kJams running quickly without having to scan every single media file for it&#039;s meta data.  The reason the xml file is stored WITH the file should be obvious enough, it really IS part of the file.  If you share the file with someone else (not your database, just the music) then the meta data *should* go with the file.  If you need to rebuild your library from scratch (due to some failure, or just because you want to) then the meta data is there, rather than lost in a database file on some other disk.  &lt;br /&gt;
&lt;br /&gt;
You can delete the xml file but you&#039;ll be deleting important information that is not stored elsewhere.&lt;br /&gt;
&lt;br /&gt;
For more info on what exactly this is good for, see [http://www.adobe.com/products/xmp/ Adobe XMP].  XMP is the exact same principal, they want the data to live WITH the file.  XMP tries to store the data inside the file, but when it can&#039;t, it creates a &amp;quot;sidecar&amp;quot; file just like kJams, storing the meta data NEXT TO the file rather than within it.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10448</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10448"/>
		<updated>2015-03-10T18:13:35Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;iimg&amp;gt;http://www.opensource.org/!http://www.kjams.com/resources/open_source.png&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so i&#039;ll put up some of my programming experiences here.  Yeah, that.&lt;br /&gt;
&lt;br /&gt;
* [[Server/Code|Java served up]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/CFLite|CFLite]]  My crowning achievement in Open Source.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/HelloFuseCarbon|Hello FUSE Carbon]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Lame|LAME]] a universal binary of the famous MP3 encoder&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Vorbis|OGG Vorbis Comment Edit Frameworks]] to edit Meta Data tags in Vorbis files&lt;br /&gt;
* [[Code/karaokeArchiver|karaokeArchiver]] automates the zipping together of CD+G and MP3 files&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/AudioClip Recorder|AudioClip Recorder]] automates the creation of audio clips of your productions, and their crossfaded playback&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new iTunes Crossfader|iTunes Crossfader]] automates the cross fading between iTunes and kJams. This new version allows more flexible volume settings&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new kJams server pages with autologout|Server AutoLogout]] [Deprecated] New versions of the kJams server pages with autologout and delete key trapping&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new AUTOMAGIC iTunes Crossfader|iTunes autoCrossfader]] Automates the cross fading between iTunes and kJams. Runs continuously in the background&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Copy Singers|Copy Singers]] [Deprecated]  Service to automate the transfer of Singers between venues&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Sound Effects Player|Sound Effects Player]] Service to provide kJams (or any other program) the ability to play overlapping sound effects&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Video Backdrop Generator|Video Backdrop Generator]] Service to provide kJams with both static and animated lyric screen backdrops.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Server/Code|Flashing &amp;quot;Song Added&amp;quot; alert text]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/New Server Files]] Adds a number of features to make using the server a more streamlined experience.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Python/Code|Python code]] for embedding in C++&lt;br /&gt;
* [[Code/new purgeVM|purgeVM]] purge unused RAM and remove unnecessary swap for OSX&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Blog/Parallels/Solution|Debug a QuickTime app in Parallels without hanging]] by removing the &amp;quot;QTIdle&amp;quot; window from the clipboard chain&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10447</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10447"/>
		<updated>2015-03-10T18:12:48Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;iimg&amp;gt;http://www.opensource.org/!http://www.kjams.com/resources/open_source.png&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so i&#039;ll put up some of my programming experiences here.  Yeah, that.&lt;br /&gt;
&lt;br /&gt;
* [[Server/Code|Java served up]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/CFLite|CFLite]]  My crowning achievement in Open Source.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/HelloFuseCarbon|Hello FUSE Carbon]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Lame|LAME]] a universal binary of the famous MP3 encoder&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Vorbis|OGG Vorbis Comment Edit Frameworks]] to edit Meta Data tags in Vorbis files&lt;br /&gt;
* [[Code/karaokeArchiver|karaokeArchiver]] automates the zipping together of CD+G and MP3 files&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/AudioClip Recorder|AudioClip Recorder]] automates the creation of audio clips of your productions, and their crossfaded playback&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new iTunes Crossfader|iTunes Crossfader]] automates the cross fading between iTunes and kJams. This new version allows more flexible volume settings&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new kJams server pages with autologout|Server AutoLogout]] [Deprecated]New versions of the kJams server pages with autologout and delete key trapping&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new AUTOMAGIC iTunes Crossfader|iTunes autoCrossfader]] Automates the cross fading between iTunes and kJams. Runs continuously in the background&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new (Deprecated) Copy Singers|Copy Singers]] Service to automate the transfer of Singers between venues&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Sound Effects Player|Sound Effects Player]] Service to provide kJams (or any other program) the ability to play overlapping sound effects&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Video Backdrop Generator|Video Backdrop Generator]] Service to provide kJams with both static and animated lyric screen backdrops.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Server/Code|Flashing &amp;quot;Song Added&amp;quot; alert text]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/New Server Files]] Adds a number of features to make using the server a more streamlined experience.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Python/Code|Python code]] for embedding in C++&lt;br /&gt;
* [[Code/new purgeVM|purgeVM]] purge unused RAM and remove unnecessary swap for OSX&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Blog/Parallels/Solution|Debug a QuickTime app in Parallels without hanging]] by removing the &amp;quot;QTIdle&amp;quot; window from the clipboard chain&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10446</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=10446"/>
		<updated>2015-03-10T18:11:26Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;iimg&amp;gt;http://www.opensource.org/!http://www.kjams.com/resources/open_source.png&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so i&#039;ll put up some of my programming experiences here.  Yeah, that.&lt;br /&gt;
&lt;br /&gt;
* [[Server/Code|Java served up]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/CFLite|CFLite]]  My crowning achievement in Open Source.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/HelloFuseCarbon|Hello FUSE Carbon]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Lame|LAME]] a universal binary of the famous MP3 encoder&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Vorbis|OGG Vorbis Comment Edit Frameworks]] to edit Meta Data tags in Vorbis files&lt;br /&gt;
* [[Code/karaokeArchiver|karaokeArchiver]] automates the zipping together of CD+G and MP3 files&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/AudioClip Recorder|AudioClip Recorder]] automates the creation of audio clips of your productions, and their crossfaded playback&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new iTunes Crossfader|iTunes Crossfader]] automates the cross fading between iTunes and kJams. This new version allows more flexible volume settings&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new [Deprecated] kJams server pages with autologout|Server AutoLogout]] New versions of the kJams server pages with autologout and delete key trapping&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new AUTOMAGIC iTunes Crossfader|iTunes autoCrossfader]] Automates the cross fading between iTunes and kJams. Runs continuously in the background&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new [Deprecated] Copy Singers|Copy Singers]] Service to automate the transfer of Singers between venues&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Sound Effects Player|Sound Effects Player]] Service to provide kJams (or any other program) the ability to play overlapping sound effects&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Video Backdrop Generator|Video Backdrop Generator]] Service to provide kJams with both static and animated lyric screen backdrops.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Server/Code|Flashing &amp;quot;Song Added&amp;quot; alert text]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/New Server Files]] Adds a number of features to make using the server a more streamlined experience.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Python/Code|Python code]] for embedding in C++&lt;br /&gt;
* [[Code/new purgeVM|purgeVM]] purge unused RAM and remove unnecessary swap for OSX&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Blog/Parallels/Solution|Debug a QuickTime app in Parallels without hanging]] by removing the &amp;quot;QTIdle&amp;quot; window from the clipboard chain&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9235</id>
		<title>Moving</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9235"/>
		<updated>2013-12-13T13:06:25Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Do you want to transfer your kJams license to another computer?==&lt;br /&gt;
See the article on [[Transferring]].&lt;br /&gt;
==Preliminary==&lt;br /&gt;
These instructions are for moving your music files from your *internal* drive to an *external* drive.  If you&#039;re moving from an external to a new external, just clone the external drive and that&#039;s it.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that the below only applies to music you have ripped from your CD collection or purchased from the built-in stores.  That is, it does not work for files you have &amp;quot;Add to library...&amp;quot;&#039;d.  In other words, if you have imported pre-existing MP3+G files, this procedure will not help you.  In that case, use the &amp;quot;[[Moving#The_Symbolic_Link_Trick|The Symbolic Link Trick]]&amp;quot; below&lt;br /&gt;
&lt;br /&gt;
==Just The Music==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; All your actual music files are on an external volume, saving space on your internal drive.  You can run kJams even if the volume is offline, creating playlists, setting pitches, creating / editing singers, edit meta info, or any other editing or management.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can&#039;t rip, play or burn, and your settings (songs &amp;amp; meta info, playists, singers etc) won&#039;t transfer automatically if you plug the external drive into another machine.&amp;lt;br&amp;gt;&lt;br /&gt;
# In the location where you want to put your music (which may be on an external drive, or network folder), create a folder called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# Now go to ~/Music/kJams/ (on your internal drive), inside that you&#039;ll find &amp;quot;kJams Music&amp;quot; folder&lt;br /&gt;
# Drag that folder to the newly created &amp;quot;kJams&amp;quot; folder from step 1. If this is on an external volume, it will be copied, so be sure to delete the original &amp;quot;kJams Music&amp;quot; folder after you make the copy.&lt;br /&gt;
# Run kJams.  Once the application is running, go to preferences-&amp;gt;advanced, and click the &amp;quot;Change...&amp;quot; button to set the library location to the new place (pick &amp;quot;kJams Music&amp;quot; from the kJams folder created in step 1).&lt;br /&gt;
&lt;br /&gt;
==Music Plus All Library Settings==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You can take your drive to a different machine and plug it in, and the kJams on THAT machine will now be up to date with all your playlists, singers, venues, rotation, songs and related meta info.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can not run kJams with the external drive disconnected.&lt;br /&gt;
&lt;br /&gt;
# In the Finder, go to [[~|&amp;lt;User Folder&amp;gt;/]]Music/kJams/&lt;br /&gt;
# Drag that entire folder (the one called &amp;quot;kJams&amp;quot;) to your external volume.  Delete the original afterwards.&lt;br /&gt;
# On the external volume, select the newly copied &amp;quot;kJams&amp;quot; folder and make an alias.&lt;br /&gt;
# Drag that alias into your [[~|&amp;lt;User Folder&amp;gt;/]]Music/ folder, make sure you rename the alias so it just says &amp;quot;kJams&amp;quot;, not &amp;quot;kJams alias&amp;quot;&lt;br /&gt;
# Now, on all the machines you plan to use this library with, plug in the drive, then do steps 3 and 4&lt;br /&gt;
# you can now delete the alias from the other volume, you don&#039;t need it any more&lt;br /&gt;
&lt;br /&gt;
Here is a [http://karaoke.kjams.com/screenshots/Consolidate_on_External.m4v Tutorial Video] for [[Rebuild|Rebuilding]] while Moving to the external drive&lt;br /&gt;
&lt;br /&gt;
==Preferences==&lt;br /&gt;
If you want to keep your preferences also on the external drive (which includes your serial number license file), do this:&lt;br /&gt;
&lt;br /&gt;
# if your external drive does NOT have a kJams folder already on it (ie: you did NOT do the above procedure, then create a &amp;quot;kJams&amp;quot; folder now on the external drive and leave it open&lt;br /&gt;
# run kjams&lt;br /&gt;
# click &amp;quot;help-&amp;gt;reveal preferences&amp;quot;&lt;br /&gt;
# quit kJams&lt;br /&gt;
# in the Preferences folder that was revealed, you will see the name of that revealed folder is called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# drag that &amp;quot;kJams&amp;quot; preferences folder IN to the &amp;quot;kJams&amp;quot; folder on your external drive&lt;br /&gt;
# delete the &amp;quot;kJams&amp;quot; folder from the Preferences folder you just drug it from&lt;br /&gt;
# The Preferences folder should now NOT have a &amp;quot;kJams&amp;quot; folder in it, and the external drive should now have the folder &amp;quot;kJams&amp;quot; with another folder called &amp;quot;kJams&amp;quot; inside it.  I know that&#039;s a little weird, we&#039;ll fix that in a second&lt;br /&gt;
# select the &amp;quot;kJams&amp;quot; folder that is inside the &amp;quot;kJams&amp;quot; folder on the external drive&lt;br /&gt;
# create an alias / shortcut of that folder&lt;br /&gt;
# drag that alias / shortcut back to the &amp;quot;Preferences&amp;quot; folder&lt;br /&gt;
# in the preferences folder, rename the alias so that it does NOT have the word &amp;quot;alias&amp;quot; or &amp;quot;shortcut&amp;quot; at the end.  BE VERY CAREFUL that you remove the extra space at the end.  eg: when you start it will be &amp;quot;kJams_alias&amp;quot;, note i made the space look like an underbar to make it clear.  you must NOT rename it to &amp;quot;kJams_&amp;quot;, that will not work.  Be sure to get rid of the space too!&lt;br /&gt;
# delete the alias shortcut from the kJams folder&lt;br /&gt;
all set!  when you run, kJams will now use the preferences on the external drive.  If when you run it seems your preferences have been reset to default, and kJams is in tryout mode, then you probably named the alias wrong, so check that again.&lt;br /&gt;
==Cloning a setup==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You maintain a fullly working ready-to-run backup of your entire setup&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You must manually maintain sync between the two systems.&lt;br /&gt;
&lt;br /&gt;
To see the instructions see [[Cloning]].&lt;br /&gt;
&lt;br /&gt;
==Serving Music Remotely==&lt;br /&gt;
You can serve your music from one computer to another.  Using either of the above methods, you can mount your music volume from your network before you launch kJams.  If you store your music on a FAT32 or DOS volume (which is reasonable if you share your karaoke library with a Windows computer), you will need to share your music with [http://www.hornware.com/sharepoints/ SharePoints] using SMB, and mount the volume using smb:// in the connect dialog in the finder.&lt;br /&gt;
==The Symbolic Link Trick==&lt;br /&gt;
This may not work on Windows, not tested yet, anyone care to try and let me know?&lt;br /&gt;
# Quit kJams&lt;br /&gt;
# download and install [http://www.cocoatech.com/pathfinder/ PathFinder] or [http://seiryu.home.comcast.net/~seiryu/symboliclinker.html SymbolicLinker]&lt;br /&gt;
# drag and drop the root folder (or folders if your songs and other assets are stored across multiple directories) from the source location to the dest location&lt;br /&gt;
# delete the folder from the source location (if you wish to keep the original folder/files, e.g. if you are transferring from an external to an internal, and want to keep the external for a backup, move all source files/folders to another location, such as hiding them in another folder)&lt;br /&gt;
# empty the trash.  &amp;lt;-- critical step!  if you don&#039;t do this, you&#039;ll be in for another headache&lt;br /&gt;
# using PathFinder (File Menu-&amp;gt;Alias-&amp;gt;Make Symbolic Link) or SymbolicLinker (right click on file-&amp;gt;Make Symbolic Link), make a Symbolic Link of the folder(s) at the dest location&lt;br /&gt;
# drag it (them) to the source location, so it *seems* that the files appear to be in the source location, at the same path&lt;br /&gt;
# if the symlink is still there next to the dest location folder, you can delete it&lt;br /&gt;
# run kJams, open your &amp;quot;Activity&amp;quot; window, wait for any tasks to finish&lt;br /&gt;
# do a Forced Save (⌘⇧⌥⌃-S) -- this will update all the paths in the DB to the new location&lt;br /&gt;
# delete the symbolic lik&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9234</id>
		<title>Moving</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9234"/>
		<updated>2013-12-13T13:05:46Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Do you want to transfer your kJams license to another computer?==&lt;br /&gt;
See the article on [[Transferring]].&lt;br /&gt;
==Preliminary==&lt;br /&gt;
These instructions are for moving your music files from your *internal* drive to an *external* drive.  If you&#039;re moving from an external to a new external, just clone the external drive and that&#039;s it.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that the below only applies to music you have ripped from your CD collection or purchased from the built-in stores.  That is, it does not work for files you have &amp;quot;Add to library...&amp;quot;&#039;d.  In other words, if you have imported pre-existing MP3+G files, this procedure will not help you.  In that case, use the &amp;quot;[[Moving#The_Symbolic_Link_Trick|The Symbolic Link Trick]]&amp;quot; below&lt;br /&gt;
&lt;br /&gt;
==Just The Music==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; All your actual music files are on an external volume, saving space on your internal drive.  You can run kJams even if the volume is offline, creating playlists, setting pitches, creating / editing singers, edit meta info, or any other editing or management.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can&#039;t rip, play or burn, and your settings (songs &amp;amp; meta info, playists, singers etc) won&#039;t transfer automatically if you plug the external drive into another machine.&amp;lt;br&amp;gt;&lt;br /&gt;
# In the location where you want to put your music (which may be on an external drive, or network folder), create a folder called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# Now go to ~/Music/kJams/ (on your internal drive), inside that you&#039;ll find &amp;quot;kJams Music&amp;quot; folder&lt;br /&gt;
# Drag that folder to the newly created &amp;quot;kJams&amp;quot; folder from step 1. If this is on an external volume, it will be copied, so be sure to delete the original &amp;quot;kJams Music&amp;quot; folder after you make the copy.&lt;br /&gt;
# Run kJams.  Once the application is running, go to preferences-&amp;gt;advanced, and click the &amp;quot;Change...&amp;quot; button to set the library location to the new place (pick &amp;quot;kJams Music&amp;quot; from the kJams folder created in step 1).&lt;br /&gt;
&lt;br /&gt;
==Music Plus All Library Settings==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You can take your drive to a different machine and plug it in, and the kJams on THAT machine will now be up to date with all your playlists, singers, venues, rotation, songs and related meta info.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can not run kJams with the external drive disconnected.&lt;br /&gt;
&lt;br /&gt;
# In the Finder, go to [[~|&amp;lt;User Folder&amp;gt;/]]Music/kJams/&lt;br /&gt;
# Drag that entire folder (the one called &amp;quot;kJams&amp;quot;) to your external volume.  Delete the original afterwards.&lt;br /&gt;
# On the external volume, select the newly copied &amp;quot;kJams&amp;quot; folder and make an alias.&lt;br /&gt;
# Drag that alias into your [[~|&amp;lt;User Folder&amp;gt;/]]Music/ folder, make sure you rename the alias so it just says &amp;quot;kJams&amp;quot;, not &amp;quot;kJams alias&amp;quot;&lt;br /&gt;
# Now, on all the machines you plan to use this library with, plug in the drive, then do steps 3 and 4&lt;br /&gt;
# you can now delete the alias from the other volume, you don&#039;t need it any more&lt;br /&gt;
&lt;br /&gt;
Here is a [http://karaoke.kjams.com/screenshots/Consolidate_on_External.m4v Tutorial Video] for [[Rebuild|Rebuilding]] while Moving to the external drive&lt;br /&gt;
&lt;br /&gt;
==Preferences==&lt;br /&gt;
If you want to keep your preferences also on the external drive (which includes your serial number license file), do this:&lt;br /&gt;
&lt;br /&gt;
# if your external drive does NOT have a kJams folder already on it (ie: you did NOT do the above procedure, then create a &amp;quot;kJams&amp;quot; folder now on the external drive and leave it open&lt;br /&gt;
# run kjams&lt;br /&gt;
# click &amp;quot;help-&amp;gt;reveal preferences&amp;quot;&lt;br /&gt;
# quit kJams&lt;br /&gt;
# in the Preferences folder that was revealed, you will see the name of that revealed folder is called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# drag that &amp;quot;kJams&amp;quot; preferences folder IN to the &amp;quot;kJams&amp;quot; folder on your external drive&lt;br /&gt;
# delete the &amp;quot;kJams&amp;quot; folder from the Preferences folder you just drug it from&lt;br /&gt;
# The Preferences folder should now NOT have a &amp;quot;kJams&amp;quot; folder in it, and the external drive should now have the folder &amp;quot;kJams&amp;quot; with another folder called &amp;quot;kJams&amp;quot; inside it.  I know that&#039;s a little weird, we&#039;ll fix that in a second&lt;br /&gt;
# select the &amp;quot;kJams&amp;quot; folder that is inside the &amp;quot;kJams&amp;quot; folder on the external drive&lt;br /&gt;
# create an alias / shortcut of that folder&lt;br /&gt;
# drag that alias / shortcut back to the &amp;quot;Preferences&amp;quot; folder&lt;br /&gt;
# in the preferences folder, rename the alias so that it does NOT have the word &amp;quot;alias&amp;quot; or &amp;quot;shortcut&amp;quot; at the end.  BE VERY CAREFUL that you remove the extra space at the end.  eg: when you start it will be &amp;quot;kJams_alias&amp;quot;, note i made the space look like an underbar to make it clear.  you must NOT rename it to &amp;quot;kJams_&amp;quot;, that will not work.  Be sure to get rid of the space too!&lt;br /&gt;
# delete the alias shortcut from the kJams folder&lt;br /&gt;
all set!  when you run, kJams will now use the preferences on the external drive.  If when you run it seems your preferences have been reset to default, and kJams is in tryout mode, then you probably named the alias wrong, so check that again.&lt;br /&gt;
==Cloning a setup==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You maintain a fullly working ready-to-run backup of your entire setup&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You must manually maintain sync between the two systems.&lt;br /&gt;
&lt;br /&gt;
To see the instructions see [[Cloning]].&lt;br /&gt;
&lt;br /&gt;
==Serving Music Remotely==&lt;br /&gt;
You can serve your music from one computer to another.  Using either of the above methods, you can mount your music volume from your network before you launch kJams.  If you store your music on a FAT32 or DOS volume (which is reasonable if you share your karaoke library with a Windows computer), you will need to share your music with [http://www.hornware.com/sharepoints/ SharePoints] using SMB, and mount the volume using smb:// in the connect dialog in the finder.&lt;br /&gt;
==The Symbolic Link Trick==&lt;br /&gt;
This may not work on Windows, not tested yet, anyone care to try and let me know?&lt;br /&gt;
# Quit kJams&lt;br /&gt;
# download and install [http://www.cocoatech.com/pathfinder/ PathFinder] or [http://seiryu.home.comcast.net/~seiryu/symboliclinker.html SymbolicLinker]&lt;br /&gt;
# drag and drop the root folder (or folders if your songs and other assets are stored across multiple directories) from the source location to the dest location&lt;br /&gt;
# delete the folder from the source location (if you wish to keep the original folder/files, e.g. if you are transferring from an external to an internal, and want to keep the external for a backup, move all folders to another location, such as hiding them in another folder)&lt;br /&gt;
# empty the trash.  &amp;lt;-- critical step!  if you don&#039;t do this, you&#039;ll be in for another headache&lt;br /&gt;
# using PathFinder (File Menu-&amp;gt;Alias-&amp;gt;Make Symbolic Link) or SymbolicLinker (right click on file-&amp;gt;Make Symbolic Link), make a Symbolic Link of the folder(s) at the dest location&lt;br /&gt;
# drag it (them) to the source location, so it *seems* that the files appear to be in the source location, at the same path&lt;br /&gt;
# if the symlink is still there next to the dest location folder, you can delete it&lt;br /&gt;
# run kJams, open your &amp;quot;Activity&amp;quot; window, wait for any tasks to finish&lt;br /&gt;
# do a Forced Save (⌘⇧⌥⌃-S) -- this will update all the paths in the DB to the new location&lt;br /&gt;
# delete the symbolic lik&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9233</id>
		<title>Moving</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Moving&amp;diff=9233"/>
		<updated>2013-12-13T13:03:29Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Do you want to transfer your kJams license to another computer?==&lt;br /&gt;
See the article on [[Transferring]].&lt;br /&gt;
==Preliminary==&lt;br /&gt;
These instructions are for moving your music files from your *internal* drive to an *external* drive.  If you&#039;re moving from an external to a new external, just clone the external drive and that&#039;s it.&lt;br /&gt;
&lt;br /&gt;
Also keep in mind that the below only applies to music you have ripped from your CD collection or purchased from the built-in stores.  That is, it does not work for files you have &amp;quot;Add to library...&amp;quot;&#039;d.  In other words, if you have imported pre-existing MP3+G files, this procedure will not help you.  In that case, use the &amp;quot;[[Moving#The_Symbolic_Link_Trick|The Symbolic Link Trick]]&amp;quot; below&lt;br /&gt;
&lt;br /&gt;
==Just The Music==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; All your actual music files are on an external volume, saving space on your internal drive.  You can run kJams even if the volume is offline, creating playlists, setting pitches, creating / editing singers, edit meta info, or any other editing or management.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can&#039;t rip, play or burn, and your settings (songs &amp;amp; meta info, playists, singers etc) won&#039;t transfer automatically if you plug the external drive into another machine.&amp;lt;br&amp;gt;&lt;br /&gt;
# In the location where you want to put your music (which may be on an external drive, or network folder), create a folder called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# Now go to ~/Music/kJams/ (on your internal drive), inside that you&#039;ll find &amp;quot;kJams Music&amp;quot; folder&lt;br /&gt;
# Drag that folder to the newly created &amp;quot;kJams&amp;quot; folder from step 1. If this is on an external volume, it will be copied, so be sure to delete the original &amp;quot;kJams Music&amp;quot; folder after you make the copy.&lt;br /&gt;
# Run kJams.  Once the application is running, go to preferences-&amp;gt;advanced, and click the &amp;quot;Change...&amp;quot; button to set the library location to the new place (pick &amp;quot;kJams Music&amp;quot; from the kJams folder created in step 1).&lt;br /&gt;
&lt;br /&gt;
==Music Plus All Library Settings==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You can take your drive to a different machine and plug it in, and the kJams on THAT machine will now be up to date with all your playlists, singers, venues, rotation, songs and related meta info.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You can not run kJams with the external drive disconnected.&lt;br /&gt;
&lt;br /&gt;
# In the Finder, go to [[~|&amp;lt;User Folder&amp;gt;/]]Music/kJams/&lt;br /&gt;
# Drag that entire folder (the one called &amp;quot;kJams&amp;quot;) to your external volume.  Delete the original afterwards.&lt;br /&gt;
# On the external volume, select the newly copied &amp;quot;kJams&amp;quot; folder and make an alias.&lt;br /&gt;
# Drag that alias into your [[~|&amp;lt;User Folder&amp;gt;/]]Music/ folder, make sure you rename the alias so it just says &amp;quot;kJams&amp;quot;, not &amp;quot;kJams alias&amp;quot;&lt;br /&gt;
# Now, on all the machines you plan to use this library with, plug in the drive, then do steps 3 and 4&lt;br /&gt;
# you can now delete the alias from the other volume, you don&#039;t need it any more&lt;br /&gt;
&lt;br /&gt;
Here is a [http://karaoke.kjams.com/screenshots/Consolidate_on_External.m4v Tutorial Video] for [[Rebuild|Rebuilding]] while Moving to the external drive&lt;br /&gt;
&lt;br /&gt;
==Preferences==&lt;br /&gt;
If you want to keep your preferences also on the external drive (which includes your serial number license file), do this:&lt;br /&gt;
&lt;br /&gt;
# if your external drive does NOT have a kJams folder already on it (ie: you did NOT do the above procedure, then create a &amp;quot;kJams&amp;quot; folder now on the external drive and leave it open&lt;br /&gt;
# run kjams&lt;br /&gt;
# click &amp;quot;help-&amp;gt;reveal preferences&amp;quot;&lt;br /&gt;
# quit kJams&lt;br /&gt;
# in the Preferences folder that was revealed, you will see the name of that revealed folder is called &amp;quot;kJams&amp;quot;&lt;br /&gt;
# drag that &amp;quot;kJams&amp;quot; preferences folder IN to the &amp;quot;kJams&amp;quot; folder on your external drive&lt;br /&gt;
# delete the &amp;quot;kJams&amp;quot; folder from the Preferences folder you just drug it from&lt;br /&gt;
# The Preferences folder should now NOT have a &amp;quot;kJams&amp;quot; folder in it, and the external drive should now have the folder &amp;quot;kJams&amp;quot; with another folder called &amp;quot;kJams&amp;quot; inside it.  I know that&#039;s a little weird, we&#039;ll fix that in a second&lt;br /&gt;
# select the &amp;quot;kJams&amp;quot; folder that is inside the &amp;quot;kJams&amp;quot; folder on the external drive&lt;br /&gt;
# create an alias / shortcut of that folder&lt;br /&gt;
# drag that alias / shortcut back to the &amp;quot;Preferences&amp;quot; folder&lt;br /&gt;
# in the preferences folder, rename the alias so that it does NOT have the word &amp;quot;alias&amp;quot; or &amp;quot;shortcut&amp;quot; at the end.  BE VERY CAREFUL that you remove the extra space at the end.  eg: when you start it will be &amp;quot;kJams_alias&amp;quot;, note i made the space look like an underbar to make it clear.  you must NOT rename it to &amp;quot;kJams_&amp;quot;, that will not work.  Be sure to get rid of the space too!&lt;br /&gt;
# delete the alias shortcut from the kJams folder&lt;br /&gt;
all set!  when you run, kJams will now use the preferences on the external drive.  If when you run it seems your preferences have been reset to default, and kJams is in tryout mode, then you probably named the alias wrong, so check that again.&lt;br /&gt;
==Cloning a setup==&lt;br /&gt;
&#039;&#039;&#039;Advantage:&#039;&#039;&#039; You maintain a fullly working ready-to-run backup of your entire setup&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Disadvantage:&#039;&#039;&#039; You must manually maintain sync between the two systems.&lt;br /&gt;
&lt;br /&gt;
To see the instructions see [[Cloning]].&lt;br /&gt;
&lt;br /&gt;
==Serving Music Remotely==&lt;br /&gt;
You can serve your music from one computer to another.  Using either of the above methods, you can mount your music volume from your network before you launch kJams.  If you store your music on a FAT32 or DOS volume (which is reasonable if you share your karaoke library with a Windows computer), you will need to share your music with [http://www.hornware.com/sharepoints/ SharePoints] using SMB, and mount the volume using smb:// in the connect dialog in the finder.&lt;br /&gt;
==The Symbolic Link Trick==&lt;br /&gt;
This may not work on Windows, not tested yet, anyone care to try and let me know?&lt;br /&gt;
# Quit kJams&lt;br /&gt;
# download and install [http://www.cocoatech.com/pathfinder/ PathFinder] or [http://seiryu.home.comcast.net/~seiryu/symboliclinker.html SymbolicLinker]&lt;br /&gt;
# drag and drop the root folder (or folders if your songs and other assets are stored across multiple directories) from the source location to the dest location&lt;br /&gt;
# delete the folder from the source location&lt;br /&gt;
# empty the trash.  &amp;lt;-- critical step!  if you don&#039;t do this, you&#039;ll be in for another headache&lt;br /&gt;
# using PathFinder (File Menu-&amp;gt;Alias-&amp;gt;Make Symbolic Link) or SymbolicLinker (right click on file-&amp;gt;Make Symbolic Link), make a Symbolic Link of the folder(s) at the dest location&lt;br /&gt;
# drag it (them) to the source location, so it *seems* that the files appear to be in the source location, at the same path&lt;br /&gt;
# if the symlink is still there next to the dest location folder, you can delete it&lt;br /&gt;
# run kJams, open your &amp;quot;Activity&amp;quot; window, wait for any tasks to finish&lt;br /&gt;
# do a Forced Save (⌘⇧⌥⌃-S) -- this will update all the paths in the DB to the new location&lt;br /&gt;
# delete the symbolic lik&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9219</id>
		<title>Code/new purgeVM</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9219"/>
		<updated>2013-12-03T00:31:02Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you are having problems with losing disk space on OSX due to swap file space growing out of control, you can solve the issue by rebooting&lt;br /&gt;
Alternately, if you are not afraid of venturing into Terminal land, you can use this tiny little app I wrote, which will purge unused RAM cache and collapse and remove unused swap space, potentially dramatically restarting &amp;quot;missing&amp;quot; disk space and  restoring system performance.&lt;br /&gt;
&lt;br /&gt;
Be VERY careful, however, as setting it up involves doing things that could potentially render your system unbootable.&lt;br /&gt;
(If what I am writing seems unintelligible to you, it might be best for you not to attempt it!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a text editor and paste in the code. Save somewhere. Then go to Terminal. Log in to an administrator account and type &amp;quot;chmod 755 path/to/the/file&amp;quot;. Now you can double click on it, and it will open Terminal, run the code, and exit. You need to make sure you are either running this from an admin account, or add your standard user account to sudoers for this to work.&lt;br /&gt;
&lt;br /&gt;
To add your standard account to sudoers, log in to an admin account, type &amp;quot;sudo visudo&amp;quot; and type in your admin password. Find the following line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
and add your standard user account info like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
yourshortusername     All=(ALL) ALL&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternately, you can run AppleScript Editor, and paste the following code into a new script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do shell script &amp;quot;sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;quot; with administrator privileges&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Save as an application by selecting &amp;quot;Save…&amp;quot; from the File menu then selecting &amp;quot;Application&amp;quot; from the &amp;quot;File format&amp;quot; pop up menu.&lt;br /&gt;
&lt;br /&gt;
Now you can just double click and run like any normal OSX app.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9218</id>
		<title>Code/new purgeVM</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9218"/>
		<updated>2013-12-03T00:30:15Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you are having problems with losing disk space on OSX due to swap file space growing out of control, you can solve the issue by rebooting&lt;br /&gt;
Alternately, if you are not afraid of venturing into Terminal land, you can use this tiny little app I wrote, which will purge unused RAM cache and collapse and remove unused swap space, potentially dramatically restarting &amp;quot;missing&amp;quot; disk space and  restoring system performance.&lt;br /&gt;
&lt;br /&gt;
Be VERY careful, however, as setting it up involves doing things that could potentially render your system unbootable.&lt;br /&gt;
(If what I am writing seems unintelligible to you, it might be best for you not to attempt it!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a text editor and paste in the code. Save somewhere. Then go to Terminal. Log in to an administrator account and type &amp;quot;chmod 755 path/to/the/file&amp;quot;. Now you can double click on it, and it will open Terminal, run the code, and exit. You need to make sure you are either running this from an admin account, or add your standard user account to sudoers for this to work.&lt;br /&gt;
&lt;br /&gt;
To add your standard account to sudoers, log in to an admin account, type &amp;quot;sudo visudo&amp;quot; and type in your admin password. Find the following line:&lt;br /&gt;
&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
and add your standard user account info like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
yourshortusername     All=(ALL) ALL&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Alternately, you can run AppleScript Editor, and paste the following code into a new script:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
do shell script &amp;quot;sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;quot; with administrator privileges&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Save as an application by selecting &amp;quot;Save…&amp;quot; from the File menu then selecting &amp;quot;Application&amp;quot; from the &amp;quot;File format&amp;quot; pop up menu.&lt;br /&gt;
&lt;br /&gt;
Now you can just double click and run like any normal OSX app.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9217</id>
		<title>Code/new purgeVM</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9217"/>
		<updated>2013-12-03T00:28:54Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you are having problems with losing disk space on OSX due to swap file space growing out of control, you can solve the issue by rebooting&lt;br /&gt;
Alternately, if you are not afraid of venturing into Terminal land, you can use this tiny little app I wrote, which will purge unused RAM cache and collapse and remove unused swap space, potentially dramatically restarting &amp;quot;missing&amp;quot; disk space and  restoring system performance.&lt;br /&gt;
&lt;br /&gt;
Be VERY careful, however, as setting it up involves doing things that could potentially render your system unbootable.&lt;br /&gt;
(If what I am writing seems unintelligible to you, it might be best for you not to attempt it!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre?&lt;br /&gt;
sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Open a text editor and paste in the code. Save somewhere. Then go to Terminal. Log in to an administrator account and type &amp;quot;chmod 755 path/to/the/file&amp;quot;. Now you can double click on it, and it will open Terminal, run the code, and exit. You need to make sure you are either running this from an admin account, or add your standard user account to sudoers for this to work.&lt;br /&gt;
&lt;br /&gt;
To add your standard account to sudoers, log in to an admin account, type &amp;quot;sudo visudo&amp;quot; and type in your admin password. Find the following line:&lt;br /&gt;
&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
and add your standard user account info like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
yourshortusername     All=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Alternately, you can run AppleScript Editor, and paste the following code into a new script:&lt;br /&gt;
&lt;br /&gt;
do shell script &amp;quot;sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;quot; with administrator privileges&lt;br /&gt;
&lt;br /&gt;
Save as an application by selecting &amp;quot;Save…&amp;quot; from the File menu then selecting &amp;quot;Application&amp;quot; from the &amp;quot;File format&amp;quot; pop up menu.&lt;br /&gt;
&lt;br /&gt;
Now you can just double click and run like any normal OSX app.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9216</id>
		<title>Code/new purgeVM</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_purgeVM&amp;diff=9216"/>
		<updated>2013-12-03T00:27:47Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: Created page with &amp;quot;If you are having problems with losing disk space on OSX due to swap file space growing out of control, you can solve the issue by rebooting Alternately, if you are not afraid...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you are having problems with losing disk space on OSX due to swap file space growing out of control, you can solve the issue by rebooting&lt;br /&gt;
Alternately, if you are not afraid of venturing into Terminal land, you can use this tiny little app I wrote, which will purge unused RAM cache and collapse and remove unused swap space, potentially dramatically restarting &amp;quot;missing&amp;quot; disk space and  restoring system performance.&lt;br /&gt;
&lt;br /&gt;
Be VERY careful, however, as setting it up involves doing things that could potentially render your system unbootable.&lt;br /&gt;
(If what I am writing seems unintelligible to you, it might be best for you not to attempt it!)&lt;br /&gt;
&lt;br /&gt;
[code]&lt;br /&gt;
sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
[/code]&lt;br /&gt;
&lt;br /&gt;
Open a text editor and paste in the code. Save somewhere. Then go to Terminal. Log in to an administrator account and type &amp;quot;chmod 755 path/to/the/file&amp;quot;. Now you can double click on it, and it will open Terminal, run the code, and exit. You need to make sure you are either running this from an admin account, or add your standard user account to sudoers for this to work.&lt;br /&gt;
&lt;br /&gt;
To add your standard account to sudoers, log in to an admin account, type &amp;quot;sudo visudo&amp;quot; and type in your admin password. Find the following line:&lt;br /&gt;
&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
and add your standard user account info like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# User privilege specification&lt;br /&gt;
root    ALL=(ALL) ALL&lt;br /&gt;
%admin  ALL=(ALL) ALL&lt;br /&gt;
yourshortusername     All=(ALL) ALL&lt;br /&gt;
&lt;br /&gt;
Alternately, you can run AppleScript Editor, and paste the following code into a new script:&lt;br /&gt;
&lt;br /&gt;
do shell script &amp;quot;sudo purge&lt;br /&gt;
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
sudo rm /private/var/vm/swapfile*&lt;br /&gt;
sudo launchctl load -wF /System/Library/LaunchDaemons/com.apple.dynamic_pager.plist&lt;br /&gt;
&amp;quot; with administrator privileges&lt;br /&gt;
&lt;br /&gt;
Save as an application by selecting &amp;quot;Save…&amp;quot; from the File menu then selecting &amp;quot;Application&amp;quot; from the &amp;quot;File format&amp;quot; pop up menu.&lt;br /&gt;
&lt;br /&gt;
Now you can just double click and run like any normal OSX app.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=9215</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=9215"/>
		<updated>2013-12-02T23:54:00Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;iimg&amp;gt;http://www.opensource.org/!http://www.kjams.com/resources/open_source.png&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so i&#039;ll put up some of my programming experiences here.  Yeah, that.&lt;br /&gt;
&lt;br /&gt;
* [[Server/Code|Java served up]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/CFLite|CFLite]]  My crowning achievement in Open Source.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/HelloFuseCarbon|Hello FUSE Carbon]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Lame|LAME]] a universal binary of the famous MP3 encoder&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Vorbis|OGG Vorbis Comment Edit Frameworks]] to edit Meta Data tags in Vorbis files&lt;br /&gt;
* [[Code/karaokeArchiver|karaokeArchiver]] automates the zipping together of CD+G and MP3 files&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/AudioClip Recorder|AudioClip Recorder]] automates the creation of audio clips of your productions, and their crossfaded playback&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new iTunes Crossfader|iTunes Crossfader]] automates the cross fading between iTunes and kJams. This new version allows more flexible volume settings&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new kJams server pages with autologout|Server AutoLogout]] New versions of the kJams server pages with autologout and delete key trapping&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new AUTOMAGIC iTunes Crossfader|iTunes autoCrossfader]] Automates the cross fading between iTunes and kJams. Runs continuously in the background&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Copy Singers|Copy Singers]] Service to automate the transfer of Singers between venues&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Sound Effects Player|Sound Effects Player]] Service to provide kJams (or any other program) the ability to play overlapping sound effects&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Video Backdrop Generator|Video Backdrop Generator]] Service to provide kJams with both static and animated lyric screen backdrops.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Server/Code|Flashing &amp;quot;Song Added&amp;quot; alert text]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/New Server Files]] Adds a number of features to make using the server a more streamlined experience.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Python/Code|Python code]] for embedding in C++&lt;br /&gt;
* [[Code/new purgeVM|purgeVM]] purge unused RAM and remove unnecessary swap for OSX&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_Copy_Singers&amp;diff=9164</id>
		<title>Code/new Copy Singers</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_Copy_Singers&amp;diff=9164"/>
		<updated>2013-10-31T11:46:35Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So with the advent of &amp;quot;Venues&amp;quot; you may have run into the situation where a singer from another venue shows up out of the blue at the current venue, wanting to see their history list. Accessing it is kinda a nightmare, involving going to the Finder, drilling down until you find the right singer folder, creating an alias, and then copying that alias over to the current venue folder, followed by changing venues in kJams, and then changing it back again in order to force kJams to reload the current venue&#039;s Singers folder.&lt;br /&gt;
&lt;br /&gt;
Well, I can&#039;t do anything about the kJams end of things, as that functionality is not currently exposed to an API like Applescript, but what I can do is automate the rest.&lt;br /&gt;
After a full 1/2 day of work (mostly since I am a lousy programmer!) I managed to get the following working. You have two choices on how to use this. You can open Applescript Editor and paste the following code into a new script window, and save as an application, and then run as you would any other application.&lt;br /&gt;
But better yet, open up Automator, select &amp;quot;Service&amp;quot; from the template choices on the opening splash screen, and then drag &amp;quot;Run AppleScript&amp;quot; from the Library onto the Stage. Change the &amp;quot;Service receives selected&amp;quot; popup to &amp;quot;no input&amp;quot;, and &amp;quot;applications&amp;quot; to &amp;quot;kJams&amp;quot;. (First choose &amp;quot;other…&amp;quot; from the popup menu, and then browse to kJams in the file selector.) Next, paste the following code over top of where is says &amp;quot;(* Your script goes here *)&amp;quot;. Finally, change the first line where it says &amp;quot;set kJamsPath to &amp;quot;Users/yourusername/Music/kJams/kJams Library/&amp;quot; by replacing &amp;quot;yourusername&amp;quot; with, oddly, you user name (use your short user name) and save.&lt;br /&gt;
&lt;br /&gt;
Then when you run kJams, and need this functionality, either run the application from where you saved it to, or if you saved it in automator as a service, simply select &amp;quot;Services&amp;quot; from the kJams menu, and then select your saved service.&lt;br /&gt;
At that point just follow the prompts to tell the service which singers you want to transfer (you can transfer multiple singers at the same time.) This will put an alias in your current venue folder, thus letting that singer access his or her playlists from either venue.&lt;br /&gt;
&lt;br /&gt;
If this is helpful, let me know [https://karaoke.kjams.com/forum/viewtopic.php?f=1&amp;amp;t=1406&amp;amp;sid=844b30850395dd5448ac2bf9a78a581c&amp;amp;p=7915#p7915 here].&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
Thanks to recent additions to the kJams code and its exposure to AppleScript, I was able to fully automate the code. Use the following code now to perform the entire act of copying the singers&#039; folders to the new venue AND actually making kJams recognize that the singers are in the new venue.&lt;br /&gt;
Proceed with a small amount of caution, however, as you are on the cutting edge here, and you might get a little blood on you! In particular, it appears to expose a bug that causes kJams to go slightly bonkers, and possibly lose the copied singers&#039; lists IF you already have an alias to the same singer(s) in that venue already. I am speculating that this is because you are trying to have multiple singers with the same ID, and kjams gets noticeably, and justifiably, upset. This should affect almost no one, and actually no one, if you don&#039;t mess around in your venues by hand and run this script hundreds of times, thus getting things royally confused in there, trying to test things out!&lt;br /&gt;
As always, let me know how it is working!&lt;br /&gt;
&lt;br /&gt;
P.S. as added goodness, in my testing, the new code NEVER caused server to fail to come back up due to an unreleased port!&lt;br /&gt;
P.P.S. If you totally love this, please feel free to [https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;amp;business=manifold_sky%yahoo%2ecom&amp;amp;item_name=kJams%20Video%20Backdrop%20Donation&amp;amp;no_shipping=2&amp;amp;no_note=1&amp;amp;currency_code=USD&amp;amp;lc=US&amp;amp;bn=PP%2dBuyNowBF&amp;amp;charset=UTF%2d8 paypal the author].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iimg&amp;gt;https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;amp;business=manifold_sky%yahoo%2ecom&amp;amp;item_name=kJams%20Video%20Backdrop%20Donation&amp;amp;no_shipping=2&amp;amp;no_note=1&amp;amp;currency_code=USD&amp;amp;lc=US&amp;amp;bn=PP%2dBuyNowBF&amp;amp;charset=UTF%2d8&lt;br /&gt;
!http://kjams.com/resources/paypal.gif&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
set kJamsPath to &amp;quot;/Users/YourUserName/Music/kJams/kJams Library/&amp;quot;&lt;br /&gt;
set kJamsLibraryPath to kJamsPath &amp;amp; &amp;quot;Library.xml&amp;quot;&lt;br /&gt;
set XMLfile to (POSIX file (kJamsLibraryPath))&lt;br /&gt;
set Paras to paragraphs of (read XMLfile)&lt;br /&gt;
&lt;br /&gt;
-- we cycle through the list and extract the portion between the tag we&#039;re interested in&lt;br /&gt;
-- we know that the tag we want is immediately after &amp;quot;&amp;lt;key&amp;gt;Current Venue&amp;lt;/key&amp;gt;&amp;quot;&lt;br /&gt;
set tagValue to {}&lt;br /&gt;
repeat with i from 1 to count of Paras&lt;br /&gt;
	if item i of Paras contains &amp;quot;Current Venue&amp;quot; then -- first we find the tag we&#039;re interested in&lt;br /&gt;
		set tagValue to item (i + 1) of Paras&lt;br /&gt;
		exit repeat&lt;br /&gt;
	end if&lt;br /&gt;
end repeat&lt;br /&gt;
&lt;br /&gt;
-- next we extract each value from the found tags knowing that the value is between &amp;quot;&amp;lt;string&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/string&amp;gt;&lt;br /&gt;
repeat with i from 1 to count of tagValue&lt;br /&gt;
	set thisTag to item i of tagValue&lt;br /&gt;
	set venueName to &amp;quot;&amp;quot;&lt;br /&gt;
	if thisTag is &amp;quot;&amp;gt;&amp;quot; then&lt;br /&gt;
		repeat with k from (i + 1) to count of tagValue&lt;br /&gt;
			set thisTag to item k of tagValue&lt;br /&gt;
			if thisTag is &amp;quot;&amp;lt;&amp;quot; then exit repeat&lt;br /&gt;
			set venueName to venueName &amp;amp; thisTag&lt;br /&gt;
		end repeat&lt;br /&gt;
		exit repeat&lt;br /&gt;
	end if&lt;br /&gt;
end repeat&lt;br /&gt;
-- thisTagValue&lt;br /&gt;
set kJamsPath to kJamsPath &amp;amp; &amp;quot;Venues/&amp;quot;&lt;br /&gt;
set venuePath to (POSIX file (kJamsPath))&lt;br /&gt;
set singerPath to (POSIX file (kJamsPath &amp;amp; venueName &amp;amp; &amp;quot;/Singers&amp;quot;))&lt;br /&gt;
set Singers to (choose folder default location alias venuePath with prompt &amp;quot;Choose singers to copy to the current venue&amp;quot; with multiple selections allowed) as list&lt;br /&gt;
&lt;br /&gt;
tell application &amp;quot;Finder&amp;quot;&lt;br /&gt;
	make new alias file at singerPath to Singers&lt;br /&gt;
end tell&lt;br /&gt;
&lt;br /&gt;
set kCurSongTime_REMAINING to 2&lt;br /&gt;
set kScriptCommand_RESCAN_VENUE to 19&lt;br /&gt;
set kScriptCommand_SHOW_ROTATION to 20&lt;br /&gt;
set kScriptCommand_HIDE_SHOWSCREEN to 21&lt;br /&gt;
set kScriptCommand_IS_SHOWSCREEN_SHOWING to 22&lt;br /&gt;
set kScriptCommand_GET_SHOW_ROTATION_TIME_REMAIN to 23&lt;br /&gt;
tell application &amp;quot;kJams Pro&amp;quot;&lt;br /&gt;
	set rotationCueTime to docommand kScriptCommand_GET_SHOW_ROTATION_TIME_REMAIN&lt;br /&gt;
	set timeRemaining to get time kCurSongTime_REMAINING&lt;br /&gt;
	set showScreenIsShowing to docommand kScriptCommand_IS_SHOWSCREEN_SHOWING&lt;br /&gt;
	&lt;br /&gt;
	if showScreenIsShowing = 0 then&lt;br /&gt;
		if rotationCueTime is equal to timeRemaining then docommand kScriptCommand_SHOW_ROTATION&lt;br /&gt;
		&lt;br /&gt;
	end if&lt;br /&gt;
	docommand kScriptCommand_RESCAN_VENUE&lt;br /&gt;
end tell&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to make into a service,&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/New_Server_Files&amp;diff=8520</id>
		<title>Code/New Server Files</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/New_Server_Files&amp;diff=8520"/>
		<updated>2013-04-25T21:42:47Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are the files you need to update the server. Changes/New Features include:&lt;br /&gt;
&lt;br /&gt;
•Filters for search&amp;lt;br&amp;gt;&lt;br /&gt;
•Filters also act as search buttons if a search term exists&amp;lt;br&amp;gt;&lt;br /&gt;
•Overlay screen on search (probably to be deprecated once fast search is done)&amp;lt;br&amp;gt;&lt;br /&gt;
•No click through on overlay (probably to be deprecated once fast search is done)&amp;lt;br&amp;gt;&lt;br /&gt;
•User hints during search (probably to be deprecated once fast search is done)&amp;lt;br&amp;gt;&lt;br /&gt;
•Fast (instantaneous!) client-side sort&amp;lt;br&amp;gt;&lt;br /&gt;
•Reverse sort (click the same sort column, and it reverses the sort order&amp;lt;br&amp;gt;&lt;br /&gt;
•Sort blocked on &amp;quot;Add to&amp;quot; columns (because why would you do that?!?)&amp;lt;br&amp;gt;&lt;br /&gt;
•Status alert displaying how many tracks found in given playlist&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:/Users/u-chunchoi/Library/Preferences/kJams/server/data.js|thumbnail|data.js]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
OKAY, JUST GOT ANOTHER FEATURE REQUEST, SO I&#039;LL LEAVE THIS UP AS A WORK IN PROGRESS. IF YOU SEE THIS MESSAGE, THE FILES ARE NOT READY YET!&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/New_Server_Files&amp;diff=8519</id>
		<title>Code/New Server Files</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/New_Server_Files&amp;diff=8519"/>
		<updated>2013-04-25T21:40:52Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: Created page with &amp;quot;Here are the files you need to update the server. Changes/New Features include:  •Filters for search •Filters also act as search buttons if a search term exists •Overlay...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Here are the files you need to update the server. Changes/New Features include:&lt;br /&gt;
&lt;br /&gt;
•Filters for search&lt;br /&gt;
•Filters also act as search buttons if a search term exists&lt;br /&gt;
•Overlay screen on search (probably to be deprecated once fast search is done)&lt;br /&gt;
•No click through on overlay (probably to be deprecated once fast search is done)&lt;br /&gt;
•User hints during search (probably to be deprecated once fast search is done)&lt;br /&gt;
•Fast (instantaneous!) client-side sort&lt;br /&gt;
•Reverse sort (click the same sort column, and it reverses the sort order&lt;br /&gt;
•Sort blocked on &amp;quot;Add to&amp;quot; columns (because why would you do that?!?)&lt;br /&gt;
•Status alert displaying how many tracks found in given playlist&lt;br /&gt;
&lt;br /&gt;
[[File:/Users/u-chunchoi/Library/Preferences/kJams/server/data.js|thumbnail|data.js]]&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=8518</id>
		<title>Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code&amp;diff=8518"/>
		<updated>2013-04-25T21:21:09Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;iimg&amp;gt;http://www.opensource.org/!http://www.kjams.com/resources/open_source.png&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so i&#039;ll put up some of my programming experiences here.  Yeah, that.&lt;br /&gt;
&lt;br /&gt;
* [[Server/Code|Java served up]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/CFLite|CFLite]]  My crowning achievement in Open Source.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/HelloFuseCarbon|Hello FUSE Carbon]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Lame|LAME]] a universal binary of the famous MP3 encoder&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Vorbis|OGG Vorbis Comment Edit Frameworks]] to edit Meta Data tags in Vorbis files&lt;br /&gt;
* [[Code/karaokeArchiver|karaokeArchiver]] automates the zipping together of CD+G and MP3 files&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/AudioClip Recorder|AudioClip Recorder]] automates the creation of audio clips of your productions, and their crossfaded playback&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new iTunes Crossfader|iTunes Crossfader]] automates the cross fading between iTunes and kJams. This new version allows more flexible volume settings&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new kJams server pages with autologout|Server AutoLogout]] New versions of the kJams server pages with autologout and delete key trapping&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new AUTOMAGIC iTunes Crossfader|iTunes autoCrossfader]] Automates the cross fading between iTunes and kJams. Runs continuously in the background&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Copy Singers|Copy Singers]] Service to automate the transfer of Singers between venues&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Sound Effects Player|Sound Effects Player]] Service to provide kJams (or any other program) the ability to play overlapping sound effects&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/new Video Backdrop Generator|Video Backdrop Generator]] Service to provide kJams with both static and animated lyric screen backdrops.&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Server/Code|Flashing &amp;quot;Song Added&amp;quot; alert text]] by the kJams [[Server]]&amp;lt;br&amp;gt;&lt;br /&gt;
* [[Code/New Server Files]] Adds a number of features to make using the server a more streamlined experience.&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8046</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8046"/>
		<updated>2012-09-22T08:08:34Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some of these things I suspect are trivial, specifically fixing the fact that meta data gets reverted, extending the bleep.txt file functionality to global search and replace (&amp;quot;yeh&amp;quot; --&amp;gt; &amp;quot;yeah, &amp;quot;cuz&amp;quot; -&amp;gt; &#039;cause, etc.) and adding a warning if quitting Producer will lose changes&lt;br /&gt;
The two tricky ones that will provide the most benefit are the top two. Together these items are the bulk of the problem.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected. This theoretically makes it much simpler to fix, and as such, bumps this up to the top of the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8045</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8045"/>
		<updated>2012-09-22T08:08:03Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some of these things I suspect are trivial, specifically fixing the fact that meta data gets reverted, extending the bleep.txt file functionality to global search and replace (&amp;quot;yeh&amp;quot; --&amp;gt; &amp;quot;yeah, &amp;quot;cuz&amp;quot; -&amp;gt; &#039;cause, etc.) and adding a warning if quitting Producer will lose changes&lt;br /&gt;
The two tricky ones that will provide the most benefit are the top two. Together these four items are the bulk of the problem.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected. This theoretically makes it much simpler to fix, and as such, bumps this up to the top of the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8044</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8044"/>
		<updated>2012-09-22T08:05:27Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Some of these things I suspect are trivial, specifically fixing the fact that meta data gets reverted and adding a warning if quitting Producer will lose changes&lt;br /&gt;
The two tricky ones that will provide the most benefit are the top two. Together these four items are the bulk of the problem.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected. This theoretically makes it much simpler to fix, and as such, bumps this up to the top of the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8043</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8043"/>
		<updated>2012-09-22T08:02:24Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected. This theoretically makes it much simpler to fix, and as such, bumps this up to the top of the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8042</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8042"/>
		<updated>2012-09-22T08:00:50Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Word spacing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected. This theoretically makes it much simpler to fix, and as such, bumps this up to the top of the list.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8041</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8041"/>
		<updated>2012-09-22T07:58:33Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Word spacing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8040</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8040"/>
		<updated>2012-09-22T07:58:12Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Word spacing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;ADDENDUM: As mentioned in e-mail, One common trait of all such conjoined words is the lack of terminal white space on the first word. So &amp;quot;&amp;lt;&amp;gt;love &amp;lt;&amp;gt;&amp;quot; becomes &amp;quot;&amp;lt;&amp;gt;love&amp;lt;&amp;gt;&amp;quot;. Although there are other times that this white space is missing, it seems key here in that it prevents the following word from being separated from the first word in lines so affected.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==That forum post==&lt;br /&gt;
https://karaoke.kjams.com/forum/viewtopic.php?f=7&amp;amp;t=1965&amp;amp;p=10944#p10944&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Windows/Microphone&amp;diff=8020</id>
		<title>Windows/Microphone</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Windows/Microphone&amp;diff=8020"/>
		<updated>2012-09-17T16:14:59Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;It&#039;s possible to have a microphone play thru your Windows 7 computer.  First, plug your microphone into your &amp;quot;Line in&amp;quot; jack, or if you have a USB mic, just plug it in.&lt;br /&gt;
&lt;br /&gt;
Then, go to Start-&amp;gt;Control Panels-&amp;gt;Sound&amp;lt;br&amp;gt;&lt;br /&gt;
http://kjams.com/screenshots/windows/audio/input/1-cp.png&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then click the &amp;quot;Recording&amp;quot; tab&amp;lt;br&amp;gt;&lt;br /&gt;
Then, click the &amp;quot;Line in&amp;quot; (or your USB mic), and click &amp;quot;Properties&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
http://kjams.com/screenshots/windows/audio/input/2-cp-rec.png&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, click the &amp;quot;Listen&amp;quot; tab, then check the &amp;quot;Listen to this device&amp;quot; check box.&amp;lt;br&amp;gt;&lt;br /&gt;
http://kjams.com/screenshots/windows/audio/input/3-line-listen.png&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now click &amp;quot;Apply&amp;quot; and you will hear sound coming from your microphone.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8018</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8018"/>
		<updated>2012-09-15T02:58:17Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Fix &amp;quot;save MSI default&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8017</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=8017"/>
		<updated>2012-09-15T02:56:54Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Fix &amp;quot;save MSI default&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
NOTE:&lt;br /&gt;
I think one of the main problems here is that you are trying to save based on the Singer type (Male Vocal 1, Rap, Sing, Female, etc.). I think this is a problematic way of doing things, because these names can change from song to song quite a bit.&lt;br /&gt;
If possible, and perhaps it simplifies things, the real way to do this would be to just assign default colours based on position (first item in the list gets colours a, b, c, and d; the next item, say Male 1, gets colours e, f, g, and h, the next item, say Male 2, gets colours i, j, k, and l. This way there is only a need to store three or four default colour sets, not an unlimited number.&lt;br /&gt;
The one caveat being that if there is only one singer, that should have it&#039;s own default.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7995</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7995"/>
		<updated>2012-09-07T20:45:48Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into the javascript section of your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Bind key press function&lt;br /&gt;
	document.onkeyup = m_keyPressed;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;br /&gt;
&lt;br /&gt;
Lastly, it is probably undesirable in a kiosk-type session to allow the person to close the window on your laptops, thus making the machine useless for the next user. To block this, I added the following code:&lt;br /&gt;
&lt;br /&gt;
Add this to the script section of your mainscreen.html file (and any other page you want to stop the user from closing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will cause a micro-singularity to destroy the known universe, and I will get very upset. (At you closing the window, not the destruction of the universe, that can fend for itself.)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following lines to the function m_sessionLogout function of your main.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to force users to use both first and last names (useful if you use server heavily, since otherwise you will very quickly have name conflicts, at least in your history, if not in your tonights) you can use the following modified newsinger.html code. In addition, the new code puts instructions in the various fields, in particular that password field (since some people seem to have a hard time figuring out that what they have to do). For those interested, it was necessary to use a bit of a hack here. Normally the password field is encoded, so that when you type in characters, they get represented as &amp;quot;•&amp;quot; bullets (to prevent people from seeing the password being entered). But one consequence of this is that any text you put in the field to prompt users gets changed to bullets too.&lt;br /&gt;
So the code I added tricks the browser engine into thinking, just for a moment as it is being drawn, that it is NOT a password field (by actually making it a normal text field, and then, after the guide text is placed, changing it back to a password field, out from under the browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;meta http-equiv=Content-Type content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams New Singer&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function catname(){&lt;br /&gt;
				var firstname = document.forms[0].singerfirstname.value;&lt;br /&gt;
				var lastname = document.forms[0].singerlastname.value;&lt;br /&gt;
				document.forms[0].singername.value = firstname + &amp;quot; &amp;quot; + lastname;&lt;br /&gt;
			}&lt;br /&gt;
			function validate(thisform) {&lt;br /&gt;
				with (thisform){&lt;br /&gt;
					if (singerfirstname.value==&#039;&#039;) {&lt;br /&gt;
						alert(&#039;Hey, unless you\’re Obama, ya gotta give me a first name too. Try again.&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
					else if (singerlastname.value==&#039;Required!&#039;) {&lt;br /&gt;
						alert(&#039;What, you think you\’re Madonna? A last name is required. Lets try this again..&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
						//safe to navigate away from this page&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
						    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n:\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;New Singer&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
			&amp;lt;font color=&amp;quot;#FF0000&amp;quot;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onsubmit=&amp;quot;validate(this); allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;input type=&amp;quot;hidden&amp;quot; id=&amp;quot;singername&amp;quot; name=&amp;quot;singername&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;First Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerfirstname&amp;quot; value=&amp;quot;&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Last Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerlastname&amp;quot; value=&amp;quot;Required!&amp;quot; onfocus=&amp;quot;this.value= (this.value==&#039;Required!&#039;) ? &#039;&#039; : this.value&amp;quot; onBlur=&amp;quot;this.value= (this.value==&#039;&#039;) ? &#039;Required!&#039; : this.value&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot; id=&amp;quot;password&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var p = document.getElementById(&#039;password&#039;);&lt;br /&gt;
p.type = &#039;text&#039;;&lt;br /&gt;
p.value = &#039;Make a password&#039;;&lt;br /&gt;
p.onfocus = function() {&lt;br /&gt;
if (this.type == &#039;text&#039;) {&lt;br /&gt;
this.value = &#039;&#039;;&lt;br /&gt;
this.type = &#039;password&#039;;&lt;br /&gt;
this.focus();&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Again: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;confirm&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Jam Out!&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;p style=&amp;quot;font-size: 12pt;&amp;quot;&amp;gt;[ &amp;lt;a href=&amp;quot;/&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot;&amp;gt;Back&amp;lt;/a&amp;gt; ]&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_newsinger;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another recurring issue is that many people don&#039;t seem to understand the entire paradigm, and insist on adding themselves as a new singer every time they want to add a new song. To help prevent that, I added an extra confirmation step to try to get across the fact that this is not helpful. Try the modified login screen code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Login&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function iPhoneAlert() {&lt;br /&gt;
&lt;br /&gt;
				if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {&lt;br /&gt;
					var question = confirm(&amp;quot;You need iJams to log in!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
					if (question) {&lt;br /&gt;
						window.location = &amp;quot;http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301301004&amp;amp;mt=8&amp;quot;;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;iPhoneAlert();&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Singer Login&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onSubmit=&amp;quot;allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Singer: &amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;singers&amp;quot;&amp;gt;Please wait...&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Login&amp;quot; /&amp;gt; &amp;lt;input type=&amp;quot;button&amp;quot; onClick=&amp;quot;goNewSinger(); allowUnload=true;&amp;quot; value=&amp;quot;New Singer&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;div&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ]&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_main;&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			&lt;br /&gt;
			getSingers(url_singers, populateSingers);&lt;br /&gt;
			function populateSingers(singers) {&lt;br /&gt;
				var selectObj	= document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
				var optgroupObj	= document.createElement(&amp;quot;OPTGROUP&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				selectObj.name = &amp;quot;singer&amp;quot;;&lt;br /&gt;
				selectObj.style.width = &amp;quot;100%&amp;quot;;&lt;br /&gt;
				&lt;br /&gt;
				optgroupObj.label = &amp;quot;&amp;quot;;&lt;br /&gt;
				&lt;br /&gt;
				for (var i = 0; i &amp;lt; singers.length; i++) {&lt;br /&gt;
					if (singers[i][&#039;name&#039;][0].toUpperCase() != optgroupObj.label) {&lt;br /&gt;
						optgroupObj			= document.createElement(&amp;quot;OPTGROUP&amp;quot;);&lt;br /&gt;
						optgroupObj.label	= singers[i][&#039;name&#039;][0].toUpperCase();&lt;br /&gt;
						&lt;br /&gt;
						selectObj.appendChild(optgroupObj);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
					optionObj.value = singers[i][&#039;id&#039;];&lt;br /&gt;
					optionObj.innerHTML = singers[i][&#039;name&#039;];&lt;br /&gt;
					optgroupObj.appendChild(optionObj);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				document.getElementById(&amp;quot;singers&amp;quot;).innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
				document.getElementById(&amp;quot;singers&amp;quot;).appendChild(selectObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			function goNewSinger(){&lt;br /&gt;
			&lt;br /&gt;
				var newSingerConfirm=prompt(&amp;quot;HEY YOU.\n\nREAD THIS DIALOGUE BOX ALL THE WAY THROUGH!!!:\n\nOnly add yourself if you have never, EVER sung with me before. If you have EVER sung with me before, even if it was a two years ago, even if your name is not in the list, but you think it should be, PLEASE do not add yourself again. Instead, come see me to add your name to the system.  If you really ARE a new singer, however, type in the value of equation&amp;quot;,&amp;quot;2+3=?&amp;quot;);&lt;br /&gt;
				if (newSingerConfirm == &amp;quot;5&amp;quot;)&lt;br /&gt;
					{&lt;br /&gt;
					window.location=url_newsinger;&lt;br /&gt;
					}&lt;br /&gt;
				else&lt;br /&gt;
					{&lt;br /&gt;
					window.location=url_loginscreen;&lt;br /&gt;
					}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Feel free to modify the confirmation text as you see fit.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7994</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7994"/>
		<updated>2012-09-07T20:44:47Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into the javascript section of your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Bind key press function&lt;br /&gt;
	document.onkeyup = m_keyPressed;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;br /&gt;
&lt;br /&gt;
Lastly, it is probably undesirable in a kiosk-type session to allow the person to close the window on your laptops, thus making the machine useless for the next user. To block this, I added the following code:&lt;br /&gt;
&lt;br /&gt;
Add this to the script section of your mainscreen.html file (and any other page you want to stop the user from closing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will cause a micro-singularity to destroy the known universe, and I will get very upset. (At you closing the window, not the destruction of the universe, that can fend for itself.)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following lines to the function m_sessionLogout function of your main.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to force users to use both first and last names (useful if you use server heavily, since otherwise you will very quickly have name conflicts, at least in your history, if not in your tonights) you can use the following modified newsinger.html code. In addition, the new code puts instructions in the various fields, in particular that password field (since some people seem to have a hard time figuring out that what they have to do). For those interested, it was necessary to use a bit of a hack here. Normally the password field is encoded, so that when you type in characters, they get represented as &amp;quot;•&amp;quot; bullets (to prevent people from seeing the password being entered). But one consequence of this is that any text you put in the field to prompt users gets changed to bullets too.&lt;br /&gt;
So the code I added tricks the browser engine into thinking, just for a moment as it is being drawn, that it is NOT a password field (by actually making it a normal text field, and then, after the guide text is placed, changing it back to a password field, out from under the browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;meta http-equiv=Content-Type content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams New Singer&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function catname(){&lt;br /&gt;
				var firstname = document.forms[0].singerfirstname.value;&lt;br /&gt;
				var lastname = document.forms[0].singerlastname.value;&lt;br /&gt;
				document.forms[0].singername.value = firstname + &amp;quot; &amp;quot; + lastname;&lt;br /&gt;
			}&lt;br /&gt;
			function validate(thisform) {&lt;br /&gt;
				with (thisform){&lt;br /&gt;
					if (singerfirstname.value==&#039;&#039;) {&lt;br /&gt;
						alert(&#039;Hey, unless you\’re Obama, ya gotta give me a first name too. Try again.&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
					else if (singerlastname.value==&#039;Required!&#039;) {&lt;br /&gt;
						alert(&#039;What, you think you\’re Madonna? A last name is required. Lets try this again..&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
						//safe to navigate away from this page&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
						    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n:\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;New Singer&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
			&amp;lt;font color=&amp;quot;#FF0000&amp;quot;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onsubmit=&amp;quot;validate(this); allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;input type=&amp;quot;hidden&amp;quot; id=&amp;quot;singername&amp;quot; name=&amp;quot;singername&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;First Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerfirstname&amp;quot; value=&amp;quot;&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Last Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerlastname&amp;quot; value=&amp;quot;Required!&amp;quot; onfocus=&amp;quot;this.value= (this.value==&#039;Required!&#039;) ? &#039;&#039; : this.value&amp;quot; onBlur=&amp;quot;this.value= (this.value==&#039;&#039;) ? &#039;Required!&#039; : this.value&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot; id=&amp;quot;password&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var p = document.getElementById(&#039;password&#039;);&lt;br /&gt;
p.type = &#039;text&#039;;&lt;br /&gt;
p.value = &#039;Make a password&#039;;&lt;br /&gt;
p.onfocus = function() {&lt;br /&gt;
if (this.type == &#039;text&#039;) {&lt;br /&gt;
this.value = &#039;&#039;;&lt;br /&gt;
this.type = &#039;password&#039;;&lt;br /&gt;
this.focus();&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Again: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;confirm&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Jam Out!&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;p style=&amp;quot;font-size: 12pt;&amp;quot;&amp;gt;[ &amp;lt;a href=&amp;quot;/&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot;&amp;gt;Back&amp;lt;/a&amp;gt; ]&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_newsinger;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Another recurring issue is that many people don&#039;t seem to understand the entire paradigm, and insist on adding themselves as a new singer every time they want to add a new song. To help prevent that, I added an extra confirmation step to try to get across the fact that this is not helpful. Try the modified login screen code below:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Login&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function iPhoneAlert() {&lt;br /&gt;
&lt;br /&gt;
				if ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) {&lt;br /&gt;
					var question = confirm(&amp;quot;You need iJams to log in!&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
					if (question) {&lt;br /&gt;
						window.location = &amp;quot;http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=301301004&amp;amp;mt=8&amp;quot;;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;iPhoneAlert();&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Singer Login&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onSubmit=&amp;quot;allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Singer: &amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;singers&amp;quot;&amp;gt;Please wait...&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Login&amp;quot; /&amp;gt; &amp;lt;input type=&amp;quot;button&amp;quot; onClick=&amp;quot;goNewSinger(); allowUnload=true;&amp;quot; value=&amp;quot;New Singer&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;div&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ]&amp;lt;/div&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_main;&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			&lt;br /&gt;
			getSingers(url_singers, populateSingers);&lt;br /&gt;
			function populateSingers(singers) {&lt;br /&gt;
				var selectObj	= document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
				var optgroupObj	= document.createElement(&amp;quot;OPTGROUP&amp;quot;);&lt;br /&gt;
				&lt;br /&gt;
				selectObj.name = &amp;quot;singer&amp;quot;;&lt;br /&gt;
				selectObj.style.width = &amp;quot;100%&amp;quot;;&lt;br /&gt;
				&lt;br /&gt;
				optgroupObj.label = &amp;quot;&amp;quot;;&lt;br /&gt;
				&lt;br /&gt;
				for (var i = 0; i &amp;lt; singers.length; i++) {&lt;br /&gt;
					if (singers[i][&#039;name&#039;][0].toUpperCase() != optgroupObj.label) {&lt;br /&gt;
						optgroupObj			= document.createElement(&amp;quot;OPTGROUP&amp;quot;);&lt;br /&gt;
						optgroupObj.label	= singers[i][&#039;name&#039;][0].toUpperCase();&lt;br /&gt;
						&lt;br /&gt;
						selectObj.appendChild(optgroupObj);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
					optionObj.value = singers[i][&#039;id&#039;];&lt;br /&gt;
					optionObj.innerHTML = singers[i][&#039;name&#039;];&lt;br /&gt;
					optgroupObj.appendChild(optionObj);&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				document.getElementById(&amp;quot;singers&amp;quot;).innerHTML = &amp;quot;&amp;quot;;&lt;br /&gt;
				document.getElementById(&amp;quot;singers&amp;quot;).appendChild(selectObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			function goNewSinger(){&lt;br /&gt;
			&lt;br /&gt;
				var newSingerConfirm=prompt(&amp;quot;HEY YOU.\n\nREAD THIS DIALOGUE BOX ALL THE WAY THROUGH!!!:\n\nOnly add yourself if you have never, EVER sung with me before. If you have EVER sung with me before, even if it was a two years ago, even if your name is not in the list, but you think it should be, PLEASE do not add yourself again. Instead, come see me to add your name to the system.  If you really ARE a new singer, however, type in the value of equation&amp;quot;,&amp;quot;2+3=?&amp;quot;);&lt;br /&gt;
				if (newSingerConfirm == &amp;quot;5&amp;quot;)&lt;br /&gt;
					{&lt;br /&gt;
					window.location=url_newsinger;&lt;br /&gt;
					}&lt;br /&gt;
				else&lt;br /&gt;
					{&lt;br /&gt;
					window.location=url_loginscreen;&lt;br /&gt;
					}&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Feel free to modify the confirmation text as you see fit.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_Copy_Singers&amp;diff=7990</id>
		<title>Code/new Copy Singers</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_Copy_Singers&amp;diff=7990"/>
		<updated>2012-09-06T19:59:21Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;So with the advent of &amp;quot;Venues&amp;quot; you may have run into the situation where a singer from another venue shows up out of the blue at the current venue, wanting to see their history list. Accessing it is kinda a nightmare, involving going to the Finder, drilling down until you find the right singer folder, creating an alias, and then copying that alias over to the current venue folder, followed by changing venues in kJams, and then changing it back again in order to force kJams to reload the current venue&#039;s Singers folder.&lt;br /&gt;
&lt;br /&gt;
Well, I can&#039;t do anything about the kJams end of things, as that functionality is not currently exposed to an API like Applescript, but what I can do is automate the rest.&lt;br /&gt;
After a full 1/2 day of work (mostly since I am a lousy programmer!) I managed to get the following working. You have two choices on how to use this. You can open Applescript Editor and paste the following code into a new script window, and save as an application, and then run as you would any other application.&lt;br /&gt;
But better yet, open up Automator, select &amp;quot;Service&amp;quot; from the template choices on the opening splash screen, and then drag &amp;quot;Run AppleScript&amp;quot; from the Library onto the Stage. Change the &amp;quot;Service receives selected&amp;quot; popup to &amp;quot;no input&amp;quot;, and &amp;quot;applications&amp;quot; to &amp;quot;kJams&amp;quot;. (First choose &amp;quot;other…&amp;quot; from the popup menu, and then browse to kJams in the file selector.) Next, paste the following code over top of where is says &amp;quot;(* Your script goes here *)&amp;quot;, change the first line where it says &amp;quot;set kJamsPath to &amp;quot;Users/yourusername/Music/kJams/kJams Library/&amp;quot; by replacing &amp;quot;yourusername&amp;quot; with, oddly, you user name (use your short user name) and save.&lt;br /&gt;
&lt;br /&gt;
Then when you run kJams, and need this functionality, either run the application from where you saved it to, or if you saved it in automator as a service, simply select &amp;quot;Services&amp;quot; from the kJams menu, and then select your saved service.&lt;br /&gt;
At that point just follow the prompts to tell the service which singers you want to transfer (you can transfer multiple singers at the same time.) This will put an alias in your current venue folder, thus letting that singer access his or her playlists from either venue.&lt;br /&gt;
&lt;br /&gt;
If this is helpful, let me know [https://karaoke.kjams.com/forum/viewtopic.php?f=1&amp;amp;t=1406&amp;amp;sid=844b30850395dd5448ac2bf9a78a581c&amp;amp;p=7915#p7915 here].&lt;br /&gt;
&lt;br /&gt;
UPDATE:&lt;br /&gt;
Thanks to recent additions to the kJams code and its exposure to AppleScript, I was able to fully automate the code. Use the following code now to perform the entire act of copying the singers&#039; folders to the new venue AND actually making kJams recognize that the singers are in the new venue.&lt;br /&gt;
Proceed with a small amount of caution, however, as you are on the cutting edge here, and you might get a little blood on you! In particular, it appears to expose a bug that causes kJams to go slightly bonkers, and possibly lose the copied singers&#039; lists IF you already have an alias to the same singer(s) in that venue already. I am speculating that this is because you are trying to have multiple singers with the same ID, and kjams gets noticeably, and justifiably, upset. This should affect almost no one, and actually no one, if you don&#039;t mess around in your venues by hand and run this script hundreds of times, thus getting things royally confused in there, trying to test things out!&lt;br /&gt;
As always, let me know how it is working!&lt;br /&gt;
&lt;br /&gt;
P.S. as added goodness, in my testing, the new code NEVER caused server to fail to come back up due to an unreleased port!&lt;br /&gt;
P.P.S. If you totally love this, please feel free to [https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;amp;business=manifold_sky%yahoo%2ecom&amp;amp;item_name=kJams%20Video%20Backdrop%20Donation&amp;amp;no_shipping=2&amp;amp;no_note=1&amp;amp;currency_code=USD&amp;amp;lc=US&amp;amp;bn=PP%2dBuyNowBF&amp;amp;charset=UTF%2d8 paypal the author].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;iimg&amp;gt;https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;amp;business=manifold_sky%yahoo%2ecom&amp;amp;item_name=kJams%20Video%20Backdrop%20Donation&amp;amp;no_shipping=2&amp;amp;no_note=1&amp;amp;currency_code=USD&amp;amp;lc=US&amp;amp;bn=PP%2dBuyNowBF&amp;amp;charset=UTF%2d8&lt;br /&gt;
!http://kjams.com/resources/paypal.gif&amp;lt;/iimg&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
on run {input, parameters}&lt;br /&gt;
	&lt;br /&gt;
	set kJamsPath to &amp;quot;Users/yourusername/Music/kJams/kJams Library/&amp;quot; -- You need to edit this line to the path to YOUR kJams Library folder&lt;br /&gt;
	set kJamsLibraryPath to kJamsPath &amp;amp; &amp;quot;Library.xml&amp;quot;&lt;br /&gt;
	set XMLfile to (POSIX file (kJamsLibraryPath))&lt;br /&gt;
	set Paras to paragraphs of (read XMLfile)&lt;br /&gt;
	-- we cycle through the list and extract the portion between the tag we&#039;re interested in&lt;br /&gt;
	-- we know that the tag we want is immediately after &amp;quot;&amp;lt;key&amp;gt;Current Value&amp;lt;/key&amp;gt;&amp;quot;&lt;br /&gt;
	set tagValue to {}&lt;br /&gt;
	repeat with i from 1 to count of Paras&lt;br /&gt;
		if item i of Paras contains &amp;quot;Current Venue&amp;quot; then -- first we find the tag we&#039;re interested in&lt;br /&gt;
			set tagValue to item (i + 1) of Paras&lt;br /&gt;
			exit repeat&lt;br /&gt;
		end if&lt;br /&gt;
	end repeat&lt;br /&gt;
	-- return tagValue&lt;br /&gt;
	-- next we extract each value from the found tags knowing that the value is between &amp;quot;&amp;lt;string&amp;gt;&amp;quot; and &amp;quot;&amp;lt;/string&amp;gt;&lt;br /&gt;
	repeat with i from 1 to count of tagValue&lt;br /&gt;
		set thisTag to item i of tagValue&lt;br /&gt;
		set thisTagValue to &amp;quot;&amp;quot;&lt;br /&gt;
		if thisTag is &amp;quot;&amp;gt;&amp;quot; then&lt;br /&gt;
			repeat with k from (i + 1) to count of tagValue&lt;br /&gt;
				set thisTag to item k of tagValue&lt;br /&gt;
				if thisTag is &amp;quot;&amp;lt;&amp;quot; then exit repeat&lt;br /&gt;
				set thisTagValue to thisTagValue &amp;amp; thisTag&lt;br /&gt;
			end repeat&lt;br /&gt;
			exit repeat&lt;br /&gt;
		end if&lt;br /&gt;
	end repeat&lt;br /&gt;
	thisTagValue&lt;br /&gt;
	set kJamsPath to kJamsPath &amp;amp; &amp;quot;Venues/&amp;quot;&lt;br /&gt;
	set venuePath to (POSIX file (kJamsPath))&lt;br /&gt;
	set singerPath to (POSIX file (kJamsPath &amp;amp; thisTagValue &amp;amp; &amp;quot;/Singers&amp;quot;))&lt;br /&gt;
	set Singers to (choose folder default location alias venuePath with prompt &amp;quot;Choose singers to copy to the current venue&amp;quot; with multiple selections allowed) as list&lt;br /&gt;
	repeat with i from 1 to count of Singers&lt;br /&gt;
		tell application &amp;quot;Finder&amp;quot;&lt;br /&gt;
			set Singer to item i of Singers&lt;br /&gt;
			make new alias file at singerPath to Singer&lt;br /&gt;
		end tell&lt;br /&gt;
	end repeat&lt;br /&gt;
	set kScriptCommand_RESCAN_VENUE to 19&lt;br /&gt;
	tell application &amp;quot;kJams Pro&amp;quot;&lt;br /&gt;
		docommand kScriptCommand_RESCAN_VENUE&lt;br /&gt;
	end tell&lt;br /&gt;
	return input&lt;br /&gt;
end run&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7988</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7988"/>
		<updated>2012-09-04T06:10:43Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into the javascript section of your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Bind key press function&lt;br /&gt;
	document.onkeyup = m_keyPressed;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;br /&gt;
&lt;br /&gt;
Lastly, it is probably undesirable in a kiosk-type session to allow the person to close the window on your laptops, thus making the machine useless for the next user. To block this, I added the following code:&lt;br /&gt;
&lt;br /&gt;
Add this to the script section of your mainscreen.html file (and any other page you want to stop the user from closing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will cause a micro-singularity to destroy the known universe, and I will get very upset. (At you closing the window, not the destruction of the universe, that can fend for itself.)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following lines to the function m_sessionLogout function of your main.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you want to force users to use both first and last names (useful if you use server heavily, since otherwise you will very quickly have name conflicts, at least in your history, if not in your tonights) you can use the following modified newsinger.html code. In addition, the new code puts instructions in the various fields, in particular that password field (since some people seem to have a hard time figuring out that what they have to do). For those interested, it was necessary to use a bit of a hack here. Normally the password field is encoded, so that when you type in characters, they get represented as &amp;quot;•&amp;quot; bullets (to prevent people from seeing the password being entered). But one consequence of this is that any text you put in the field to prompt users gets changed to bullets too.&lt;br /&gt;
So the code I added tricks the browser engine into thinking, just for a moment as it is being drawn, that it is NOT a password field (by actually making it a normal text field, and then, after the guide text is placed, changing it back to a password field, out from under the browser.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;meta http-equiv=Content-Type content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams New Singer&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function catname(){&lt;br /&gt;
				var firstname = document.forms[0].singerfirstname.value;&lt;br /&gt;
				var lastname = document.forms[0].singerlastname.value;&lt;br /&gt;
				document.forms[0].singername.value = firstname + &amp;quot; &amp;quot; + lastname;&lt;br /&gt;
			}&lt;br /&gt;
			function validate(thisform) {&lt;br /&gt;
				with (thisform){&lt;br /&gt;
					if (singerfirstname.value==&#039;&#039;) {&lt;br /&gt;
						alert(&#039;Hey, unless you\’re Obama, ya gotta give me a first name too. Try again.&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
					else if (singerlastname.value==&#039;Required!&#039;) {&lt;br /&gt;
						alert(&#039;What, you think you\’re Madonna? A last name is required. Lets try this again..&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
						//safe to navigate away from this page&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
						    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n:\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;New Singer&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
			&amp;lt;font color=&amp;quot;#FF0000&amp;quot;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onsubmit=&amp;quot;validate(this); allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;input type=&amp;quot;hidden&amp;quot; id=&amp;quot;singername&amp;quot; name=&amp;quot;singername&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;First Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerfirstname&amp;quot; value=&amp;quot;&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Last Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerlastname&amp;quot; value=&amp;quot;Required!&amp;quot; onfocus=&amp;quot;this.value= (this.value==&#039;Required!&#039;) ? &#039;&#039; : this.value&amp;quot; onBlur=&amp;quot;this.value= (this.value==&#039;&#039;) ? &#039;Required!&#039; : this.value&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot; id=&amp;quot;password&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var p = document.getElementById(&#039;password&#039;);&lt;br /&gt;
p.type = &#039;text&#039;;&lt;br /&gt;
p.value = &#039;Make a password&#039;;&lt;br /&gt;
p.onfocus = function() {&lt;br /&gt;
if (this.type == &#039;text&#039;) {&lt;br /&gt;
this.value = &#039;&#039;;&lt;br /&gt;
this.type = &#039;password&#039;;&lt;br /&gt;
this.focus();&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Again: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;confirm&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Jam Out!&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;p style=&amp;quot;font-size: 12pt;&amp;quot;&amp;gt;[ &amp;lt;a href=&amp;quot;/&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot;&amp;gt;Back&amp;lt;/a&amp;gt; ]&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_newsinger;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7987</id>
		<title>Code/new kJams server pages with autologout</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7987"/>
		<updated>2012-09-04T03:50:41Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* = */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since the official autologout was removed, I have re-edited my mainscreen.html page to re-implement it. In addition, this versin traps the delete key, so instead of doing the rather annoying web standard &amp;quot;back a page&amp;quot; when the user hits the delete key, it does the MUCH more intuitive &amp;quot;remove the currently selected song from the active playlist.&amp;quot; There may be some other tweaks, but those are the highlights. Simply replace the server files with these:&lt;br /&gt;
&lt;br /&gt;
(As always, I hope someone finds this helpful, and consider sending me a P.M. letting me know what you think)&lt;br /&gt;
&lt;br /&gt;
main.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*	kJams Project - main.js&lt;br /&gt;
	Description: Main screen functionality.&lt;br /&gt;
	(c) 2007 kJams and David M. Cotter	*/&lt;br /&gt;
&lt;br /&gt;
var timer = null;&lt;br /&gt;
var lastPing = 0;&lt;br /&gt;
var allowBackspace = false;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populatePlaylists() {&lt;br /&gt;
	//Remove anything that was already there&lt;br /&gt;
	divObj = document.getElementById(&amp;quot;playlists&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; divObj.childNodes.length; i++) {&lt;br /&gt;
		divObj.removeChild(divObj.childNodes[i]);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	list = new KJDropList();&lt;br /&gt;
	list.create(divObj);&lt;br /&gt;
	playlistsList = list;&lt;br /&gt;
	&lt;br /&gt;
	getPlaylists(url_playlists, m_playlistsLoaded);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistsLoaded(list) {&lt;br /&gt;
	listCtrl = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			dropTarget = false;&lt;br /&gt;
		else&lt;br /&gt;
			dropTarget = true;&lt;br /&gt;
		&lt;br /&gt;
		listCtrl.addItem(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;], list[i][&#039;name&#039;], dropTarget, null, false);&lt;br /&gt;
		&lt;br /&gt;
		//Library and History items are not rearrangeable&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = false;&lt;br /&gt;
		else&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = true;&lt;br /&gt;
		&lt;br /&gt;
		//Keep track of ids for &#039;Tonight&#039; and &#039;Favorites&#039;&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			pTonightID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			pFavoritesID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//Store the playlist name in the DOM object&lt;br /&gt;
		document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).name = list[i][&#039;name&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	listCtrl.color();&lt;br /&gt;
	listCtrl.evtClick = m_populateSongs;&lt;br /&gt;
	listCtrl.evtDropInto = m_playlistDrop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populateSongs(playlist) {&lt;br /&gt;
	playlist = playlist.substring(1);&lt;br /&gt;
	&lt;br /&gt;
	//Hide&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlist != &amp;quot;1&amp;quot;) {&lt;br /&gt;
			songsList.destroy();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide &amp;quot;No Playlist&amp;quot; message, show waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//If the list is already loaded, simply display it&lt;br /&gt;
	if ((playlist == &amp;quot;1&amp;quot;) &amp;amp;&amp;amp; (songsLists[playlist] != undefined)) {&lt;br /&gt;
		songsList = songsLists[playlist];&lt;br /&gt;
		songsList.show();&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//If it&#039;s the library, request that user do a search first&lt;br /&gt;
	else if (playlist == &amp;quot;1&amp;quot;) {&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
		document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	else {&lt;br /&gt;
		//Playlist DOM object&lt;br /&gt;
		playlistObj = document.getElementById(&amp;quot;p&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		//Which columns are needed?&lt;br /&gt;
		var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		if (playlistObj.name == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Pitch&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (playlistObj.name == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		songsList = new KJList();&lt;br /&gt;
		songsList.rearrange = playlistObj.rearrange;&lt;br /&gt;
		songsList.playlist = playlist;&lt;br /&gt;
		songsList.playlistName = playlistObj.name;&lt;br /&gt;
		songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
		songsList.setColumns(columns, 0);&lt;br /&gt;
		songsList.evtDrop = m_songRearrange;&lt;br /&gt;
		songsLists[playlist] = songsList;&lt;br /&gt;
		getSongs(url_songs, m_songsLoaded, &amp;quot;playlist=&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		if (false) {&lt;br /&gt;
			songsList.evtColClick = null;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			songsList.evtColClick = m_sortSongs;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songsLoaded(list) {&lt;br /&gt;
	//Hide waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//Rearrangeable?&lt;br /&gt;
	if (songsList.rearrange)&lt;br /&gt;
		var rearrange = true;&lt;br /&gt;
	else&lt;br /&gt;
		var rearrange = false;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		//Add to favorites&lt;br /&gt;
		var favsButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		favsButton.type = &amp;quot;button&amp;quot;&lt;br /&gt;
		favsButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		favsButton.songId = list[i][&#039;id&#039;];&lt;br /&gt;
		favsButton.value = &amp;quot;Favorites&amp;quot;;&lt;br /&gt;
		favsButton.onmousedown = m_addToFavorites;&lt;br /&gt;
		&lt;br /&gt;
		//Add to Tonight&lt;br /&gt;
		var tonightButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		tonightButton.type = &amp;quot;button&amp;quot;;&lt;br /&gt;
		tonightButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		tonightButton.songId = list[i][&#039;id&#039;]; &lt;br /&gt;
		tonightButton.value = &amp;quot;Tonight&amp;quot;;&lt;br /&gt;
		tonightButton.onmousedown = m_addToTonight;&lt;br /&gt;
	&lt;br /&gt;
		//Columns&lt;br /&gt;
		var columns = Array(i, list[i][&#039;name&#039;], list[i][&#039;artist&#039;]);&lt;br /&gt;
		&lt;br /&gt;
		if (typeof(list[i][&#039;album&#039;]) == &amp;quot;object&amp;quot;) {&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;id&#039;];&lt;br /&gt;
			&lt;br /&gt;
			for (var j = 0; j &amp;lt; list[i][&#039;album&#039;][&#039;items&#039;].length; j++) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = list[i][&#039;album&#039;][&#039;items&#039;][j];&lt;br /&gt;
				optionObj.innerHTML = optionObj.value;&lt;br /&gt;
				&lt;br /&gt;
				if (list[i][&#039;album&#039;][&#039;default&#039;] == j) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(list[i][&#039;album&#039;]);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlistName == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			//Drop-down&lt;br /&gt;
			var options = {&amp;quot;+6&amp;quot; : 6, &amp;quot;+5&amp;quot; : 5, &amp;quot;+4&amp;quot; : 4, &amp;quot;+3&amp;quot; : 3, &amp;quot;+2&amp;quot; : 2, &amp;quot;+1&amp;quot; : 1, &amp;quot;0&amp;quot; : 0, &amp;quot;-1&amp;quot; : -1, &amp;quot;-2&amp;quot; : -2, &amp;quot;-3&amp;quot; : -3, &amp;quot;-4&amp;quot; : -4, &amp;quot;-5&amp;quot; : -5, &amp;quot;-6&amp;quot; : -6}&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;itemId&#039;];&lt;br /&gt;
			dropDown.songId = list[i][&#039;id&#039;];&lt;br /&gt;
			dropDown.onchange = m_changePitch;&lt;br /&gt;
			for (option in options) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = options[option];&lt;br /&gt;
				optionObj.innerHTML = option;&lt;br /&gt;
				&lt;br /&gt;
				if(list[i][&#039;pitch&#039;] == options[option]) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (songsList.playlistName == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		index = songsList.addItem(songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;], columns, rearrange, null, false);&lt;br /&gt;
		&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songName	= list[i][&#039;name&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songId		= list[i][&#039;id&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).piIx		= list[i][&#039;itemId&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	songsList.color();&lt;br /&gt;
	&lt;br /&gt;
	if (songsList.playlistName != &amp;quot;Tonight&amp;quot; &amp;amp;&amp;amp; songsList.playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
		songsList.evtColClick = m_sortSongs;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		songsList.evtColClick = null;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songRearrange(list, song, index, oldIndex) {&lt;br /&gt;
	sendData(url_rearrange, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;index=&amp;quot; + index + &amp;quot;&amp;amp;oldIndex=&amp;quot; + oldIndex);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistDrop(song, index, nodeId) {&lt;br /&gt;
	playlists	= document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	item		= songsList.getByID(song);&lt;br /&gt;
	&lt;br /&gt;
	if (songsLists[playlists.getByIndex(index).substring(1)]) { songsLists[playlists.getByIndex(index).substring(1)].destroy(); }&lt;br /&gt;
	songsLists[playlists.getByIndex(index).substring(1)] = null;&lt;br /&gt;
	sendData(url_drop, &amp;quot;playlist=&amp;quot; + playlists.getByIndex(index).substring(1) + &amp;quot;&amp;amp;song=&amp;quot; + songsList.getByID(song).songId);&lt;br /&gt;
	&lt;br /&gt;
	m_setStatus(&amp;quot;Added \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; to \&amp;quot;&amp;quot; + m_getPlaylistName(playlists.getByIndex(index)) + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToTonight(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pTonightID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToFavorites(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pFavoritesID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sortSongs(list, column) {&lt;br /&gt;
	list.removeAll();&lt;br /&gt;
	list.setPrimaryCol(column);&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	if (document.getElementById(&amp;quot;searchfield&amp;quot;).value) {&lt;br /&gt;
		search = &amp;quot;&amp;amp;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_sort, m_songsLoaded, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;orderby=&amp;quot; + column + search);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_changePitch(event) {&lt;br /&gt;
	sendData(url_pitch, &amp;quot;song=&amp;quot; + event.target.songId + &amp;quot;&amp;amp;pitch=&amp;quot; + event.target.value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_doSearch() {&lt;br /&gt;
	//Select &amp;quot;Library&amp;quot; in the side bar&lt;br /&gt;
	playlistsList.select(playlistsList.getByID(playlistsList.getByIndex(0)));&lt;br /&gt;
	&lt;br /&gt;
	//Remove old search list if it&#039;s there&lt;br /&gt;
	if (songsLists[&amp;quot;1&amp;quot;]) {&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].container);&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].columnsObj);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide currently loaded list&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
	var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	songsList = new KJList();&lt;br /&gt;
	songsList.rearrange = false;&lt;br /&gt;
	songsList.playlist = &amp;quot;1&amp;quot;;&lt;br /&gt;
	songsList.playlistName = &amp;quot;Library&amp;quot;;&lt;br /&gt;
	songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
	songsList.setColumns(columns, 1);&lt;br /&gt;
	songsLists[&amp;quot;1&amp;quot;] = songsList;&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_search, m_songsLoaded, &amp;quot;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function searchKeyPressed(event) {&lt;br /&gt;
	if (event.keyCode == 13) {&lt;br /&gt;
		m_doSearch();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getSongName(id) {&lt;br /&gt;
	songObj = document.getElementById(id);&lt;br /&gt;
	return songObj.songName;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getPlaylistName(id) {&lt;br /&gt;
	playlistObj = document.getElementById(id);&lt;br /&gt;
	return playlistObj.name;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function kj_data_error(id, desc) {&lt;br /&gt;
	songsLists[songsList.id] = null;&lt;br /&gt;
	songsList.hide();&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).innerHTML = &amp;quot;Error: &amp;quot; + desc&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 // If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else {&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
}&lt;br /&gt;
blinkFlag^=1;&lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_keyPressed(event) {&lt;br /&gt;
	//This is not IE-compliant code.&lt;br /&gt;
	if (event.keyCode == 46 || event.keyCode == 8) {&lt;br /&gt;
		if (!songsList.selection) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		playlistName	= songsList.playlistName;&lt;br /&gt;
&lt;br /&gt;
		if (playlistName != &amp;quot;Library&amp;quot; &amp;amp;&amp;amp; playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
			selection	= songsList.selection;&lt;br /&gt;
			item		= songsList.getByID(selection);&lt;br /&gt;
			&lt;br /&gt;
			songsList.select(null);&lt;br /&gt;
			sendData(url_remove, &amp;quot;playlist=&amp;quot; + songsList.playlist + &amp;quot;&amp;amp;piIx=&amp;quot; + item.piIx);&lt;br /&gt;
			m_setStatus(&amp;quot;Removed \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
			songsList.removeItem(selection);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_pingSession() {&lt;br /&gt;
	var elapsedTime = new Date().getTime()/1000.0 - lastPing;&lt;br /&gt;
	&lt;br /&gt;
	if (elapsedTime &amp;gt;= 5) {&lt;br /&gt;
		sendData(url_ping, &amp;quot;&amp;quot;);&lt;br /&gt;
		m_sessionCheckin();&lt;br /&gt;
		lastPing = new Date().getTime()/1000.0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionCheckin() {&lt;br /&gt;
	/* A true or false value is set by the server before delivering this script &lt;br /&gt;
		depending on preference. */&lt;br /&gt;
	if (!{auto_logout}) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (timer == null) {&lt;br /&gt;
		timer = setInterval(&amp;quot;m_sessionLogout()&amp;quot;, {timeout} * 1000);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		clearInterval(timer);&lt;br /&gt;
		timer = null;&lt;br /&gt;
		return m_sessionCheckin();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionLogout() {&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
	window.location=url_login;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
mainscreen.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;!--Singer: {singer}--&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Server&amp;lt;/title&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;ui.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;!--&lt;br /&gt;
			  			 var allowUnload = false;&lt;br /&gt;
			blinkSpeed=150;&lt;br /&gt;
			tagName=&amp;quot;blinker&amp;quot;;&lt;br /&gt;
			blinkerFlag=1;&lt;br /&gt;
			blinkElement=document.getElementsByName(tagName);&lt;br /&gt;
			blinkText();&lt;br /&gt;
&lt;br /&gt;
			function blinkText() {&lt;br /&gt;
				if (blinkerFlag== 1) {&lt;br /&gt;
					blinkState=&amp;quot;visible&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
				blinkState=&amp;quot;hidden&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				blinkerFlag ^=1;&lt;br /&gt;
&lt;br /&gt;
				for(i=0;i&amp;lt;blinkElement.length;i++) {&lt;br /&gt;
					blinkElement[i].style.visibility=blinkState;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				setTimeout(&amp;quot;blinkText()&amp;quot;, blinkSpeed);&lt;br /&gt;
			}&lt;br /&gt;
			--&amp;gt;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//variable to control if message is shown&lt;br /&gt;
  			 var allowUnload = false;&lt;br /&gt;
&lt;br /&gt;
  			// function triggered by any closing of the current document&lt;br /&gt;
			function confirmUnload(){&lt;br /&gt;
				if(!allowUnload){&lt;br /&gt;
					//message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
					return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this 							window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset (at you 							closing the window, not the A.I.D.S., that\&#039;s on you).\n :\&#039;(&#039;;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//register function with the event handler&lt;br /&gt;
			window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;screen.css&amp;quot; media=&amp;quot;screen&amp;quot;/&amp;gt; &lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;handheld.css&amp;quot; media=&amp;quot;handheld, only screen and (max-device-width:480px)&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;m_sessionCheckin()&amp;quot;; &amp;quot;loaded()&amp;quot; onmousemove=&amp;quot;m_pingSession()&amp;quot; onclick=&amp;quot;m_pingSession()&amp;quot; onkeypress=&amp;quot;m_pingSession()&amp;quot; onscroll=&amp;quot;m_pingSession()&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;{singer}&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;Search Library: &amp;lt;input type=&amp;quot;search&amp;quot; id=&amp;quot;searchfield&amp;quot; name=&amp;quot;search&amp;quot; onkeypress=searchKeyPressed(event) onblur=&amp;quot;inSearch.off()&amp;quot; onfocus=&amp;quot;inSearch.on()&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; style=&amp;quot;&amp;quot; name=&amp;quot;dosearch&amp;quot; value=&amp;quot;Go&amp;quot; onclick=m_doSearch() /&amp;gt;&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;help&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ] [ &amp;lt;a id=&amp;quot;logoutlink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt; ]&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
			&lt;br /&gt;
			&amp;lt;div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;playlists&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;kjams-main.jpg&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;wrapper&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;songs&amp;quot;&amp;gt;&amp;lt;p id=&amp;quot;msg_error&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;msg_dosearch&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;message&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;Type your search into the search field above and hit &amp;quot;Go&amp;quot;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;To submit a song, just click the &amp;quot;Tonight&amp;quot; button for that song in the search results. (You can also make your own &amp;quot;Favorties&amp;quot; list.)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;You will be informed at the bottom of the screen when you have successfully submitted a song.&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;waiting&amp;quot;&amp;gt;Please wait, loading search results… .&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;(This may take a while. &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;lt;a name=blinker&amp;gt;Please do NOT&amp;lt;/a&amp;gt; try another search until the first results are returned.)&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;status&amp;quot;&amp;gt;Welcome to kJams!&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//Bind key press function&lt;br /&gt;
			document.onkeyup = m_keyPressed;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			 document.onkeydown=trapDelete;&lt;br /&gt;
&lt;br /&gt;
			//Hide message fields&lt;br /&gt;
			document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			&lt;br /&gt;
			//Plug in help and logout URLs&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			document.getElementById(&amp;quot;logoutlink&amp;quot;).href = url_login;&lt;br /&gt;
			&lt;br /&gt;
			//Playlists&lt;br /&gt;
			m_populatePlaylists();&lt;br /&gt;
		&lt;br /&gt;
			if (0) {&lt;br /&gt;
				//Song list&lt;br /&gt;
				var songs = new KJList();&lt;br /&gt;
				songs.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
				songs.setColumns(Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Pitch&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;), 1);&lt;br /&gt;
				&lt;br /&gt;
				//Set clipping&lt;br /&gt;
				songs.setClipping({&#039;right&#039; : songs.getColumnWidth(5) + songs.getColumnWidth(4) + songs.getColumnWidth(3)});&lt;br /&gt;
				&lt;br /&gt;
				getSongs(url_songs, populateList, &#039;playlist=1&#039;);&lt;br /&gt;
				&lt;br /&gt;
				function populateList(songList) {&lt;br /&gt;
					for(var i = 0; i &amp;lt; songList.length; i++) {&lt;br /&gt;
						songs.addItem(songList[i][&#039;number&#039;], Array(songList[i][&#039;number&#039;], songList[i][&#039;name&#039;], songList[i][&#039;artist&#039;], &amp;quot;&amp;lt;select&amp;gt;&amp;lt;option&amp;gt;+6&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+5&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+1&amp;lt;/option&amp;gt;&amp;lt;option selected&amp;gt;0&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-1&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-5&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Tonight\&amp;quot; /&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Favorites\&amp;quot; /&amp;gt;&amp;quot;), null, null, false);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					songs.color();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7986</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7986"/>
		<updated>2012-09-04T03:48:06Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into the javascript section of your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Bind key press function&lt;br /&gt;
	document.onkeyup = m_keyPressed;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;br /&gt;
&lt;br /&gt;
Lastly, it is probably undesirable in a kiosk-type session to allow the person to close the window on your laptops, thus making the machine useless for the next user. To block this, I added the following code:&lt;br /&gt;
&lt;br /&gt;
Add this to the script section of your mainscreen.html file (and any other page you want to stop the user from closing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will cause a micro-singularity to destroy the known universe, and I will get very upset. (At you closing the window, not the destruction of the universe, that can fend for itself.)\n :\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then add the following lines to the function m_sessionLogout function of your main.js&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7985</id>
		<title>Code/new kJams server pages with autologout</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7985"/>
		<updated>2012-09-04T03:28:08Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since the official autologout was removed, I have re-edited my mainscreen.html page to re-implement it. In addition, this versin traps the delete key, so instead of doing the rather annoying web standard &amp;quot;back a page&amp;quot; when the user hits the delete key, it does the MUCH more intuitive &amp;quot;remove the currently selected song from the active playlist.&amp;quot; There may be some other tweaks, but those are the highlights. Simply replace the server files with these:&lt;br /&gt;
&lt;br /&gt;
(As always, I hope someone finds this helpful, and consider sending me a P.M. letting me know what you think)&lt;br /&gt;
&lt;br /&gt;
main.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*	kJams Project - main.js&lt;br /&gt;
	Description: Main screen functionality.&lt;br /&gt;
	(c) 2007 kJams and David M. Cotter	*/&lt;br /&gt;
&lt;br /&gt;
var timer = null;&lt;br /&gt;
var lastPing = 0;&lt;br /&gt;
var allowBackspace = false;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populatePlaylists() {&lt;br /&gt;
	//Remove anything that was already there&lt;br /&gt;
	divObj = document.getElementById(&amp;quot;playlists&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; divObj.childNodes.length; i++) {&lt;br /&gt;
		divObj.removeChild(divObj.childNodes[i]);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	list = new KJDropList();&lt;br /&gt;
	list.create(divObj);&lt;br /&gt;
	playlistsList = list;&lt;br /&gt;
	&lt;br /&gt;
	getPlaylists(url_playlists, m_playlistsLoaded);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistsLoaded(list) {&lt;br /&gt;
	listCtrl = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			dropTarget = false;&lt;br /&gt;
		else&lt;br /&gt;
			dropTarget = true;&lt;br /&gt;
		&lt;br /&gt;
		listCtrl.addItem(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;], list[i][&#039;name&#039;], dropTarget, null, false);&lt;br /&gt;
		&lt;br /&gt;
		//Library and History items are not rearrangeable&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = false;&lt;br /&gt;
		else&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = true;&lt;br /&gt;
		&lt;br /&gt;
		//Keep track of ids for &#039;Tonight&#039; and &#039;Favorites&#039;&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			pTonightID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			pFavoritesID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//Store the playlist name in the DOM object&lt;br /&gt;
		document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).name = list[i][&#039;name&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	listCtrl.color();&lt;br /&gt;
	listCtrl.evtClick = m_populateSongs;&lt;br /&gt;
	listCtrl.evtDropInto = m_playlistDrop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populateSongs(playlist) {&lt;br /&gt;
	playlist = playlist.substring(1);&lt;br /&gt;
	&lt;br /&gt;
	//Hide&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlist != &amp;quot;1&amp;quot;) {&lt;br /&gt;
			songsList.destroy();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide &amp;quot;No Playlist&amp;quot; message, show waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//If the list is already loaded, simply display it&lt;br /&gt;
	if ((playlist == &amp;quot;1&amp;quot;) &amp;amp;&amp;amp; (songsLists[playlist] != undefined)) {&lt;br /&gt;
		songsList = songsLists[playlist];&lt;br /&gt;
		songsList.show();&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//If it&#039;s the library, request that user do a search first&lt;br /&gt;
	else if (playlist == &amp;quot;1&amp;quot;) {&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
		document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	else {&lt;br /&gt;
		//Playlist DOM object&lt;br /&gt;
		playlistObj = document.getElementById(&amp;quot;p&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		//Which columns are needed?&lt;br /&gt;
		var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		if (playlistObj.name == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Pitch&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (playlistObj.name == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		songsList = new KJList();&lt;br /&gt;
		songsList.rearrange = playlistObj.rearrange;&lt;br /&gt;
		songsList.playlist = playlist;&lt;br /&gt;
		songsList.playlistName = playlistObj.name;&lt;br /&gt;
		songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
		songsList.setColumns(columns, 0);&lt;br /&gt;
		songsList.evtDrop = m_songRearrange;&lt;br /&gt;
		songsLists[playlist] = songsList;&lt;br /&gt;
		getSongs(url_songs, m_songsLoaded, &amp;quot;playlist=&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		if (false) {&lt;br /&gt;
			songsList.evtColClick = null;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			songsList.evtColClick = m_sortSongs;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songsLoaded(list) {&lt;br /&gt;
	//Hide waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//Rearrangeable?&lt;br /&gt;
	if (songsList.rearrange)&lt;br /&gt;
		var rearrange = true;&lt;br /&gt;
	else&lt;br /&gt;
		var rearrange = false;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		//Add to favorites&lt;br /&gt;
		var favsButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		favsButton.type = &amp;quot;button&amp;quot;&lt;br /&gt;
		favsButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		favsButton.songId = list[i][&#039;id&#039;];&lt;br /&gt;
		favsButton.value = &amp;quot;Favorites&amp;quot;;&lt;br /&gt;
		favsButton.onmousedown = m_addToFavorites;&lt;br /&gt;
		&lt;br /&gt;
		//Add to Tonight&lt;br /&gt;
		var tonightButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		tonightButton.type = &amp;quot;button&amp;quot;;&lt;br /&gt;
		tonightButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		tonightButton.songId = list[i][&#039;id&#039;]; &lt;br /&gt;
		tonightButton.value = &amp;quot;Tonight&amp;quot;;&lt;br /&gt;
		tonightButton.onmousedown = m_addToTonight;&lt;br /&gt;
	&lt;br /&gt;
		//Columns&lt;br /&gt;
		var columns = Array(i, list[i][&#039;name&#039;], list[i][&#039;artist&#039;]);&lt;br /&gt;
		&lt;br /&gt;
		if (typeof(list[i][&#039;album&#039;]) == &amp;quot;object&amp;quot;) {&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;id&#039;];&lt;br /&gt;
			&lt;br /&gt;
			for (var j = 0; j &amp;lt; list[i][&#039;album&#039;][&#039;items&#039;].length; j++) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = list[i][&#039;album&#039;][&#039;items&#039;][j];&lt;br /&gt;
				optionObj.innerHTML = optionObj.value;&lt;br /&gt;
				&lt;br /&gt;
				if (list[i][&#039;album&#039;][&#039;default&#039;] == j) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(list[i][&#039;album&#039;]);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlistName == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			//Drop-down&lt;br /&gt;
			var options = {&amp;quot;+6&amp;quot; : 6, &amp;quot;+5&amp;quot; : 5, &amp;quot;+4&amp;quot; : 4, &amp;quot;+3&amp;quot; : 3, &amp;quot;+2&amp;quot; : 2, &amp;quot;+1&amp;quot; : 1, &amp;quot;0&amp;quot; : 0, &amp;quot;-1&amp;quot; : -1, &amp;quot;-2&amp;quot; : -2, &amp;quot;-3&amp;quot; : -3, &amp;quot;-4&amp;quot; : -4, &amp;quot;-5&amp;quot; : -5, &amp;quot;-6&amp;quot; : -6}&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;itemId&#039;];&lt;br /&gt;
			dropDown.songId = list[i][&#039;id&#039;];&lt;br /&gt;
			dropDown.onchange = m_changePitch;&lt;br /&gt;
			for (option in options) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = options[option];&lt;br /&gt;
				optionObj.innerHTML = option;&lt;br /&gt;
				&lt;br /&gt;
				if(list[i][&#039;pitch&#039;] == options[option]) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (songsList.playlistName == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		index = songsList.addItem(songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;], columns, rearrange, null, false);&lt;br /&gt;
		&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songName	= list[i][&#039;name&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songId		= list[i][&#039;id&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).piIx		= list[i][&#039;itemId&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	songsList.color();&lt;br /&gt;
	&lt;br /&gt;
	if (songsList.playlistName != &amp;quot;Tonight&amp;quot; &amp;amp;&amp;amp; songsList.playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
		songsList.evtColClick = m_sortSongs;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		songsList.evtColClick = null;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songRearrange(list, song, index, oldIndex) {&lt;br /&gt;
	sendData(url_rearrange, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;index=&amp;quot; + index + &amp;quot;&amp;amp;oldIndex=&amp;quot; + oldIndex);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistDrop(song, index, nodeId) {&lt;br /&gt;
	playlists	= document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	item		= songsList.getByID(song);&lt;br /&gt;
	&lt;br /&gt;
	if (songsLists[playlists.getByIndex(index).substring(1)]) { songsLists[playlists.getByIndex(index).substring(1)].destroy(); }&lt;br /&gt;
	songsLists[playlists.getByIndex(index).substring(1)] = null;&lt;br /&gt;
	sendData(url_drop, &amp;quot;playlist=&amp;quot; + playlists.getByIndex(index).substring(1) + &amp;quot;&amp;amp;song=&amp;quot; + songsList.getByID(song).songId);&lt;br /&gt;
	&lt;br /&gt;
	m_setStatus(&amp;quot;Added \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; to \&amp;quot;&amp;quot; + m_getPlaylistName(playlists.getByIndex(index)) + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToTonight(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pTonightID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToFavorites(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pFavoritesID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sortSongs(list, column) {&lt;br /&gt;
	list.removeAll();&lt;br /&gt;
	list.setPrimaryCol(column);&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	if (document.getElementById(&amp;quot;searchfield&amp;quot;).value) {&lt;br /&gt;
		search = &amp;quot;&amp;amp;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_sort, m_songsLoaded, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;orderby=&amp;quot; + column + search);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_changePitch(event) {&lt;br /&gt;
	sendData(url_pitch, &amp;quot;song=&amp;quot; + event.target.songId + &amp;quot;&amp;amp;pitch=&amp;quot; + event.target.value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_doSearch() {&lt;br /&gt;
	//Select &amp;quot;Library&amp;quot; in the side bar&lt;br /&gt;
	playlistsList.select(playlistsList.getByID(playlistsList.getByIndex(0)));&lt;br /&gt;
	&lt;br /&gt;
	//Remove old search list if it&#039;s there&lt;br /&gt;
	if (songsLists[&amp;quot;1&amp;quot;]) {&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].container);&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].columnsObj);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide currently loaded list&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
	var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	songsList = new KJList();&lt;br /&gt;
	songsList.rearrange = false;&lt;br /&gt;
	songsList.playlist = &amp;quot;1&amp;quot;;&lt;br /&gt;
	songsList.playlistName = &amp;quot;Library&amp;quot;;&lt;br /&gt;
	songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
	songsList.setColumns(columns, 1);&lt;br /&gt;
	songsLists[&amp;quot;1&amp;quot;] = songsList;&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_search, m_songsLoaded, &amp;quot;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function searchKeyPressed(event) {&lt;br /&gt;
	if (event.keyCode == 13) {&lt;br /&gt;
		m_doSearch();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getSongName(id) {&lt;br /&gt;
	songObj = document.getElementById(id);&lt;br /&gt;
	return songObj.songName;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getPlaylistName(id) {&lt;br /&gt;
	playlistObj = document.getElementById(id);&lt;br /&gt;
	return playlistObj.name;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function kj_data_error(id, desc) {&lt;br /&gt;
	songsLists[songsList.id] = null;&lt;br /&gt;
	songsList.hide();&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).innerHTML = &amp;quot;Error: &amp;quot; + desc&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 // If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else {&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
}&lt;br /&gt;
blinkFlag^=1;&lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_keyPressed(event) {&lt;br /&gt;
	//This is not IE-compliant code.&lt;br /&gt;
	if (event.keyCode == 46 || event.keyCode == 8) {&lt;br /&gt;
		if (!songsList.selection) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		playlistName	= songsList.playlistName;&lt;br /&gt;
&lt;br /&gt;
		if (playlistName != &amp;quot;Library&amp;quot; &amp;amp;&amp;amp; playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
			selection	= songsList.selection;&lt;br /&gt;
			item		= songsList.getByID(selection);&lt;br /&gt;
			&lt;br /&gt;
			songsList.select(null);&lt;br /&gt;
			sendData(url_remove, &amp;quot;playlist=&amp;quot; + songsList.playlist + &amp;quot;&amp;amp;piIx=&amp;quot; + item.piIx);&lt;br /&gt;
			m_setStatus(&amp;quot;Removed \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
			songsList.removeItem(selection);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_pingSession() {&lt;br /&gt;
	var elapsedTime = new Date().getTime()/1000.0 - lastPing;&lt;br /&gt;
	&lt;br /&gt;
	if (elapsedTime &amp;gt;= 5) {&lt;br /&gt;
		sendData(url_ping, &amp;quot;&amp;quot;);&lt;br /&gt;
		m_sessionCheckin();&lt;br /&gt;
		lastPing = new Date().getTime()/1000.0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionCheckin() {&lt;br /&gt;
	/* A true or false value is set by the server before delivering this script &lt;br /&gt;
		depending on preference. */&lt;br /&gt;
	if (!{auto_logout}) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (timer == null) {&lt;br /&gt;
		timer = setInterval(&amp;quot;m_sessionLogout()&amp;quot;, {timeout} * 1000);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		clearInterval(timer);&lt;br /&gt;
		timer = null;&lt;br /&gt;
		return m_sessionCheckin();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionLogout() {&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
	window.location=url_login;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
mainscreen.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;!--Singer: {singer}--&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Server&amp;lt;/title&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;ui.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;blockUnload.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;!--&lt;br /&gt;
			  			 var allowUnload = false;&lt;br /&gt;
			blinkSpeed=150;&lt;br /&gt;
			tagName=&amp;quot;blinker&amp;quot;;&lt;br /&gt;
			blinkerFlag=1;&lt;br /&gt;
			blinkElement=document.getElementsByName(tagName);&lt;br /&gt;
			blinkText();&lt;br /&gt;
&lt;br /&gt;
			function blinkText() {&lt;br /&gt;
				if (blinkerFlag== 1) {&lt;br /&gt;
					blinkState=&amp;quot;visible&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
				blinkState=&amp;quot;hidden&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				blinkerFlag ^=1;&lt;br /&gt;
&lt;br /&gt;
				for(i=0;i&amp;lt;blinkElement.length;i++) {&lt;br /&gt;
					blinkElement[i].style.visibility=blinkState;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				setTimeout(&amp;quot;blinkText()&amp;quot;, blinkSpeed);&lt;br /&gt;
			}&lt;br /&gt;
			--&amp;gt;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//variable to control if message is shown&lt;br /&gt;
  			 var allowUnload = false;&lt;br /&gt;
&lt;br /&gt;
  			// function triggered by any closing of the current document&lt;br /&gt;
			function confirmUnload(){&lt;br /&gt;
				if(!allowUnload){&lt;br /&gt;
					//message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
					return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this 							window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset (at you 							closing the window, not the A.I.D.S., that\&#039;s on you).\n :\&#039;(&#039;;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//register function with the event handler&lt;br /&gt;
			window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;screen.css&amp;quot; media=&amp;quot;screen&amp;quot;/&amp;gt; &lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;handheld.css&amp;quot; media=&amp;quot;handheld, only screen and (max-device-width:480px)&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;m_sessionCheckin()&amp;quot;; &amp;quot;loaded()&amp;quot; onmousemove=&amp;quot;m_pingSession()&amp;quot; onclick=&amp;quot;m_pingSession()&amp;quot; onkeypress=&amp;quot;m_pingSession()&amp;quot; onscroll=&amp;quot;m_pingSession()&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;{singer}&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;Search Library: &amp;lt;input type=&amp;quot;search&amp;quot; id=&amp;quot;searchfield&amp;quot; name=&amp;quot;search&amp;quot; onkeypress=searchKeyPressed(event) onblur=&amp;quot;inSearch.off()&amp;quot; onfocus=&amp;quot;inSearch.on()&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; style=&amp;quot;&amp;quot; name=&amp;quot;dosearch&amp;quot; value=&amp;quot;Go&amp;quot; onclick=m_doSearch() /&amp;gt;&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;help&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ] [ &amp;lt;a id=&amp;quot;logoutlink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt; ]&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
			&lt;br /&gt;
			&amp;lt;div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;playlists&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;kjams-main.jpg&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;wrapper&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;songs&amp;quot;&amp;gt;&amp;lt;p id=&amp;quot;msg_error&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;msg_dosearch&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;message&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;Type your search into the search field above and hit &amp;quot;Go&amp;quot;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;To submit a song, just click the &amp;quot;Tonight&amp;quot; button for that song in the search results. (You can also make your own &amp;quot;Favorties&amp;quot; list.)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;You will be informed at the bottom of the screen when you have successfully submitted a song.&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;waiting&amp;quot;&amp;gt;Please wait, loading search results… .&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;(This may take a while. &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;lt;a name=blinker&amp;gt;Please do NOT&amp;lt;/a&amp;gt; try another search until the first results are returned.)&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;status&amp;quot;&amp;gt;Welcome to kJams!&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//Bind key press function&lt;br /&gt;
			document.onkeyup = m_keyPressed;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			 document.onkeydown=trapDelete;&lt;br /&gt;
&lt;br /&gt;
			//Hide message fields&lt;br /&gt;
			document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			&lt;br /&gt;
			//Plug in help and logout URLs&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			document.getElementById(&amp;quot;logoutlink&amp;quot;).href = url_login;&lt;br /&gt;
			&lt;br /&gt;
			//Playlists&lt;br /&gt;
			m_populatePlaylists();&lt;br /&gt;
		&lt;br /&gt;
			if (0) {&lt;br /&gt;
				//Song list&lt;br /&gt;
				var songs = new KJList();&lt;br /&gt;
				songs.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
				songs.setColumns(Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Pitch&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;), 1);&lt;br /&gt;
				&lt;br /&gt;
				//Set clipping&lt;br /&gt;
				songs.setClipping({&#039;right&#039; : songs.getColumnWidth(5) + songs.getColumnWidth(4) + songs.getColumnWidth(3)});&lt;br /&gt;
				&lt;br /&gt;
				getSongs(url_songs, populateList, &#039;playlist=1&#039;);&lt;br /&gt;
				&lt;br /&gt;
				function populateList(songList) {&lt;br /&gt;
					for(var i = 0; i &amp;lt; songList.length; i++) {&lt;br /&gt;
						songs.addItem(songList[i][&#039;number&#039;], Array(songList[i][&#039;number&#039;], songList[i][&#039;name&#039;], songList[i][&#039;artist&#039;], &amp;quot;&amp;lt;select&amp;gt;&amp;lt;option&amp;gt;+6&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+5&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+1&amp;lt;/option&amp;gt;&amp;lt;option selected&amp;gt;0&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-1&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-5&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Tonight\&amp;quot; /&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Favorites\&amp;quot; /&amp;gt;&amp;quot;), null, null, false);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					songs.color();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7984</id>
		<title>Code/new kJams server pages with autologout</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Code/new_kJams_server_pages_with_autologout&amp;diff=7984"/>
		<updated>2012-09-04T03:25:15Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since the official autologout was removed, I have re-edited my mainscreen.html page to re-implement it. In addition, this versin traps the delete key, so instead of doing the rather annoying web standard &amp;quot;back a page&amp;quot; when the user hits the delete key, it does the MUCH more intuitive &amp;quot;remove the currently selected song from the active playlist.&amp;quot; There may be some other tweaks, but those are the highlights. Simply replace the server files with these:&lt;br /&gt;
&lt;br /&gt;
(As always, I hope someone finds this helpful, and consider sending me a P.M. letting me know what you think)&lt;br /&gt;
&lt;br /&gt;
main.js:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*	kJams Project - main.js&lt;br /&gt;
	Description: Main screen functionality.&lt;br /&gt;
	(c) 2007 kJams and David M. Cotter	*/&lt;br /&gt;
&lt;br /&gt;
var timer = null;&lt;br /&gt;
var lastPing = 0;&lt;br /&gt;
var allowBackspace = false;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populatePlaylists() {&lt;br /&gt;
	//Remove anything that was already there&lt;br /&gt;
	divObj = document.getElementById(&amp;quot;playlists&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; divObj.childNodes.length; i++) {&lt;br /&gt;
		divObj.removeChild(divObj.childNodes[i]);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	list = new KJDropList();&lt;br /&gt;
	list.create(divObj);&lt;br /&gt;
	playlistsList = list;&lt;br /&gt;
	&lt;br /&gt;
	getPlaylists(url_playlists, m_playlistsLoaded);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistsLoaded(list) {&lt;br /&gt;
	listCtrl = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			dropTarget = false;&lt;br /&gt;
		else&lt;br /&gt;
			dropTarget = true;&lt;br /&gt;
		&lt;br /&gt;
		listCtrl.addItem(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;], list[i][&#039;name&#039;], dropTarget, null, false);&lt;br /&gt;
		&lt;br /&gt;
		//Library and History items are not rearrangeable&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = false;&lt;br /&gt;
		else&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = true;&lt;br /&gt;
		&lt;br /&gt;
		//Keep track of ids for &#039;Tonight&#039; and &#039;Favorites&#039;&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			pTonightID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			pFavoritesID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//Store the playlist name in the DOM object&lt;br /&gt;
		document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).name = list[i][&#039;name&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	listCtrl.color();&lt;br /&gt;
	listCtrl.evtClick = m_populateSongs;&lt;br /&gt;
	listCtrl.evtDropInto = m_playlistDrop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populateSongs(playlist) {&lt;br /&gt;
	playlist = playlist.substring(1);&lt;br /&gt;
	&lt;br /&gt;
	//Hide&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlist != &amp;quot;1&amp;quot;) {&lt;br /&gt;
			songsList.destroy();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide &amp;quot;No Playlist&amp;quot; message, show waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//If the list is already loaded, simply display it&lt;br /&gt;
	if ((playlist == &amp;quot;1&amp;quot;) &amp;amp;&amp;amp; (songsLists[playlist] != undefined)) {&lt;br /&gt;
		songsList = songsLists[playlist];&lt;br /&gt;
		songsList.show();&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//If it&#039;s the library, request that user do a search first&lt;br /&gt;
	else if (playlist == &amp;quot;1&amp;quot;) {&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
		document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	else {&lt;br /&gt;
		//Playlist DOM object&lt;br /&gt;
		playlistObj = document.getElementById(&amp;quot;p&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		//Which columns are needed?&lt;br /&gt;
		var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		if (playlistObj.name == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Pitch&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (playlistObj.name == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		songsList = new KJList();&lt;br /&gt;
		songsList.rearrange = playlistObj.rearrange;&lt;br /&gt;
		songsList.playlist = playlist;&lt;br /&gt;
		songsList.playlistName = playlistObj.name;&lt;br /&gt;
		songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
		songsList.setColumns(columns, 0);&lt;br /&gt;
		songsList.evtDrop = m_songRearrange;&lt;br /&gt;
		songsLists[playlist] = songsList;&lt;br /&gt;
		getSongs(url_songs, m_songsLoaded, &amp;quot;playlist=&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		if (false) {&lt;br /&gt;
			songsList.evtColClick = null;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			songsList.evtColClick = m_sortSongs;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songsLoaded(list) {&lt;br /&gt;
	//Hide waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//Rearrangeable?&lt;br /&gt;
	if (songsList.rearrange)&lt;br /&gt;
		var rearrange = true;&lt;br /&gt;
	else&lt;br /&gt;
		var rearrange = false;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		//Add to favorites&lt;br /&gt;
		var favsButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		favsButton.type = &amp;quot;button&amp;quot;&lt;br /&gt;
		favsButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		favsButton.songId = list[i][&#039;id&#039;];&lt;br /&gt;
		favsButton.value = &amp;quot;Favorites&amp;quot;;&lt;br /&gt;
		favsButton.onmousedown = m_addToFavorites;&lt;br /&gt;
		&lt;br /&gt;
		//Add to Tonight&lt;br /&gt;
		var tonightButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		tonightButton.type = &amp;quot;button&amp;quot;;&lt;br /&gt;
		tonightButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		tonightButton.songId = list[i][&#039;id&#039;]; &lt;br /&gt;
		tonightButton.value = &amp;quot;Tonight&amp;quot;;&lt;br /&gt;
		tonightButton.onmousedown = m_addToTonight;&lt;br /&gt;
	&lt;br /&gt;
		//Columns&lt;br /&gt;
		var columns = Array(i, list[i][&#039;name&#039;], list[i][&#039;artist&#039;]);&lt;br /&gt;
		&lt;br /&gt;
		if (typeof(list[i][&#039;album&#039;]) == &amp;quot;object&amp;quot;) {&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;id&#039;];&lt;br /&gt;
			&lt;br /&gt;
			for (var j = 0; j &amp;lt; list[i][&#039;album&#039;][&#039;items&#039;].length; j++) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = list[i][&#039;album&#039;][&#039;items&#039;][j];&lt;br /&gt;
				optionObj.innerHTML = optionObj.value;&lt;br /&gt;
				&lt;br /&gt;
				if (list[i][&#039;album&#039;][&#039;default&#039;] == j) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(list[i][&#039;album&#039;]);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlistName == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			//Drop-down&lt;br /&gt;
			var options = {&amp;quot;+6&amp;quot; : 6, &amp;quot;+5&amp;quot; : 5, &amp;quot;+4&amp;quot; : 4, &amp;quot;+3&amp;quot; : 3, &amp;quot;+2&amp;quot; : 2, &amp;quot;+1&amp;quot; : 1, &amp;quot;0&amp;quot; : 0, &amp;quot;-1&amp;quot; : -1, &amp;quot;-2&amp;quot; : -2, &amp;quot;-3&amp;quot; : -3, &amp;quot;-4&amp;quot; : -4, &amp;quot;-5&amp;quot; : -5, &amp;quot;-6&amp;quot; : -6}&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;itemId&#039;];&lt;br /&gt;
			dropDown.songId = list[i][&#039;id&#039;];&lt;br /&gt;
			dropDown.onchange = m_changePitch;&lt;br /&gt;
			for (option in options) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = options[option];&lt;br /&gt;
				optionObj.innerHTML = option;&lt;br /&gt;
				&lt;br /&gt;
				if(list[i][&#039;pitch&#039;] == options[option]) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (songsList.playlistName == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		index = songsList.addItem(songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;], columns, rearrange, null, false);&lt;br /&gt;
		&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songName	= list[i][&#039;name&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songId		= list[i][&#039;id&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).piIx		= list[i][&#039;itemId&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	songsList.color();&lt;br /&gt;
	&lt;br /&gt;
	if (songsList.playlistName != &amp;quot;Tonight&amp;quot; &amp;amp;&amp;amp; songsList.playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
		songsList.evtColClick = m_sortSongs;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		songsList.evtColClick = null;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songRearrange(list, song, index, oldIndex) {&lt;br /&gt;
	sendData(url_rearrange, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;index=&amp;quot; + index + &amp;quot;&amp;amp;oldIndex=&amp;quot; + oldIndex);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistDrop(song, index, nodeId) {&lt;br /&gt;
	playlists	= document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	item		= songsList.getByID(song);&lt;br /&gt;
	&lt;br /&gt;
	if (songsLists[playlists.getByIndex(index).substring(1)]) { songsLists[playlists.getByIndex(index).substring(1)].destroy(); }&lt;br /&gt;
	songsLists[playlists.getByIndex(index).substring(1)] = null;&lt;br /&gt;
	sendData(url_drop, &amp;quot;playlist=&amp;quot; + playlists.getByIndex(index).substring(1) + &amp;quot;&amp;amp;song=&amp;quot; + songsList.getByID(song).songId);&lt;br /&gt;
	&lt;br /&gt;
	m_setStatus(&amp;quot;Added \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; to \&amp;quot;&amp;quot; + m_getPlaylistName(playlists.getByIndex(index)) + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToTonight(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pTonightID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToFavorites(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pFavoritesID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sortSongs(list, column) {&lt;br /&gt;
	list.removeAll();&lt;br /&gt;
	list.setPrimaryCol(column);&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	if (document.getElementById(&amp;quot;searchfield&amp;quot;).value) {&lt;br /&gt;
		search = &amp;quot;&amp;amp;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_sort, m_songsLoaded, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;orderby=&amp;quot; + column + search);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_changePitch(event) {&lt;br /&gt;
	sendData(url_pitch, &amp;quot;song=&amp;quot; + event.target.songId + &amp;quot;&amp;amp;pitch=&amp;quot; + event.target.value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_doSearch() {&lt;br /&gt;
	//Select &amp;quot;Library&amp;quot; in the side bar&lt;br /&gt;
	playlistsList.select(playlistsList.getByID(playlistsList.getByIndex(0)));&lt;br /&gt;
	&lt;br /&gt;
	//Remove old search list if it&#039;s there&lt;br /&gt;
	if (songsLists[&amp;quot;1&amp;quot;]) {&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].container);&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].columnsObj);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide currently loaded list&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
	var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	songsList = new KJList();&lt;br /&gt;
	songsList.rearrange = false;&lt;br /&gt;
	songsList.playlist = &amp;quot;1&amp;quot;;&lt;br /&gt;
	songsList.playlistName = &amp;quot;Library&amp;quot;;&lt;br /&gt;
	songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
	songsList.setColumns(columns, 1);&lt;br /&gt;
	songsLists[&amp;quot;1&amp;quot;] = songsList;&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_search, m_songsLoaded, &amp;quot;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function searchKeyPressed(event) {&lt;br /&gt;
	if (event.keyCode == 13) {&lt;br /&gt;
		m_doSearch();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getSongName(id) {&lt;br /&gt;
	songObj = document.getElementById(id);&lt;br /&gt;
	return songObj.songName;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getPlaylistName(id) {&lt;br /&gt;
	playlistObj = document.getElementById(id);&lt;br /&gt;
	return playlistObj.name;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function kj_data_error(id, desc) {&lt;br /&gt;
	songsLists[songsList.id] = null;&lt;br /&gt;
	songsList.hide();&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).innerHTML = &amp;quot;Error: &amp;quot; + desc&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 // If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else {&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
}&lt;br /&gt;
blinkFlag^=1;&lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_keyPressed(event) {&lt;br /&gt;
	//This is not IE-compliant code.&lt;br /&gt;
	if (event.keyCode == 46 || event.keyCode == 8) {&lt;br /&gt;
		if (!songsList.selection) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		playlistName	= songsList.playlistName;&lt;br /&gt;
&lt;br /&gt;
		if (playlistName != &amp;quot;Library&amp;quot; &amp;amp;&amp;amp; playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
			selection	= songsList.selection;&lt;br /&gt;
			item		= songsList.getByID(selection);&lt;br /&gt;
			&lt;br /&gt;
			songsList.select(null);&lt;br /&gt;
			sendData(url_remove, &amp;quot;playlist=&amp;quot; + songsList.playlist + &amp;quot;&amp;amp;piIx=&amp;quot; + item.piIx);&lt;br /&gt;
			m_setStatus(&amp;quot;Removed \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
			songsList.removeItem(selection);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_pingSession() {&lt;br /&gt;
	var elapsedTime = new Date().getTime()/1000.0 - lastPing;&lt;br /&gt;
	&lt;br /&gt;
	if (elapsedTime &amp;gt;= 5) {&lt;br /&gt;
		sendData(url_ping, &amp;quot;&amp;quot;);&lt;br /&gt;
		m_sessionCheckin();&lt;br /&gt;
		lastPing = new Date().getTime()/1000.0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionCheckin() {&lt;br /&gt;
	/* A true or false value is set by the server before delivering this script &lt;br /&gt;
		depending on preference. */&lt;br /&gt;
	if (!{auto_logout}) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (timer == null) {&lt;br /&gt;
		timer = setInterval(&amp;quot;m_sessionLogout()&amp;quot;, {timeout} * 1000);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		clearInterval(timer);&lt;br /&gt;
		timer = null;&lt;br /&gt;
		return m_sessionCheckin();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionLogout() {&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
	window.location=url_login;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=================================================================================================================================================&lt;br /&gt;
&lt;br /&gt;
mainscreen.html&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt; &lt;br /&gt;
	&amp;lt;head&amp;gt; &lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Server&amp;lt;/title&amp;gt; &lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script src=&amp;quot;ui.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt; &lt;br /&gt;
			var timer = 0;&lt;br /&gt;
			function set_interval() {&lt;br /&gt;
				//the interval &#039;timer&#039; is set as soon as the page loads&lt;br /&gt;
				timer=setInterval(&amp;quot;auto_logout()&amp;quot;,120000);&lt;br /&gt;
				// the figure &#039;120000&#039; above indicates how many milliseconds the timer be set to.&lt;br /&gt;
				//Eg: to set it to 2 mins, calculate 2min= 2x60=120 sec = 120,000 millisec. So set it to 120000&lt;br /&gt;
			}&lt;br /&gt;
			function reset_interval() {&lt;br /&gt;
				//resets the timer. The timer is reset on each of the below events:&lt;br /&gt;
				// 1. mousemove   2. mouseclick   3. key press 4. scroliing&lt;br /&gt;
				//first step: clear the existing timer&lt;br /&gt;
				if (timer != 0) {&lt;br /&gt;
					clearInterval(timer);&lt;br /&gt;
					timer = 0;&lt;br /&gt;
				}&lt;br /&gt;
				//second step: implement the timer again&lt;br /&gt;
				timer=setInterval(&amp;quot;auto_logout()&amp;quot;,120000);&lt;br /&gt;
				//completed the reset of the timer&lt;br /&gt;
			}&lt;br /&gt;
 &lt;br /&gt;
			function auto_logout() {&lt;br /&gt;
				//this function will redirect the user to the logout script&lt;br /&gt;
				window.location=logoutlink;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt; &lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt; &lt;br /&gt;
			#main {&lt;br /&gt;
				padding: 10px;&lt;br /&gt;
				margin-right: 20px;&lt;br /&gt;
				margin-left: 20px;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				cursor: default;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#title {&lt;br /&gt;
				padding-right: 30px;&lt;br /&gt;
				text-align: left;&lt;br /&gt;
				font-family: Arial Black;&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
				font-weight: bold;&lt;br /&gt;
				margin-bottom: 5px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#search {&lt;br /&gt;
				width: 100%;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#searchfield {&lt;br /&gt;
				height: 21px;&lt;br /&gt;
				width: 144px;&lt;br /&gt;
				background: url(&#039;search.png&#039;);&lt;br /&gt;
				border-width: 0px;&lt;br /&gt;
				padding-left: 7px;&lt;br /&gt;
				padding-right: 7px;&lt;br /&gt;
				padding-top: 2px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#left {&lt;br /&gt;
				float: left;&lt;br /&gt;
				width: 200px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
				margin-left: 0px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#status {&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				color: #333333;&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJList {&lt;br /&gt;
				overflow: auto;&lt;br /&gt;
				height: 240px;&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				background-color: #FFFFFF;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #999999;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJList td {&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJList table {&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#photo {&lt;br /&gt;
				padding: 3px;&lt;br /&gt;
				width: 190px;&lt;br /&gt;
				height: 143px;&lt;br /&gt;
				max-height: 150px;&lt;br /&gt;
				overflow: hidden;&lt;br /&gt;
				margin-top: 5px;&lt;br /&gt;
				background-color: #FFFFFF;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #999999;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#songs {&lt;br /&gt;
				border-style: solid&lt;br /&gt;
				border-color: #999999;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
				margin-left: 220px;&lt;br /&gt;
				background-color: #FFFFFF;&lt;br /&gt;
				min-height: 400px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			#message, #waiting, #msg_dosearch, #msg_error {&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				font-size: 14pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#songs .KJList {&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				height: 400px;&lt;br /&gt;
				overflow: auto;&lt;br /&gt;
				!background-color: #FFFFFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListColumn {&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
				background: url(&#039;column-bg.jpg&#039;);&lt;br /&gt;
				cursor: default;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListColumn td {&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #999999;&lt;br /&gt;
				border-width: 0px;&lt;br /&gt;
				border-right-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListColumn .primary {&lt;br /&gt;
				background: url(&#039;column-selected-bg.jpg&#039;);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListItem, .KJListItem_alt, .KJListItem_selected, .KJListItem_drag, .KJListItem_target, .KJListItem_alt_target {&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				padding-top: 0px;&lt;br /&gt;
				padding-bottom: 0px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
				cursor: default;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #FFFFFF;&lt;br /&gt;
				border-width: 0px;&lt;br /&gt;
				border-bottom-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListItem_alt {&lt;br /&gt;
				background-color: #EEEEFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListItem_selected {&lt;br /&gt;
				background-color: #4444FF;&lt;br /&gt;
				color: #FFFFFF;&lt;br /&gt;
			}&lt;br /&gt;
						&lt;br /&gt;
			.KJListItem_target, .KJListItem_alt_target {&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 0px;&lt;br /&gt;
				border-top-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListItem_alt_target {&lt;br /&gt;
				background-color: #EEEEFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJListItem_drag {&lt;br /&gt;
				position: absolute;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
				background-color: #DDDDDD;&lt;br /&gt;
				filter:alpha(opacity=40); /* for IE */&lt;br /&gt;
				-moz-opacity:0.4;&lt;br /&gt;
				opacity: 0.4;	&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJList input {&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				margin: 0px;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			.KJList input:active {&lt;br /&gt;
				background-color: #000000;&lt;br /&gt;
				color: #FFFFFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJListItem, #playlists .KJListItem_alt, #playlists .KJListItem_selected, #playlists .KJListItem_target, #playlists .KJListItem_alt_target {&lt;br /&gt;
				background: url(&#039;playlist-icon.gif&#039;);&lt;br /&gt;
				background-repeat: no-repeat;&lt;br /&gt;
				padding: 0px;&lt;br /&gt;
				padding-left: 20px;&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #FFFFFF;&lt;br /&gt;
				border-width: 3px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJListItem_alt {&lt;br /&gt;
				background-color: #EEEEFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJListItem_selected {&lt;br /&gt;
				background-color: #4444FF;&lt;br /&gt;
				color: #FFFFFF;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#playlists .KJListItem_target, #playlists .KJListItem_alt_target {&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				background-color: #9999FF;&lt;br /&gt;
			}&lt;br /&gt;
 &lt;br /&gt;
			.clear {&lt;br /&gt;
				clear: both;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt; &lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;/head&amp;gt; &lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;set_interval()&amp;quot; onmousemove=&amp;quot;reset_interval()&amp;quot; onclick=&amp;quot;reset_interval()&amp;quot; onkeypress=&amp;quot;reset_interval()&amp;quot; onscroll=&amp;quot;reset_interval()&amp;quot;&amp;gt; &lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt; &lt;br /&gt;
			&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;*DeusExMachina&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;Search Library: &amp;lt;input type=&amp;quot;search&amp;quot; id=&amp;quot;searchfield&amp;quot; name=&amp;quot;search&amp;quot; onkeypress=searchKeyPressed(event) onblur=&amp;quot;inSearch.off()&amp;quot; onfocus=&amp;quot;inSearch.on()&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; style=&amp;quot;&amp;quot; name=&amp;quot;dosearch&amp;quot; value=&amp;quot;Go&amp;quot; onclick=m_doSearch() /&amp;gt;&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;help&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ] [ &amp;lt;a id=&amp;quot;logoutlink&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt; ]&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt; &lt;br /&gt;
			&lt;br /&gt;
			&amp;lt;div&amp;gt; &lt;br /&gt;
				&amp;lt;div id=&amp;quot;left&amp;quot;&amp;gt; &lt;br /&gt;
					&amp;lt;div id=&amp;quot;playlists&amp;quot;&amp;gt;&amp;lt;/div&amp;gt; &lt;br /&gt;
					&amp;lt;div id=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;kjams-main.jpg&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt; &lt;br /&gt;
				&amp;lt;/div&amp;gt; &lt;br /&gt;
				&lt;br /&gt;
				&amp;lt;div id=&amp;quot;songs&amp;quot;&amp;gt;&amp;lt;p id=&amp;quot;msg_error&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;msg_dosearch&amp;quot;&amp;gt;Please enter a search.&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;message&amp;quot;&amp;gt;No Playlist Selected.&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;waiting&amp;quot;&amp;gt;Please wait, loading playlist...&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt; &lt;br /&gt;
				&lt;br /&gt;
				&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt; &amp;lt;/div&amp;gt; &lt;br /&gt;
				&amp;lt;div id=&amp;quot;status&amp;quot;&amp;gt;Welcome to kJams!&amp;lt;/div&amp;gt; &lt;br /&gt;
			&amp;lt;/div&amp;gt; &lt;br /&gt;
		&amp;lt;/div&amp;gt; &lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt; &lt;br /&gt;
			//Bind key press function&lt;br /&gt;
			document.onkeyup = m_keyPressed;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			document.onkeydown=trapDelete;&lt;br /&gt;
 &lt;br /&gt;
			//Hide message fields&lt;br /&gt;
			document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			&lt;br /&gt;
			//Plug in help and logout URLs&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			document.getElementById(&amp;quot;logoutlink&amp;quot;).href = url_login;&lt;br /&gt;
			&lt;br /&gt;
			//Playlists&lt;br /&gt;
			m_populatePlaylists();&lt;br /&gt;
		&lt;br /&gt;
			if (0) {&lt;br /&gt;
				//Song list&lt;br /&gt;
				var songs = new KJList();&lt;br /&gt;
				songs.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
				songs.setColumns(Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Pitch&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;), 1);&lt;br /&gt;
				&lt;br /&gt;
				//Set clipping&lt;br /&gt;
				songs.setClipping({&#039;right&#039; : songs.getColumnWidth(5) + songs.getColumnWidth(4) + songs.getColumnWidth(3)});&lt;br /&gt;
				&lt;br /&gt;
				getSongs(url_songs, populateList, &#039;playlist=1&#039;);&lt;br /&gt;
				&lt;br /&gt;
				function populateList(songList) {&lt;br /&gt;
					for(var i = 0; i &amp;lt; songList.length; i++) {&lt;br /&gt;
						songs.addItem(songList[i][&#039;number&#039;], Array(songList[i][&#039;number&#039;], songList[i][&#039;name&#039;], songList[i][&#039;artist&#039;], &amp;quot;&amp;lt;select&amp;gt;&amp;lt;option&amp;gt;+6&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+5&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+1&amp;lt;/option&amp;gt;&amp;lt;option selected&amp;gt;0&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-1&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-5&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Tonight\&amp;quot; /&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Favorites\&amp;quot; /&amp;gt;&amp;quot;), null, null, false);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					songs.color();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt; &lt;br /&gt;
	&amp;lt;/body&amp;gt; &lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7983</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7983"/>
		<updated>2012-09-04T02:56:09Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into the javascript section of your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Bind key press function&lt;br /&gt;
	document.onkeyup = m_keyPressed;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7982</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7982"/>
		<updated>2012-09-04T02:46:53Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
	//Prevent browser from seeing the Delete key press&lt;br /&gt;
	document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7981</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7981"/>
		<updated>2012-09-04T02:46:14Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then you can just add the following code into your other pages:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			 document.onkeydown=trapDelete;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7980</id>
		<title>Server/Code/modifications to main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/modifications_to_main.js&amp;diff=7980"/>
		<updated>2012-09-04T02:44:34Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Often times when using kJams Server, the user will miss the &amp;quot;Song Added&amp;quot; alert at the bottom of the window. (Heck, even I just recently noticed it!) As a result, they will mistakenly hit the &amp;quot;Tonight&amp;quot; button over and over, thus adding the song multiple times. To combat this (but not be quite as intrusive as a pop up alert) I made this little code snippet that will make the text bright red and flash it several times to catch the users attention.&lt;br /&gt;
&lt;br /&gt;
To use it, open the file &amp;quot;main.js&amp;quot; (it should be in &amp;quot;~/Libraries/Preferences/kJams/server&amp;quot;) and find the &amp;quot;function m_setStatus(status, revert)&amp;quot; code block. Replace it with the text below and save.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer(); &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 //If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkFlag=0; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else { &lt;br /&gt;
blinkFlag=1; &lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
} &lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition, it is very useful to trap the delete key, so that users do not inadvertently go back to the previous page by hitting this key (which, for instance, might take them back to the previous singers page from the login screen after a log out). This would be bad!&lt;br /&gt;
To do this, you need to make a few mods to the pages. In particular, you need to call the function in your pages. To make it work, paste this into the variable declaration section of your main.js (at the top).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And then add this somewhere in the function declarations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Alternately, you can just use the entire main.js file from the previous page.&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/newsinger.html&amp;diff=7979</id>
		<title>Server/Code/newsinger.html</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/newsinger.html&amp;diff=7979"/>
		<updated>2012-09-04T02:27:54Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: Created page with &amp;quot;&amp;lt;pre&amp;gt; &amp;lt;html&amp;gt; 	&amp;lt;head&amp;gt; 		&amp;lt;meta http-equiv=Content-Type content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt; 		&amp;lt;title&amp;gt;kJams New Singer&amp;lt;/title&amp;gt; 		 		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt; 		&amp;lt;script src...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
		&amp;lt;meta http-equiv=Content-Type content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams New Singer&amp;lt;/title&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;./spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			function catname(){&lt;br /&gt;
				var firstname = document.forms[0].singerfirstname.value;&lt;br /&gt;
				var lastname = document.forms[0].singerlastname.value;&lt;br /&gt;
				document.forms[0].singername.value = firstname + &amp;quot; &amp;quot; + lastname;&lt;br /&gt;
			}&lt;br /&gt;
			function validate(thisform) {&lt;br /&gt;
				with (thisform){&lt;br /&gt;
					if (singerfirstname.value==&#039;&#039;) {&lt;br /&gt;
						alert(&#039;Hey, unless you\’re Obama, ya gotta give me a first name too. Try again.&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
					else if (singerlastname.value==&#039;Required!&#039;) {&lt;br /&gt;
						alert(&#039;What, you think you\’re Madonna? A last name is required. Lets try this again..&#039;);&lt;br /&gt;
						event.returnValue=false;&lt;br /&gt;
					}&lt;br /&gt;
						//safe to navigate away from this page&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
						    //variable to control if message is shown&lt;br /&gt;
    var allowUnload = false;&lt;br /&gt;
  &lt;br /&gt;
    //function triggered by any closing of the current document&lt;br /&gt;
    function confirmUnload(){ &lt;br /&gt;
        if(!allowUnload){&lt;br /&gt;
            //message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
            return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset. (At you closing the window, not the A.I.D.S..)\n:\&#039;(&#039;;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //register function with the event handler&lt;br /&gt;
    window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;&lt;br /&gt;
			#main {&lt;br /&gt;
				width: 400px;&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
				text-align: center;&lt;br /&gt;
				background: url(&#039;metal.jpg&#039;);&lt;br /&gt;
				border-style: solid;&lt;br /&gt;
				border-color: #000000;&lt;br /&gt;
				border-width: 1px;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main p {&lt;br /&gt;
				font-size: 24pt;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main table {&lt;br /&gt;
				margin-left: auto;&lt;br /&gt;
				margin-right: auto;&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			#main img {&lt;br /&gt;
				margin-bottom: 10px;&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/style&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;body&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;New Singer&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;img src=&amp;quot;kjams.png&amp;quot; /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
			&amp;lt;font color=&amp;quot;#FF0000&amp;quot;&amp;gt;&amp;lt;/font&amp;gt;&lt;br /&gt;
			&amp;lt;form id=&amp;quot;form&amp;quot; method=&amp;quot;POST&amp;quot; action=&amp;quot;&amp;quot; onsubmit=&amp;quot;validate(this); allowUnload=true&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;table&amp;gt;&lt;br /&gt;
					&amp;lt;input type=&amp;quot;hidden&amp;quot; id=&amp;quot;singername&amp;quot; name=&amp;quot;singername&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;First Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerfirstname&amp;quot; value=&amp;quot;&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Last Name: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;singerlastname&amp;quot; value=&amp;quot;Required!&amp;quot; onfocus=&amp;quot;this.value= (this.value==&#039;Required!&#039;) ? &#039;&#039; : this.value&amp;quot; onBlur=&amp;quot;this.value= (this.value==&#039;&#039;) ? &#039;Required!&#039; : this.value&amp;quot; onkeyup=&amp;quot;catname()&amp;quot;/&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Password: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;password&amp;quot; id=&amp;quot;password&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
var p = document.getElementById(&#039;password&#039;);&lt;br /&gt;
p.type = &#039;text&#039;;&lt;br /&gt;
p.value = &#039;Make a password&#039;;&lt;br /&gt;
p.onfocus = function() {&lt;br /&gt;
if (this.type == &#039;text&#039;) {&lt;br /&gt;
this.value = &#039;&#039;;&lt;br /&gt;
this.type = &#039;password&#039;;&lt;br /&gt;
this.focus();&lt;br /&gt;
}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Again: &amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;password&amp;quot; name=&amp;quot;confirm&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
					&amp;lt;tr&amp;gt;&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot;  name=&amp;quot;submit&amp;quot; value=&amp;quot;Jam Out!&amp;quot; /&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
				&amp;lt;/table&amp;gt;&lt;br /&gt;
			&amp;lt;/form&amp;gt;&lt;br /&gt;
			&amp;lt;p style=&amp;quot;font-size: 12pt;&amp;quot;&amp;gt;[ &amp;lt;a href=&amp;quot;/&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot;&amp;gt;Back&amp;lt;/a&amp;gt; ]&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			document.getElementById(&amp;quot;form&amp;quot;).action = url_newsinger;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code&amp;diff=7978</id>
		<title>Server/Code</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code&amp;diff=7978"/>
		<updated>2012-09-04T02:27:26Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* [[Server/Code/main.js|main.js]]&lt;br /&gt;
* [[Server/Code/mainscreen.html|mainscreen.html]]&lt;br /&gt;
* [[Server/Code/modifications to main.js|modifications to main.js]]&lt;br /&gt;
* [[Server/Code/newsinger.html|newsinger.html]]&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/main.js&amp;diff=7977</id>
		<title>Server/Code/main.js</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/main.js&amp;diff=7977"/>
		<updated>2012-09-04T02:23:10Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/*	kJams Project - main.js&lt;br /&gt;
	Description: Main screen functionality.&lt;br /&gt;
	(c) 2007 kJams and David M. Cotter	*/&lt;br /&gt;
&lt;br /&gt;
var timer = null;&lt;br /&gt;
var lastPing = 0;&lt;br /&gt;
var allowBackspace = false;&lt;br /&gt;
//checks to see if the search field it in focus. If it is, allow the user to use the Delete/Backspace key. Otherwise, set flag to trap it.&lt;br /&gt;
var inSearch = {&lt;br /&gt;
   on: function() {allowBackspace = true;},&lt;br /&gt;
   off: function() {allowBackspace = false;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populatePlaylists() {&lt;br /&gt;
	//Remove anything that was already there&lt;br /&gt;
	divObj = document.getElementById(&amp;quot;playlists&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; divObj.childNodes.length; i++) {&lt;br /&gt;
		divObj.removeChild(divObj.childNodes[i]);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	list = new KJDropList();&lt;br /&gt;
	list.create(divObj);&lt;br /&gt;
	playlistsList = list;&lt;br /&gt;
	&lt;br /&gt;
	getPlaylists(url_playlists, m_playlistsLoaded);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistsLoaded(list) {&lt;br /&gt;
	listCtrl = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			dropTarget = false;&lt;br /&gt;
		else&lt;br /&gt;
			dropTarget = true;&lt;br /&gt;
		&lt;br /&gt;
		listCtrl.addItem(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;], list[i][&#039;name&#039;], dropTarget, null, false);&lt;br /&gt;
		&lt;br /&gt;
		//Library and History items are not rearrangeable&lt;br /&gt;
		if ((list[i][&#039;name&#039;] == &amp;quot;Library&amp;quot;) || (list[i][&#039;name&#039;] == &amp;quot;History&amp;quot;))&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = false;&lt;br /&gt;
		else&lt;br /&gt;
			document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).rearrange = true;&lt;br /&gt;
		&lt;br /&gt;
		//Keep track of ids for &#039;Tonight&#039; and &#039;Favorites&#039;&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			pTonightID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (list[i][&#039;name&#039;] == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			pFavoritesID = list[i][&#039;id&#039;];&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		//Store the playlist name in the DOM object&lt;br /&gt;
		document.getElementById(&amp;quot;p&amp;quot; + list[i][&#039;id&#039;]).name = list[i][&#039;name&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	listCtrl.color();&lt;br /&gt;
	listCtrl.evtClick = m_populateSongs;&lt;br /&gt;
	listCtrl.evtDropInto = m_playlistDrop;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_populateSongs(playlist) {&lt;br /&gt;
	playlist = playlist.substring(1);&lt;br /&gt;
	&lt;br /&gt;
	//Hide&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlist != &amp;quot;1&amp;quot;) {&lt;br /&gt;
			songsList.destroy();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide &amp;quot;No Playlist&amp;quot; message, show waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//If the list is already loaded, simply display it&lt;br /&gt;
	if ((playlist == &amp;quot;1&amp;quot;) &amp;amp;&amp;amp; (songsLists[playlist] != undefined)) {&lt;br /&gt;
		songsList = songsLists[playlist];&lt;br /&gt;
		songsList.show();&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//If it&#039;s the library, request that user do a search first&lt;br /&gt;
	else if (playlist == &amp;quot;1&amp;quot;) {&lt;br /&gt;
		document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
		document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	else {&lt;br /&gt;
		//Playlist DOM object&lt;br /&gt;
		playlistObj = document.getElementById(&amp;quot;p&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		//Which columns are needed?&lt;br /&gt;
		var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		if (playlistObj.name == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Pitch&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (playlistObj.name == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
			columns.push(&amp;quot;Add to&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		songsList = new KJList();&lt;br /&gt;
		songsList.rearrange = playlistObj.rearrange;&lt;br /&gt;
		songsList.playlist = playlist;&lt;br /&gt;
		songsList.playlistName = playlistObj.name;&lt;br /&gt;
		songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
		songsList.setColumns(columns, 0);&lt;br /&gt;
		songsList.evtDrop = m_songRearrange;&lt;br /&gt;
		songsLists[playlist] = songsList;&lt;br /&gt;
		getSongs(url_songs, m_songsLoaded, &amp;quot;playlist=&amp;quot; + playlist);&lt;br /&gt;
		&lt;br /&gt;
		if (false) {&lt;br /&gt;
			songsList.evtColClick = null;&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			songsList.evtColClick = m_sortSongs;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songsLoaded(list) {&lt;br /&gt;
	//Hide waiting message&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	//Rearrangeable?&lt;br /&gt;
	if (songsList.rearrange)&lt;br /&gt;
		var rearrange = true;&lt;br /&gt;
	else&lt;br /&gt;
		var rearrange = false;&lt;br /&gt;
	&lt;br /&gt;
	for (var i = 0; i &amp;lt; list.length; i++) {&lt;br /&gt;
		//Add to favorites&lt;br /&gt;
		var favsButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		favsButton.type = &amp;quot;button&amp;quot;&lt;br /&gt;
		favsButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		favsButton.songId = list[i][&#039;id&#039;];&lt;br /&gt;
		favsButton.value = &amp;quot;Favorites&amp;quot;;&lt;br /&gt;
		favsButton.onmousedown = m_addToFavorites;&lt;br /&gt;
		&lt;br /&gt;
		//Add to Tonight&lt;br /&gt;
		var tonightButton = document.createElement(&amp;quot;INPUT&amp;quot;);&lt;br /&gt;
		tonightButton.type = &amp;quot;button&amp;quot;;&lt;br /&gt;
		tonightButton.name = songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;];&lt;br /&gt;
		tonightButton.songId = list[i][&#039;id&#039;]; &lt;br /&gt;
		tonightButton.value = &amp;quot;Tonight&amp;quot;;&lt;br /&gt;
		tonightButton.onmousedown = m_addToTonight;&lt;br /&gt;
	&lt;br /&gt;
		//Columns&lt;br /&gt;
		var columns = Array(i, list[i][&#039;name&#039;], list[i][&#039;artist&#039;]);&lt;br /&gt;
		&lt;br /&gt;
		if (typeof(list[i][&#039;album&#039;]) == &amp;quot;object&amp;quot;) {&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;id&#039;];&lt;br /&gt;
			&lt;br /&gt;
			for (var j = 0; j &amp;lt; list[i][&#039;album&#039;][&#039;items&#039;].length; j++) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = list[i][&#039;album&#039;][&#039;items&#039;][j];&lt;br /&gt;
				optionObj.innerHTML = optionObj.value;&lt;br /&gt;
				&lt;br /&gt;
				if (list[i][&#039;album&#039;][&#039;default&#039;] == j) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(list[i][&#039;album&#039;]);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if (songsList.playlistName == &amp;quot;Tonight&amp;quot;) {&lt;br /&gt;
			//Drop-down&lt;br /&gt;
			var options = {&amp;quot;+6&amp;quot; : 6, &amp;quot;+5&amp;quot; : 5, &amp;quot;+4&amp;quot; : 4, &amp;quot;+3&amp;quot; : 3, &amp;quot;+2&amp;quot; : 2, &amp;quot;+1&amp;quot; : 1, &amp;quot;0&amp;quot; : 0, &amp;quot;-1&amp;quot; : -1, &amp;quot;-2&amp;quot; : -2, &amp;quot;-3&amp;quot; : -3, &amp;quot;-4&amp;quot; : -4, &amp;quot;-5&amp;quot; : -5, &amp;quot;-6&amp;quot; : -6}&lt;br /&gt;
			var dropDown = document.createElement(&amp;quot;SELECT&amp;quot;);&lt;br /&gt;
			dropDown.name = list[i][&#039;itemId&#039;];&lt;br /&gt;
			dropDown.songId = list[i][&#039;id&#039;];&lt;br /&gt;
			dropDown.onchange = m_changePitch;&lt;br /&gt;
			for (option in options) {&lt;br /&gt;
				var optionObj = document.createElement(&amp;quot;OPTION&amp;quot;);&lt;br /&gt;
				optionObj.value = options[option];&lt;br /&gt;
				optionObj.innerHTML = option;&lt;br /&gt;
				&lt;br /&gt;
				if(list[i][&#039;pitch&#039;] == options[option]) {&lt;br /&gt;
					optionObj.selected = true;&lt;br /&gt;
				}&lt;br /&gt;
				&lt;br /&gt;
				dropDown.appendChild(optionObj);&lt;br /&gt;
			}&lt;br /&gt;
			&lt;br /&gt;
			columns.push(dropDown);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else if (songsList.playlistName == &amp;quot;Favorites&amp;quot;) {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		else {&lt;br /&gt;
			columns.push(tonightButton);&lt;br /&gt;
			columns.push(favsButton);&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		index = songsList.addItem(songsList.playlist + &amp;quot;-&amp;quot; + list[i][&#039;itemId&#039;], columns, rearrange, null, false);&lt;br /&gt;
		&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songName	= list[i][&#039;name&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).songId		= list[i][&#039;id&#039;];&lt;br /&gt;
		document.getElementById(songsList.getByIndex(index)).piIx		= list[i][&#039;itemId&#039;];&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	songsList.color();&lt;br /&gt;
	&lt;br /&gt;
	if (songsList.playlistName != &amp;quot;Tonight&amp;quot; &amp;amp;&amp;amp; songsList.playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
		songsList.evtColClick = m_sortSongs;&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		songsList.evtColClick = null;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_songRearrange(list, song, index, oldIndex) {&lt;br /&gt;
	sendData(url_rearrange, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;index=&amp;quot; + index + &amp;quot;&amp;amp;oldIndex=&amp;quot; + oldIndex);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_playlistDrop(song, index, nodeId) {&lt;br /&gt;
	playlists	= document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	item		= songsList.getByID(song);&lt;br /&gt;
	&lt;br /&gt;
	if (songsLists[playlists.getByIndex(index).substring(1)]) { songsLists[playlists.getByIndex(index).substring(1)].destroy(); }&lt;br /&gt;
	songsLists[playlists.getByIndex(index).substring(1)] = null;&lt;br /&gt;
	sendData(url_drop, &amp;quot;playlist=&amp;quot; + playlists.getByIndex(index).substring(1) + &amp;quot;&amp;amp;song=&amp;quot; + songsList.getByID(song).songId);&lt;br /&gt;
	&lt;br /&gt;
	m_setStatus(&amp;quot;Added \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; to \&amp;quot;&amp;quot; + m_getPlaylistName(playlists.getByIndex(index)) + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToTonight(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent;&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pTonightID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_addToFavorites(event) {&lt;br /&gt;
	playlists = document.getElementById(&amp;quot;playlists&amp;quot;).childNodes[0].parent&lt;br /&gt;
	m_playlistDrop(event.target.name, playlists.getIndex(&amp;quot;p&amp;quot; + pFavoritesID), event.target.name);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sortSongs(list, column) {&lt;br /&gt;
	list.removeAll();&lt;br /&gt;
	list.setPrimaryCol(column);&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
	&lt;br /&gt;
	if (document.getElementById(&amp;quot;searchfield&amp;quot;).value) {&lt;br /&gt;
		search = &amp;quot;&amp;amp;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_sort, m_songsLoaded, &amp;quot;playlist=&amp;quot; + list.playlist + &amp;quot;&amp;amp;orderby=&amp;quot; + column + search);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_changePitch(event) {&lt;br /&gt;
	sendData(url_pitch, &amp;quot;song=&amp;quot; + event.target.songId + &amp;quot;&amp;amp;pitch=&amp;quot; + event.target.value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_doSearch() {&lt;br /&gt;
	//Select &amp;quot;Library&amp;quot; in the side bar&lt;br /&gt;
	playlistsList.select(playlistsList.getByID(playlistsList.getByIndex(0)));&lt;br /&gt;
	&lt;br /&gt;
	//Remove old search list if it&#039;s there&lt;br /&gt;
	if (songsLists[&amp;quot;1&amp;quot;]) {&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].container);&lt;br /&gt;
		songsLists[&amp;quot;1&amp;quot;].parentObj.removeChild(songsLists[&amp;quot;1&amp;quot;].columnsObj);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	//Hide currently loaded list&lt;br /&gt;
	if (songsList) {&lt;br /&gt;
		songsList.hide();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;message&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
&lt;br /&gt;
	var columns = Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Album&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
	songsList = new KJList();&lt;br /&gt;
	songsList.rearrange = false;&lt;br /&gt;
	songsList.playlist = &amp;quot;1&amp;quot;;&lt;br /&gt;
	songsList.playlistName = &amp;quot;Library&amp;quot;;&lt;br /&gt;
	songsList.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
	songsList.setColumns(columns, 1);&lt;br /&gt;
	songsLists[&amp;quot;1&amp;quot;] = songsList;&lt;br /&gt;
	&lt;br /&gt;
	getSongs(url_search, m_songsLoaded, &amp;quot;search=&amp;quot; + document.getElementById(&amp;quot;searchfield&amp;quot;).value);&lt;br /&gt;
	m_sessionCheckin();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function searchKeyPressed(event) {&lt;br /&gt;
	if (event.keyCode == 13) {&lt;br /&gt;
		m_doSearch();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getSongName(id) {&lt;br /&gt;
	songObj = document.getElementById(id);&lt;br /&gt;
	return songObj.songName;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_getPlaylistName(id) {&lt;br /&gt;
	playlistObj = document.getElementById(id);&lt;br /&gt;
	return playlistObj.name;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function kj_data_error(id, desc) {&lt;br /&gt;
	songsLists[songsList.id] = null;&lt;br /&gt;
	songsList.hide();&lt;br /&gt;
	document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
	&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).innerHTML = &amp;quot;Error: &amp;quot; + desc&lt;br /&gt;
	document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;&#039;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_setStatus(status, revert) {&lt;br /&gt;
	statusObj = document.getElementById(&amp;quot;status&amp;quot;);&lt;br /&gt;
	statusObj.innerHTML = &amp;quot;&amp;lt;span style=&#039;color:#FF0000&#039;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;;&lt;br /&gt;
	var newInnerHTML=&#039;statusObj.innerHTML = &amp;quot;&amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;quot; + status + &amp;quot;&amp;lt;/span&amp;gt;&amp;quot;&#039;;&lt;br /&gt;
	blink();&lt;br /&gt;
	setTimeout(&amp;quot;statusObj.innerHTML = newInnerHTML&amp;quot;,1250);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blink(){ &lt;br /&gt;
blinkFlag = 1 &lt;br /&gt;
blinkCount = 1 &lt;br /&gt;
blinkTimer();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function blinkTimer(){ &lt;br /&gt;
if(blinkFlag==1){&lt;br /&gt;
blinkSpeed=250&lt;br /&gt;
blinkNumber=10 // If this value is even, the text flashes then remains visible. If it is odd, it flashes, then disappears&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;visible&#039;; &lt;br /&gt;
}else {&lt;br /&gt;
blinkCount++; &lt;br /&gt;
document.getElementById(&amp;quot;status&amp;quot;).style.visibility=&#039;hidden&#039;; &lt;br /&gt;
}&lt;br /&gt;
blinkFlag^=1;&lt;br /&gt;
if (blinkCount &amp;lt; blinkNumber) {setTimeout(&#039;blinkTimer()&#039;, blinkSpeed);} &lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
function trapDelete() {&lt;br /&gt;
	//Checks to see if the key pressed is the Delete/Backspace key, and if so, stop it from getting to the browser.&lt;br /&gt;
   var keyID = (window.event) ? event.keyCode : e.keyCode;&lt;br /&gt;
   if (keyID==8 &amp;amp;&amp;amp; !allowBackspace){&lt;br /&gt;
	  return false;&lt;br /&gt;
   }&lt;br /&gt;
   return true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_keyPressed(event) {&lt;br /&gt;
	//This is not IE-compliant code.&lt;br /&gt;
	if (event.keyCode == 46 || event.keyCode == 8) {&lt;br /&gt;
		if (!songsList.selection) {&lt;br /&gt;
			return;&lt;br /&gt;
		}&lt;br /&gt;
	&lt;br /&gt;
		playlistName	= songsList.playlistName;&lt;br /&gt;
&lt;br /&gt;
		if (playlistName != &amp;quot;Library&amp;quot; &amp;amp;&amp;amp; playlistName != &amp;quot;History&amp;quot;) {&lt;br /&gt;
			selection	= songsList.selection;&lt;br /&gt;
			item		= songsList.getByID(selection);&lt;br /&gt;
			&lt;br /&gt;
			songsList.select(null);&lt;br /&gt;
			sendData(url_remove, &amp;quot;playlist=&amp;quot; + songsList.playlist + &amp;quot;&amp;amp;piIx=&amp;quot; + item.piIx);&lt;br /&gt;
			m_setStatus(&amp;quot;Removed \&amp;quot;&amp;quot; + item.songName + &amp;quot;\&amp;quot; ...&amp;quot;);&lt;br /&gt;
			songsList.removeItem(selection);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_pingSession() {&lt;br /&gt;
	var elapsedTime = new Date().getTime()/1000.0 - lastPing;&lt;br /&gt;
	&lt;br /&gt;
	if (elapsedTime &amp;gt;= 5) {&lt;br /&gt;
		sendData(url_ping, &amp;quot;&amp;quot;);&lt;br /&gt;
		m_sessionCheckin();&lt;br /&gt;
		lastPing = new Date().getTime()/1000.0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionCheckin() {&lt;br /&gt;
	/* A true or false value is set by the server before delivering this script &lt;br /&gt;
		depending on preference. */&lt;br /&gt;
	if (!{auto_logout}) {&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (timer == null) {&lt;br /&gt;
		timer = setInterval(&amp;quot;m_sessionLogout()&amp;quot;, {timeout} * 1000);&lt;br /&gt;
	}&lt;br /&gt;
	else {&lt;br /&gt;
		clearInterval(timer);&lt;br /&gt;
		timer = null;&lt;br /&gt;
		return m_sessionCheckin();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function m_sessionLogout() {&lt;br /&gt;
	// Sets the flag to tell confirmUnload subroutine that it is OK to let the user leave this page (close the Window, etc.)&lt;br /&gt;
	allowUnload = true;&lt;br /&gt;
	window.location=url_login;&lt;br /&gt;
}&lt;br /&gt;
function loaded() {&lt;br /&gt;
	document.addEventListener(&#039;touchmove&#039;, function(e){ e.preventDefault(); });&lt;br /&gt;
	myScroll = new iScroll(&#039;songs&#039;);&lt;br /&gt;
}&lt;br /&gt;
//document.addEventListener(&#039;DOMContentLoaded&#039;, loaded);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/mainscreen.html&amp;diff=7976</id>
		<title>Server/Code/mainscreen.html</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/mainscreen.html&amp;diff=7976"/>
		<updated>2012-09-04T02:08:51Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;!--Singer: {singer}--&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Server&amp;lt;/title&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;ui.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;iscroll.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;blockUnload.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;!--&lt;br /&gt;
			  			 var allowUnload = false;&lt;br /&gt;
			blinkSpeed=150;&lt;br /&gt;
			tagName=&amp;quot;blinker&amp;quot;;&lt;br /&gt;
			blinkerFlag=1;&lt;br /&gt;
			blinkElement=document.getElementsByName(tagName);&lt;br /&gt;
			blinkText();&lt;br /&gt;
&lt;br /&gt;
			function blinkText() {&lt;br /&gt;
				if (blinkerFlag== 1) {&lt;br /&gt;
					blinkState=&amp;quot;visible&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
				blinkState=&amp;quot;hidden&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				blinkerFlag ^=1;&lt;br /&gt;
&lt;br /&gt;
				for(i=0;i&amp;lt;blinkElement.length;i++) {&lt;br /&gt;
					blinkElement[i].style.visibility=blinkState;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				setTimeout(&amp;quot;blinkText()&amp;quot;, blinkSpeed);&lt;br /&gt;
			}&lt;br /&gt;
			--&amp;gt;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//variable to control if message is shown&lt;br /&gt;
  			 var allowUnload = false;&lt;br /&gt;
&lt;br /&gt;
  			// function triggered by any closing of the current document&lt;br /&gt;
			function confirmUnload(){&lt;br /&gt;
				if(!allowUnload){&lt;br /&gt;
					//message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
					return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this 							window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset (at you 							closing the window, not the A.I.D.S., that\&#039;s on you).\n :\&#039;(&#039;;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//register function with the event handler&lt;br /&gt;
			window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;screen.css&amp;quot; media=&amp;quot;screen&amp;quot;/&amp;gt; &lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;handheld.css&amp;quot; media=&amp;quot;handheld, only screen and (max-device-width:480px)&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;m_sessionCheckin()&amp;quot;; &amp;quot;loaded()&amp;quot; onmousemove=&amp;quot;m_pingSession()&amp;quot; onclick=&amp;quot;m_pingSession()&amp;quot; onkeypress=&amp;quot;m_pingSession()&amp;quot; onscroll=&amp;quot;m_pingSession()&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;{singer}&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;Search Library: &amp;lt;input type=&amp;quot;search&amp;quot; id=&amp;quot;searchfield&amp;quot; name=&amp;quot;search&amp;quot; onkeypress=searchKeyPressed(event) onblur=&amp;quot;inSearch.off()&amp;quot; onfocus=&amp;quot;inSearch.on()&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; style=&amp;quot;&amp;quot; name=&amp;quot;dosearch&amp;quot; value=&amp;quot;Go&amp;quot; onclick=m_doSearch() /&amp;gt;&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;help&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ] [ &amp;lt;a id=&amp;quot;logoutlink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt; ]&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
			&lt;br /&gt;
			&amp;lt;div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;playlists&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;kjams-main.jpg&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;wrapper&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;songs&amp;quot;&amp;gt;&amp;lt;p id=&amp;quot;msg_error&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;msg_dosearch&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;message&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;Type your search into the search field above and hit &amp;quot;Go&amp;quot;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;To submit a song, just click the &amp;quot;Tonight&amp;quot; button for that song in the search results. (You can also make your own &amp;quot;Favorties&amp;quot; list.)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;You will be informed at the bottom of the screen when you have successfully submitted a song.&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;waiting&amp;quot;&amp;gt;Please wait, loading search results… .&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;(This may take a while. &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;lt;a name=blinker&amp;gt;Please do NOT&amp;lt;/a&amp;gt; try another search until the first results are returned.)&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;status&amp;quot;&amp;gt;Welcome to kJams!&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//Bind key press function&lt;br /&gt;
			document.onkeyup = m_keyPressed;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			 document.onkeydown=trapDelete;&lt;br /&gt;
&lt;br /&gt;
			//Hide message fields&lt;br /&gt;
			document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			&lt;br /&gt;
			//Plug in help and logout URLs&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			document.getElementById(&amp;quot;logoutlink&amp;quot;).href = url_login;&lt;br /&gt;
			&lt;br /&gt;
			//Playlists&lt;br /&gt;
			m_populatePlaylists();&lt;br /&gt;
		&lt;br /&gt;
			if (0) {&lt;br /&gt;
				//Song list&lt;br /&gt;
				var songs = new KJList();&lt;br /&gt;
				songs.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
				songs.setColumns(Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Pitch&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;), 1);&lt;br /&gt;
				&lt;br /&gt;
				//Set clipping&lt;br /&gt;
				songs.setClipping({&#039;right&#039; : songs.getColumnWidth(5) + songs.getColumnWidth(4) + songs.getColumnWidth(3)});&lt;br /&gt;
				&lt;br /&gt;
				getSongs(url_songs, populateList, &#039;playlist=1&#039;);&lt;br /&gt;
				&lt;br /&gt;
				function populateList(songList) {&lt;br /&gt;
					for(var i = 0; i &amp;lt; songList.length; i++) {&lt;br /&gt;
						songs.addItem(songList[i][&#039;number&#039;], Array(songList[i][&#039;number&#039;], songList[i][&#039;name&#039;], songList[i][&#039;artist&#039;], &amp;quot;&amp;lt;select&amp;gt;&amp;lt;option&amp;gt;+6&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+5&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+1&amp;lt;/option&amp;gt;&amp;lt;option selected&amp;gt;0&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-1&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-5&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Tonight\&amp;quot; /&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Favorites\&amp;quot; /&amp;gt;&amp;quot;), null, null, false);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					songs.color();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Server/Code/mainscreen.html&amp;diff=7975</id>
		<title>Server/Code/mainscreen.html</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Server/Code/mainscreen.html&amp;diff=7975"/>
		<updated>2012-09-04T02:07:01Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;html&amp;gt;&lt;br /&gt;
	&amp;lt;head&amp;gt;&lt;br /&gt;
	&amp;lt;!--Singer: {singer}--&amp;gt;&lt;br /&gt;
		&amp;lt;title&amp;gt;kJams Server&amp;lt;/title&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/xpath.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;spry/SpryData.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;ui.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;data.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;main.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;iscroll.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script src=&amp;quot;blockUnload.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;!--&lt;br /&gt;
			  			 var allowUnload = false;&lt;br /&gt;
			blinkSpeed=150;&lt;br /&gt;
			tagName=&amp;quot;blinker&amp;quot;;&lt;br /&gt;
			blinkerFlag=1;&lt;br /&gt;
			blinkElement=document.getElementsByName(tagName);&lt;br /&gt;
			blinkText();&lt;br /&gt;
&lt;br /&gt;
			function blinkText() {&lt;br /&gt;
				if (blinkerFlag== 1) {&lt;br /&gt;
					blinkState=&amp;quot;visible&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				else {&lt;br /&gt;
				blinkState=&amp;quot;hidden&amp;quot;;&lt;br /&gt;
				}&lt;br /&gt;
				blinkerFlag ^=1;&lt;br /&gt;
&lt;br /&gt;
				for(i=0;i&amp;lt;blinkElement.length;i++) {&lt;br /&gt;
					blinkElement[i].style.visibility=blinkState;&lt;br /&gt;
				}&lt;br /&gt;
&lt;br /&gt;
				setTimeout(&amp;quot;blinkText()&amp;quot;, blinkSpeed);&lt;br /&gt;
			}&lt;br /&gt;
			--&amp;gt;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//variable to control if message is shown&lt;br /&gt;
  			 var allowUnload = false;&lt;br /&gt;
&lt;br /&gt;
  			// function triggered by any closing of the current document&lt;br /&gt;
			function confirmUnload(){&lt;br /&gt;
				if(!allowUnload){&lt;br /&gt;
					//message displayed (as well as inbuilt IE junk) when page is unloaded.&lt;br /&gt;
					return &#039;Why on earth would you think it is a good idea to close this window?!? Well, it ISN\&#039;T!!! Do NOT close this 							window. If you do, all hell will rain down upon you, you will get A.I.D.S., and I will get very upset (at you 							closing the window, not the A.I.D.S., that\&#039;s on you).\n :\&#039;(&#039;;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//register function with the event handler&lt;br /&gt;
			window.onbeforeunload = confirmUnload;&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;screen.css&amp;quot; media=&amp;quot;screen&amp;quot;/&amp;gt; &lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;handheld.css&amp;quot; media=&amp;quot;handheld, only screen and (max-device-width:480px)&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;/head&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;body onLoad=&amp;quot;m_sessionCheckin()&amp;quot;; &amp;quot;loaded()&amp;quot; onmousemove=&amp;quot;m_pingSession()&amp;quot; onclick=&amp;quot;m_pingSession()&amp;quot; onkeypress=&amp;quot;m_pingSession()&amp;quot; onscroll=&amp;quot;m_pingSession()&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div id=&amp;quot;main&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;title&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;{singer}&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;Search Library: &amp;lt;input type=&amp;quot;search&amp;quot; id=&amp;quot;searchfield&amp;quot; name=&amp;quot;search&amp;quot; onkeypress=searchKeyPressed(event) onblur=&amp;quot;inSearch.off()&amp;quot; onfocus=&amp;quot;inSearch.on()&amp;quot; /&amp;gt;&amp;lt;input type=&amp;quot;submit&amp;quot; style=&amp;quot;&amp;quot; name=&amp;quot;dosearch&amp;quot; value=&amp;quot;Go&amp;quot; onclick=m_doSearch() /&amp;gt;&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td id=&amp;quot;help&amp;quot;&amp;gt;&amp;lt;nobr&amp;gt;[ &amp;lt;a id=&amp;quot;helplink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Help&amp;lt;/a&amp;gt; ] [ &amp;lt;a id=&amp;quot;logoutlink&amp;quot; onClick=&amp;quot;allowUnload=true&amp;quot; href=&amp;quot;&amp;quot;&amp;gt;Logout&amp;lt;/a&amp;gt; ]&amp;lt;/nobr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
			&lt;br /&gt;
			&amp;lt;div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;playlists&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div id=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;kjams-main.jpg&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;wrapper&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;songs&amp;quot;&amp;gt;&amp;lt;p id=&amp;quot;msg_error&amp;quot;&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;msg_dosearch&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;message&amp;quot;&amp;gt;Please enter a search.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;Type your search into the search field above and hit &amp;quot;Go&amp;quot;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;To submit a song, just click the &amp;quot;Tonight&amp;quot; button for that song in the search results. (You can also make your own &amp;quot;Favorties&amp;quot; list.)&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;You will be informed at the bottom of the screen when you have successfully submitted a song.&amp;lt;/i&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;b&amp;gt; Hint: To limit your search to just a particular artist, type &amp;quot;artist:&amp;quot; followed by the name of the artist.&amp;lt;br&amp;gt;Likewise, to search just on song names  type &amp;quot;song name:&amp;quot; and then the name of your song, etc..&amp;lt;/b&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;p id=&amp;quot;waiting&amp;quot;&amp;gt;Please wait, loading search results… .&amp;lt;br&amp;gt;&amp;lt;i&amp;gt;&amp;lt;b&amp;gt;(This may take a while. &amp;lt;span style=&amp;quot;color:#FF0000&amp;quot;&amp;gt;&amp;lt;a name=blinker&amp;gt;Please do NOT&amp;lt;/a&amp;gt; try another search until the first results are returned.)&amp;lt;/span&amp;gt;&amp;lt;/b&amp;gt;&amp;lt;/i&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div class=&amp;quot;clear&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;status&amp;quot;&amp;gt;Welcome to kJams!&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
			//Bind key press function&lt;br /&gt;
			document.onkeyup = m_keyPressed;&lt;br /&gt;
			//Prevent browser from seeing the Delete key press&lt;br /&gt;
			 document.onkeydown=trapDelete;&lt;br /&gt;
&lt;br /&gt;
			//Hide message fields&lt;br /&gt;
			document.getElementById(&amp;quot;waiting&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_dosearch&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			document.getElementById(&amp;quot;msg_error&amp;quot;).style.display = &#039;none&#039;;&lt;br /&gt;
			&lt;br /&gt;
			//Plug in help and logout URLs&lt;br /&gt;
			document.getElementById(&amp;quot;helplink&amp;quot;).href = url_help;&lt;br /&gt;
			document.getElementById(&amp;quot;logoutlink&amp;quot;).href = url_login;&lt;br /&gt;
			&lt;br /&gt;
			//Playlists&lt;br /&gt;
			m_populatePlaylists();&lt;br /&gt;
		&lt;br /&gt;
			if (0) {&lt;br /&gt;
				//Song list&lt;br /&gt;
				var songs = new KJList();&lt;br /&gt;
				songs.create(document.getElementById(&amp;quot;songs&amp;quot;));&lt;br /&gt;
				songs.setColumns(Array(&amp;quot;#&amp;quot;, &amp;quot;Song Name&amp;quot;, &amp;quot;Artist&amp;quot;, &amp;quot;Pitch&amp;quot;, &amp;quot;Add to&amp;quot;, &amp;quot;Add to&amp;quot;), 1);&lt;br /&gt;
				&lt;br /&gt;
				//Set clipping&lt;br /&gt;
				songs.setClipping({&#039;right&#039; : songs.getColumnWidth(5) + songs.getColumnWidth(4) + songs.getColumnWidth(3)});&lt;br /&gt;
				&lt;br /&gt;
				getSongs(url_songs, populateList, &#039;playlist=1&#039;);&lt;br /&gt;
				&lt;br /&gt;
				function populateList(songList) {&lt;br /&gt;
					for(var i = 0; i &amp;lt; songList.length; i++) {&lt;br /&gt;
						songs.addItem(songList[i][&#039;number&#039;], Array(songList[i][&#039;number&#039;], songList[i][&#039;name&#039;], songList[i][&#039;artist&#039;], &amp;quot;&amp;lt;select&amp;gt;&amp;lt;option&amp;gt;+6&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+5&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;+1&amp;lt;/option&amp;gt;&amp;lt;option selected&amp;gt;0&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-1&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-4&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;-5&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Tonight\&amp;quot; /&amp;gt;&amp;quot;, &amp;quot;&amp;lt;input type=\&amp;quot;submit\&amp;quot; value=\&amp;quot;Favorites\&amp;quot; /&amp;gt;&amp;quot;), null, null, false);&lt;br /&gt;
					}&lt;br /&gt;
					&lt;br /&gt;
					songs.color();&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		&amp;lt;/script&amp;gt;&lt;br /&gt;
	&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7926</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7926"/>
		<updated>2012-08-21T23:24:05Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Arrow key nudging/time entry for blobs in Inspector */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad.&lt;br /&gt;
&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7925</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7925"/>
		<updated>2012-08-21T14:49:46Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* Warn if quitting Producer will lose changes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self-evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7924</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7924"/>
		<updated>2012-08-21T14:49:17Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: /* The separate thing® (Meta data gets reverted) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes==&lt;br /&gt;
Self- evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7923</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7923"/>
		<updated>2012-08-21T14:45:28Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Warn if quitting Producer will lose changes&lt;br /&gt;
Self- evident, no?&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
&lt;br /&gt;
==Quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
	<entry>
		<id>https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7922</id>
		<title>Bugs/Mark</title>
		<link rel="alternate" type="text/html" href="https://karaoke.kjams.com/w/index.php?title=Bugs/Mark&amp;diff=7922"/>
		<updated>2012-08-21T14:43:00Z</updated>

		<summary type="html">&lt;p&gt;Deusexmachina: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;Notes in italics&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;In order of priority (subject to change):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Arrow key nudging/time entry for blobs in Inspector==&lt;br /&gt;
It would be really nice if it were possible to nudge elements around on the page using the arrow keys, instead of the error-prone use of the mouse/trackpad&lt;br /&gt;
In the same vein, it would be very helpful to have a blob&#039;s time position editable in a field in the Inspector window, just like you can enter scrubber position by clicking in the time field on the left of the Timeline.&lt;br /&gt;
&lt;br /&gt;
==Word spacing==&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: This is potentially just an incorrect assumption somewhere in the code..&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Second most time consuming, because every track must be checked, it is hard to do by visual inspection, and since when a track needs one edit, it often needs MANY, and involves lots of zooming in and zooming out, and blob dragging, which is not particularly efficient in the current interface:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Sometimes words that are supposed to be separated are not. They are placed right next to each other. E.g., &amp;quot;Willyou&amp;quot; instead of &amp;quot;Will you&amp;quot;, even though they are separate words in the actually .fly file.&lt;br /&gt;
Because of this, although it is not particularly common, I still have to go through every track, page by page, checking to see if this has occurred. This can be time-consuming and a bit frustrating. When one is found, there are usually repeats, and editing them all can take significant amounts of time.&lt;br /&gt;
&#039;&#039;Of almost equal priority, since it has to be checked in every file, and if not corrected, forces a redo (unlike the previous one, which can sneak by the quality control staff!):&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;you can also put any related song files into this folder too, and make a link to them so everything is accessible directly from this web page, like this:&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test file: [http://kjams.com/screenshots/bugs/word_spacing/Archive.zip SFDT-2741 The Beatles - Tomorrow Never Knows]&amp;lt;br&amp;gt;&lt;br /&gt;
1:35 &amp;quot;nowlove&amp;quot; should be &amp;quot;now love&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
01:53 &amp;quot;theymourn&amp;quot; should be &amp;quot;they mourn&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
02:23 &amp;quot;soplay&amp;quot; should be &amp;quot;so play&amp;quot;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
There are probably more examples in this file. These are the ones in this file that slipped by my first edit, and so were brought up by SF QC.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;Note: I am pretty sure that this phenomenon only occurs on the first words of a line.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Better pre-post gap settings==&lt;br /&gt;
As discussed before, being able to set a maximum percentage to reduce the size of the final blobs on each page to accommodate the post and pre gaps, first shrinking the final blob until it reached 100 - max percentage, and then shrinking the next one, etc., until the post and pre gaps fit, would finalize this procedure.&lt;br /&gt;
Currently, Producer just shrinks the last blob on the &amp;quot;pre&amp;quot; page to nothing, and only then goes on to shrink the next to last blob, with the result being that the final word just flies by. this has a very disconcerting psychological effect that hampers finding your place on the next page.&lt;br /&gt;
:a percentage of what though?  it can&#039;t be &amp;quot;percentage of original duration&amp;quot; because that can vary wildly.  i think instead it should just be a &amp;quot;minimum duration&amp;quot; in seconds, then you could enter something like &amp;quot;0.25&amp;quot; for one quarter second?  if this seems like it would work, let me know.  -[[User:Dave|dave]] ([[User talk:Dave|talk]]) 22:56, 12 June 2012 (PDT)&lt;br /&gt;
&lt;br /&gt;
No, I really do mean percentage of original duration. For instance, if the last blob needs a full second to sweep, but does not have enough time, it gets squeezed. As of now, if there is less time left in the current page than there is space, it gets squeezed to a &amp;quot;singularity&amp;quot; (no apparent width and instant sweep time). If that is still not enough, the next to last blob gets squeezed, also possibly to a singularity, and so on and so one, causing a set of lyrics that can just flash by before the whole page disappears, which is very psychologically disconcerting.&lt;br /&gt;
I am proposing that the last blob only gets shrunk to a certain extent, and after that, each successive blob can only be shrunk by 25% (75% of its original size) before the next left-most blob gets squeezed. This results in a minimal disruption of the timing, as well as leaving a reasonably sized blob to sweep. Because of the realities of how the pages get made, I suspect there will be few incidents where the blobs will be affected past the last three.&lt;br /&gt;
For instance, the bigger the penultimate blob (gotta use that word at every opportunity) the more time 25% of that blob will be, and thus the bigger cushion you have to fit the final blob. No blob should be able to be shrunk more that a certain minimal duration (enough to ensure that it will actually appear to sweep) so the amount any one blob can shrink is limited by either 75% of original size or the minimum duration parameter, whichever comes first.&lt;br /&gt;
For example: the final four blobs each last 0:75.3. The next page however must come up 1:50.0 after the final blob. As such, the pre and post gap settings would force the final two blobs to reduce to essentially 0:00.0, and the third to last blob being shrunk to accommodate the post gap. To prevent these word from just flashing to the sweep colour and the page disappearing it would instead reduce the final blob to the minimum blob size parameter. It would then check how much it would need to reduce the penultimate blob to accommodate the last word, which would be over 75% of its current size, so it would only be reduced by 25%. Then the penpenultimate blob would be checked. It too would have to be reduced beyond 75%, so it would hit its maximum reduction at 24%. Lastly, the third to final blob wuld be shrunk a small amount, less than 25%, which would successfully accommodate the space needed.&lt;br /&gt;
Alternately, if we presuppose that the second to last blob was only 0:50.0 to begin with, and the minimum blob size was set to, say, 0:40.0, shrinking the full 25% would leave a blob only 0:37.2 seconds wide, below the minimum blob size. As such, the blob would only be shrunk to 0.40.0, and the next blob to the left would have to shrink more to accommodate the difference.&lt;br /&gt;
&lt;br /&gt;
But whatever works. The ultimate goal is just to prevent it from doing those instantaneous sweeps, where the singer thinks he has a certain amount of time, but the word just vanishes, and the page changes. If it is better to do it with a minimum duration in seconds, that is fine. I just suspect that it would be more accurate to the original if it were a percentage.&lt;br /&gt;
&lt;br /&gt;
==Fix &amp;quot;save MSI default&amp;quot;==&lt;br /&gt;
Dave, this ^^^ is a separate thing® from the item below it&lt;br /&gt;
&lt;br /&gt;
Right now, saving the default text and sweep colours and font size etc does NOT work. It was supposed to be fixed, but never actually was. Some things sorta, kinda, partially save, but mostly it just doesn&#039;t work.&lt;br /&gt;
&lt;br /&gt;
Steps:&lt;br /&gt;
# Select track&lt;br /&gt;
# Open in Producer&lt;br /&gt;
# Select Get Media Info&lt;br /&gt;
# Change something (say, sweep colour)&lt;br /&gt;
# Option click &amp;quot;OK&amp;quot; to save  &amp;lt;-- (Dialogue box comes up saying it is saved)&lt;br /&gt;
# Open another track that you have never opened before in Producer&lt;br /&gt;
# Select GMI&lt;br /&gt;
&lt;br /&gt;
Note that the sweep colour is NOT the colour that you saved, but rather the original colour from before the save (or sometimes, even, another colour entirely).&lt;br /&gt;
&lt;br /&gt;
Also, I have tried to edit the xml by hand, and while I can get certain things to change, I have not been able to reliably get the RIGHT thing to change. Colours seem to change at random, or sometimes not at all. If I could just get a working copy of the XML with all the right settings, then being able to correctly save wouldn&#039;t matter. I could just lock the file, and possibly swap another copy in as needed, but nothing I do in the file works reliably, and nothing really makes sense, anyway.&lt;br /&gt;
&lt;br /&gt;
==The separate thing® (Meta data gets reverted)==&lt;br /&gt;
[[Bugs/Mark/Meta_Revert|Meta Revert]]&lt;br /&gt;
&lt;br /&gt;
==Trailing Punctuation==&lt;br /&gt;
It would be nice if, if the final blob on a given line was punctuation, that it actually be placed directly adjacent to the previous word, rather than separated by white space.&lt;br /&gt;
E.g., &amp;quot;you   ….&amp;quot; would be &amp;quot;you….&amp;quot;&lt;br /&gt;
This is important stylistically, not only because of aesthetics, but because of consistency, as some times, for instance, an ellipsis will appear as part of one blob, and other times as a separate one, in the same phrase in the same sentence in the same song.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I can upload, but it is any file where the punctuation is a separate blob from the word before it. So, for example, sometime they might have &amp;quot;love....&amp;quot; as a single entity, and others they may have &amp;quot;love&amp;quot; as one word, and &amp;quot;....&amp;quot; as another. As a result, kJams does what it &amp;quot;should&amp;quot; do, puts a gap between these &amp;quot;words&amp;quot;.&lt;br /&gt;
But not only does this look bad, it makes it inconsistent when SF is inconsistent, and has it so that sometimes there is a space between words and punctuation, and sometimes there is not. IMO, there should NEVER be white space between the word and the following punctuation, be it period, ellipsis, comma, or what have you. Certainly in implementation, this could take the form of an exclusion list.&lt;br /&gt;
&lt;br /&gt;
==Words with hyphens incorrectly sized==&lt;br /&gt;
In the YSTHs tracks, Words with hyphens get incorrectly sized. The hyphen is too long but more interestingly, the bounding box is made too big vertically. This is probably a font issue (Univers 67 condensed bold) but when I replace the hyphen in the blob with the keyboard hyphen, I get the correctly sized character. I thought the preference we added, &amp;quot;producer: interpret hyphens as syllable markers&amp;quot; was supposed to ignore syllable markers, and thus allow the standard keyboard hyphen-minus char to survive the encoding process? If not, it really should!&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;please provide a .fly/.mp3 pair that shows this problem&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Can not create break screen==&lt;br /&gt;
Also in the YSTHs tracks, I still can not create a YSTHs-specific break screen (like &amp;quot;Instrumental/n 10 seconds) that does not crash kJams like a stone.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me your home-made break screen and any accompanying media, and i&#039;ll see why it&#039;s crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
It might be easier for you to just recreate the same one I am trying to use. The YSTHs break screen is just red text that reads &amp;quot;Instrumental xx seconds&amp;quot;. As such, I just took the standard SunFly one, deleted the SF graphic, and changed the text colour of the text asset, which had the tag [msg ].&lt;br /&gt;
When I do this, it crashes immediately.&lt;br /&gt;
&lt;br /&gt;
In fact, no matter what I change it to, even if it has no tag at all, if the screen specified in the prefs is not the SF one, and the track has a break, it crashes.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;definitely easier (for me) if you give me something to work with that is already crashing&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:magenta;&amp;quot;&amp;gt;I think you said this is fixed, no?&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==AE Video Insert==&lt;br /&gt;
In the last YSTHs issue, it would be nice if I could get a video upcard out of AE that I could correctly paste into QT. As it is now, I get a time code error, and as such, am forced to use AE to re-encode the entire video, just to add the terminating upcard onto the end.&lt;br /&gt;
Don&#039;t know if this is an AE error, or something I am doing wrong.&lt;br /&gt;
&lt;br /&gt;
Note: I think I have fixed this, by opening the asset in QT, and exporting using QT.&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;send me an AE project and accompanying media, that has an RQ item that exports the file you wish could be pasted into QT, and i&#039;ll have a look at it&amp;lt;/span&amp;gt;&lt;br /&gt;
As mentioned, I got it to work, by bypassing AE, and using QT to reencode.&lt;br /&gt;
That said, I uploaded the assets along while ago, back when I first brought this up, and they are still on the server. I do believe you opened them then and got the same error trying to C&amp;amp;P in QT.&lt;br /&gt;
&lt;br /&gt;
==FLY file fail==&lt;br /&gt;
Certain .FLY files still do not convert correctly. There appears to be either a math error or a faulty assumption that breaks certain files. I will upload one (Madonna - Borderline) to the FTP.&lt;br /&gt;
:&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;yep, let me know&amp;lt;/span&amp;gt;&lt;br /&gt;
Test files: [http://kjams.com/screenshots/bugs/fly_fail/Archive.zip Two versions of Madonna - Borderline]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Crash / slow switching venues==&lt;br /&gt;
Switching venues multiple times, as I have to do in my copy singers script, often crashed kJams.&lt;br /&gt;
:send dem crash reports (with log files)&lt;br /&gt;
&lt;br /&gt;
It is also &#039;&#039;&#039;SLOWWWWW&#039;&#039;&#039;, but I suspect fixing that will require a re-architecting.&lt;br /&gt;
:i&#039;ve done some optimizations for r57, let me know&lt;br /&gt;
&lt;br /&gt;
==Random crashes==&lt;br /&gt;
&#039;&#039;Heads up:&#039;&#039; There is still an issue of random crashes, I think server-related, but not sure. More data coming if I can catch it with Activity monitor and get code samples.&lt;br /&gt;
&lt;br /&gt;
As discussed, probably not server related. OSX related.&lt;br /&gt;
&lt;br /&gt;
==Editing a playlist for case==&lt;br /&gt;
Editing a playlist for case does not do anything&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:red;&amp;quot;&amp;gt;Fixed in r54+&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Duration missing==&lt;br /&gt;
kJams does not appear to be properly pulling metadata. As of a few versions ago, Most items in the library no longer have an entry for duration. This effects several items, including estimating rotation times.&lt;br /&gt;
==quit producer with cmd-.==&lt;br /&gt;
Hitting cmd-. while in an editable text box in Producer does NOT quit Producer (as expected) rather it nulls out the text field, in an obnoxiously non-undoable fasion.&lt;br /&gt;
&lt;br /&gt;
==Mark Song as Sung==&lt;br /&gt;
Please please PLEASE add a &amp;quot;Mark Song as Sung&amp;quot; context menu to a song in a singer&#039;s tonight list. Many times there is a song with a LONG outro that you want to fade out and move to the next song, but when you do so, the song fails to be added to the singer&#039;s History list.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color:blue;&amp;quot;&amp;gt;New&amp;lt;/span&amp;gt;&lt;br /&gt;
==Warn in Producer if trying to quit without saving current changes==&lt;br /&gt;
&lt;br /&gt;
==Hyphens as syllable separators does not appear to work with FLY files.==&lt;br /&gt;
Whether set to true or false, the hyphen still shows up, and does not join the words together, as in latest e-mail, reproduced below:&lt;br /&gt;
&lt;br /&gt;
So sometimes SF texters, for whatever reason. split words on syllable boundaries. However, there is no clear delineation, like with KTP, or how to rejoin them. So I figured I could find those leading syllables, add a hyphen in the fly file, and trick kJams into stitching them back together. For instance, the following:&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo&amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which should be &amp;quot;losing&amp;quot; but shows as &amp;quot;lo sing&amp;quot;, and changing it to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;6&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;3&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;9&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;117&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;136&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;lo- &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeMinutes&amp;gt;0&amp;lt;/hiliteStartATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeSeconds&amp;gt;23&amp;lt;/hiliteStartATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteStartATimeFrames&amp;gt;40&amp;lt;/hiliteStartATimeFrames&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeMinutes&amp;gt;0&amp;lt;/hiliteDurATimeMinutes&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeSeconds&amp;gt;1&amp;lt;/hiliteDurATimeSeconds&amp;gt;&lt;br /&gt;
    &amp;lt;hiliteDurATimeFrames&amp;gt;46&amp;lt;/hiliteDurATimeFrames&amp;gt;&lt;br /&gt;
  &amp;lt;/dtIcdgEventText&amp;gt;&lt;br /&gt;
  &amp;lt;dtIcdgEventText&amp;gt;&lt;br /&gt;
    &amp;lt;TextID&amp;gt;7&amp;lt;/TextID&amp;gt;&lt;br /&gt;
    &amp;lt;HeaderID&amp;gt;0&amp;lt;/HeaderID&amp;gt;&lt;br /&gt;
    &amp;lt;PageID&amp;gt;3&amp;lt;/PageID&amp;gt;&lt;br /&gt;
    &amp;lt;orderPageTLBR&amp;gt;4&amp;lt;/orderPageTLBR&amp;gt;&lt;br /&gt;
    &amp;lt;orderGlobal&amp;gt;10&amp;lt;/orderGlobal&amp;gt;&lt;br /&gt;
    &amp;lt;StartX&amp;gt;136&amp;lt;/StartX&amp;gt;&lt;br /&gt;
    &amp;lt;StartY&amp;gt;521&amp;lt;/StartY&amp;gt;&lt;br /&gt;
    &amp;lt;EndX&amp;gt;187&amp;lt;/EndX&amp;gt;&lt;br /&gt;
    &amp;lt;EndY&amp;gt;553&amp;lt;/EndY&amp;gt;&lt;br /&gt;
    &amp;lt;VoiceID&amp;gt;1&amp;lt;/VoiceID&amp;gt;&lt;br /&gt;
    &amp;lt;LyricText&amp;gt;sing &amp;lt;/LyricText&amp;gt;&lt;br /&gt;
&lt;br /&gt;
which SHOULD be &amp;quot;losing&amp;quot; (Syllables stitched together by kJams) but instead shows up as &amp;quot;lo-sing&amp;quot; (no white space).&lt;br /&gt;
&lt;br /&gt;
What is wrong with my thought process here?&lt;/div&gt;</summary>
		<author><name>Deusexmachina</name></author>
	</entry>
</feed>