update

update

FasdUAS 1.101.10
k
l  "Terminal" ׼		& TJ "Terminal" PZY}QY

l7
O7

k6
I
.coredoscnullctxt
m
l

 ǰӦ T/R_SRM^u(
I

.miscactvnullnull
l3- õһΪҪִвĴ. fRn{,NN*zSO\N:cNgebgLdO\vzS !
 r"#
"4$

cwin
$v%%&
&m
#o0win!'(
'l)*) õǰ Tab*++ n_SRMv Tab(,-
,r./
.n01
01

tcnt
1o0win
/o0
currenttab
currentTab-23
2l454&  ڵǰ Tab ִиıĿ¼Ĳ566& W(_SRM Tab N-bgLe9Sv_UvdO\378
7I&9:
.coredoscnullctxt
9m ;;<<8cd ~/Library/Developer/Xcode:=

kfil
=o!"0
currenttab
currentTab8>?
>l''@A@ ӳABB ^?CD
CI',E
.sysodelanullnmbr
Em'(DFG
Fl--HIH ִĲIJJ bgLnd[XvdO\GKL
KI-4MN
.coredoscnullctxt
Mm-.OOPP(rm -rf DerivedData/ NQ

kfil
Qo/00
currenttab
currentTabLR
Rl55

mSS@alislMacintosh HDH+XTerminal.app]PS	 	UtilitiesPXZ2Macintosh HD:Applications:Utilities:Terminal.appTerminal.appMacintosh HD#Applications/Utilities/Terminal.app/TUT
.aevtoappnull****UVWX
.aevtoappnull****
Vk7YY
WXS;O
.coredoscnullctxt
.miscactvnullnull

cwin0win

tcnt0
currenttab
currentTab

kfil
.sysodelanullnmbr84jO*jO*jk
/EO,EOlOkj
OlOPUascr
ޭ

FasdUAS 1.101.10
k
l  "Terminal" ׼		& TJ "Terminal" PZY}QY

l1
O1

k0
I
.coredoscnullctxt
m
l

 ǰӦ T/R_SRM^u(
I

.miscactvnullnull
l3- õһΪҪִвĴ. fRn{,NN*zSO\N:cNgebgLdO\vzS !
 r"#
"4$

cwin
$v%%&
&m
#o0win!'(
'l)*) õǰ Tab*++ n_SRMv Tab(,-
,r./
.n01
01

tcnt
1o0win
/o0
currenttab
currentTab-23
2l454&  ڵǰ Tab ִиıĿ¼Ĳ566& W(_SRM Tab N-bgLe9Sv_UvdO\378
7I&9:
.coredoscnullctxt
9m ;;<<8cd ~/Library/Developer/Xcode:=

kfil
=o!"0
currenttab
currentTab8>?
>l''@A@ ִĲABB bgLnd[XvdO\?CD
CI'.EF
.coredoscnullctxt
Em'(GGHH(rm -rf DerivedData/ FI

kfil
Io)*0
currenttab
currentTabDJ
Jl//

mKK@alislMacintosh HDH+XTerminal.app]PS	 	UtilitiesPXZ2Macintosh HD:Applications:Utilities:Terminal.appTerminal.appMacintosh HD#Applications/Utilities/Terminal.app/LML
.aevtoappnull****MNOP
.aevtoappnull****
Nk1QQ
OPK;G
.coredoscnullctxt
.miscactvnullnull

cwin0win

tcnt0
currenttab
currentTab

kfil2.jO*jO*jk
/EO,EOlOlOPUascr
ޭ


updated getObjectAndSubs to use ensureObjectRef

-- getObjectAndSubs({someObjectRef:null, outputType:"TEXT", maxSubLevel:null, subLevel:0})
-- Daniel A. Shockley & Erik Shagdar, NYHTC
-- Gets detailed UI Scripting info for the specified object, recursively for all sub-objects.

(*
HISTORY:
	1.1 - 2017-06-29 ( dshockley ): added ensureObjectRef.
	1.0 - 2016-10-21 ( dshockley ): first created.

TODO:
	2017-01-12 ( dshockley ): Try to figure out a way to preseve human-friendly class names (without the chevrons)

REQUIRES:
	coerceToString
	ensureObjectRef
	quoteString
	repeatString
*)

on run
	tell application "System Events"
		tell application process "FileMaker Pro Advanced"
			set frontmost to true
			delay 0.5

			-- WARNING!!! If you pick a high (or no) maxSubLevel, it can take a LONG time for objects with many sub-objects.
			set objectString to my getObjectAndSubs({someObjectRef:window 1, maxSubLevel:4})

			set the clipboard to objectString

			return objectString
		end tell
	end tell
end run

--------------------
-- START OF CODE
--------------------

on getObjectAndSubs(prefs)
	-- version 1.1

	set defaultPrefs to {someObjectRef:null, outputType:"TEXT", maxSubLevel:null, subLevel:0}
	(*
		Other options:
		  outputType:"TEXT", "Record"
	*)

	set prefs to prefs & defaultPrefs

	set someObjectRef to someObjectRef of prefs
	set outputType to outputType of prefs
	set maxSubLevel to maxSubLevel of prefs
	set subLevel to subLevel of prefs

	set someObjectRef to ensureObjectRef(someObjectRef)

	set indentString to my repeatString({someString:tab, repeatCount:subLevel})
	set subIndentString to my repeatString({someString:tab, repeatCount:subLevel + 1})

	tell application "System Events"

		set thisObjectInfo to properties of someObjectRef

		try
			set thisObjClass to class of someObjectRef
		end try
		try
			set thisObjectName to name of someObjectRef
		end try

		if maxSubLevel is null then
			set doSub to true
		else if subLevel is greater than or equal to maxSubLevel then
			set doSub to false
		else
			set doSub to true
		end if

		if not doSub then
			set thisSubObjectList to null
		else

			try
				set subObjects to UI elements of someObjectRef

				(*
				if subLevel is 1 then
					tell me to activate
					display dialog my coerceToString(someObjectRef)
					display dialog "subObjects : " & my coerceToString(subObjects)
					display dialog (length of indentString) as string
					error -128
				end if
				*)

				if outputType is "Record" then
					set thisSubObjectList to {}
				else if outputType is "TEXT" then
					if (count of subObjects) is 0 then
						set thisSubObjectList to "{}"
					else
						set subList_START to "{ " & return & subIndentString & ""
						set subList_BeforeEach to return & subIndentString
						set subList_BetweenAdjacent to ", " & return & subIndentString & ""
						set thisSubObjectList to subList_START
						set subObjectsListHasItems to false

					end if
				end if

				if (count of subObjects) is greater than 0 then

					repeat with oneSubObject in subObjects
						set subObjectInfo to my getObjectAndSubs({someObjectRef:oneSubObject, subLevel:subLevel + 1} & prefs)
						if outputType is "Record" then
							copy subObjectInfo to end of thisSubObjectList
						else if outputType is "TEXT" then
							if subObjectsListHasItems then
								set thisSubObjectList to thisSubObjectList & subList_BetweenAdjacent
							else
								set subObjectsListHasItems to true
							end if
							set thisSubObjectList to thisSubObjectList & subList_BeforeEach & subObjectInfo
						end if
					end repeat

					-- had sub-objects, so need to put on ending string:
					if outputType is "TEXT" then
						set thisSubObjectList to thisSubObjectList & "" & return & indentString & "}"
					end if
				end if

			on error errMsg number errNum
				if errNum is -128 then error -128
				-- had no sub-objects, so list will be/remain empty
				if outputType is "TEXT" then set thisSubObjectList to "missing value"
			end try

		end if

		if outputType is "Record" then
			return {objClass:thisObjClass, objName:thisObjectName, objRef:someObjectRef, objInfo:thisObjectInfo, subObjList:thisSubObjectList}
		else if outputType is "TEXT" then

			(*  CANNOT make uppercase until we figure out how to preserve classes without chevrons... 2016-10-21 ( dshockley )
			-- make the class uppercase for legibility:
			set thisObjClass to my coerceToString(thisObjClass)
			set thisObjClass to do shell script "echo " & quoted form of thisObjClass & " | tr [:lower:] [:upper:]"
			*)

			set resultString to ""
			set resultString to resultString &
				"{objClass: " & my coerceToString(thisObjClass) & ", "

			set resultString to resultString & return &
				indentString & "objName: " & my quoteString(thisObjectName) & ", "

			set resultString to resultString & return &
				indentString & "objRef: " & my coerceToString(someObjectRef) & ", "

			set resultString to resultString & return &
				indentString & "objInfo: " & my coerceToString(thisObjectInfo) & ", "

			if thisSubObjectList is null then
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
			else if (count of thisSubObjectList) is 0 then
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
			else
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
				(*
					set resultString to resultString & return &
					indentString & "subObjList: " & return & thisSubObjectList & " "
				*)

			end if

			set resultString to resultString & return & indentString & "}"

			return resultString

		end if

	end tell

end getObjectAndSubs

--------------------
-- END OF CODE
--------------------

on coerceToString(incomingObject)
	tell application "htcLib" to coerceToString(incomingObject)
end coerceToString

on ensureObjectRef(someObject)
	tell application "htcLib" to ensureObjectRef(someObject)
end ensureObjectRef

on quoteString(someString)
	tell application "htcLib" to quoteString(someString)
end quoteString

on repeatString(prefs)
	tell application "htcLib" to repeatString(prefs)
end repeatString

-- getObjectAndSubs({someObjectRef:null, outputType:"TEXT", maxSubLevel:null, subLevel:0})
-- Daniel A. Shockley & Erik Shagdar, NYHTC
-- Gets detailed UI Scripting info for the specified object, recursively for all sub-objects.

(*
HISTORY:
	1.0 - 2016-10-21 ( dshockley ): first created.

TODO:
	2017-01-12 ( dshockley ): Try to figure out a way to preseve human-friendly class names (without the chevrons)

REQUIRES:
	coerceToString
	quoteString
	repeatString
*)

on run
	tell application "System Events"
		tell application process "FileMaker Pro Advanced"
			set frontmost to true
			delay 0.5

			-- WARNING!!! If you pick a high (or no) maxSubLevel, it can take a LONG time for objects with many sub-objects.
			set objectString to my getObjectAndSubs({someObjectRef:window 1, maxSubLevel:4})

			set the clipboard to objectString

			return objectString
		end tell
	end tell
end run

--------------------
-- START OF CODE
--------------------

on getObjectAndSubs(prefs)
	-- version 1.0

	set defaultPrefs to {someObjectRef:null, outputType:"TEXT", maxSubLevel:null, subLevel:0}
	(*
		Other options:
		  outputType:"TEXT", "Record"
	*)

	set prefs to prefs & defaultPrefs

	set someObjectRef to someObjectRef of prefs
	set outputType to outputType of prefs
	set maxSubLevel to maxSubLevel of prefs
	set subLevel to subLevel of prefs

	set indentString to my repeatString({someString:tab, repeatCount:subLevel})
	set subIndentString to my repeatString({someString:tab, repeatCount:subLevel + 1})

	tell application "System Events"

		set thisObjectInfo to properties of someObjectRef

		try
			set thisObjClass to class of someObjectRef
		end try
		try
			set thisObjectName to name of someObjectRef
		end try

		if maxSubLevel is null then
			set doSub to true
		else if subLevel is greater than or equal to maxSubLevel then
			set doSub to false
		else
			set doSub to true
		end if

		if not doSub then
			set thisSubObjectList to null
		else

			try
				set subObjects to UI elements of someObjectRef

				(*
				if subLevel is 1 then
					tell me to activate
					display dialog my coerceToString(someObjectRef)
					display dialog "subObjects : " & my coerceToString(subObjects)
					display dialog (length of indentString) as string
					error -128
				end if
				*)

				if outputType is "Record" then
					set thisSubObjectList to {}
				else if outputType is "TEXT" then
					if (count of subObjects) is 0 then
						set thisSubObjectList to "{}"
					else
						set subList_START to "{ " & return & subIndentString & ""
						set subList_BeforeEach to return & subIndentString
						set subList_BetweenAdjacent to ", " & return & subIndentString & ""
						set thisSubObjectList to subList_START
						set subObjectsListHasItems to false

					end if
				end if

				if (count of subObjects) is greater than 0 then

					repeat with oneSubObject in subObjects
						set subObjectInfo to my getObjectAndSubs({someObjectRef:oneSubObject, subLevel:subLevel + 1} & prefs)
						if outputType is "Record" then
							copy subObjectInfo to end of thisSubObjectList
						else if outputType is "TEXT" then
							if subObjectsListHasItems then
								set thisSubObjectList to thisSubObjectList & subList_BetweenAdjacent
							else
								set subObjectsListHasItems to true
							end if
							set thisSubObjectList to thisSubObjectList & subList_BeforeEach & subObjectInfo
						end if
					end repeat

					-- had sub-objects, so need to put on ending string:
					if outputType is "TEXT" then
						set thisSubObjectList to thisSubObjectList & "" & return & indentString & "}"
					end if
				end if

			on error errMsg number errNum
				if errNum is -128 then error -128
				-- had no sub-objects, so list will be/remain empty
				if outputType is "TEXT" then set thisSubObjectList to "missing value"
			end try

		end if

		if outputType is "Record" then
			return {objClass:thisObjClass, objName:thisObjectName, objRef:someObjectRef, objInfo:thisObjectInfo, subObjList:thisSubObjectList}
		else if outputType is "TEXT" then

			(*  CANNOT make uppercase until we figure out how to preserve classes without chevrons... 2016-10-21 ( dshockley )
			-- make the class uppercase for legibility:
			set thisObjClass to my coerceToString(thisObjClass)
			set thisObjClass to do shell script "echo " & quoted form of thisObjClass & " | tr [:lower:] [:upper:]"
			*)

			set resultString to ""
			set resultString to resultString &
				"{objClass: " & my coerceToString(thisObjClass) & ", "

			set resultString to resultString & return &
				indentString & "objName: " & my quoteString(thisObjectName) & ", "

			set resultString to resultString & return &
				indentString & "objRef: " & my coerceToString(someObjectRef) & ", "

			set resultString to resultString & return &
				indentString & "objInfo: " & my coerceToString(thisObjectInfo) & ", "

			if thisSubObjectList is null then
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
			else if (count of thisSubObjectList) is 0 then
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
			else
				set resultString to resultString & return &
					indentString & "subObjList: " & thisSubObjectList & " "
				(*
					set resultString to resultString & return &
					indentString & "subObjList: " & return & thisSubObjectList & " "
				*)

			end if

			set resultString to resultString & return & indentString & "}"

			return resultString

		end if

	end tell

end getObjectAndSubs

--------------------
-- END OF CODE
--------------------

on coerceToString(incomingObject)
	tell application "htcLib" to coerceToString(incomingObject)
end coerceToString

on quoteString(someString)
	tell application "htcLib" to quoteString(someString)
end quoteString

on repeatString(prefs)
	tell application "htcLib" to repeatString(prefs)
end repeatString


Added tagging support for Camino

Added tagging support for Camino

FasdUAS 1.101.10
k
l
O
k

l

r
6
n

1

pnam
4

pcap
m
=
1

pisf
m
boovtrue
o0frontappfrontApp
l
l Handle file selection, Handle file selection
r!"
!J
"o0thefilestheFiles #$
#l$%&
%ZM'(
'=)*
)o0frontappfrontApp
*m++,,Finder
(O!I-.
-k%H//01
0r%*23
2l%(4
41%(

sele
3o0
selecteditems
selectedItems15
5X+H67
6s;C89
8l;@:
:n;@;<
;1>@

psxp
<l;>=
=c;>>?
>o;<0theitemtheItem
?m<=

alis
9l@
@nAB
A;AB
Bl@AC
Co@A0thefilestheFiles0theitemtheItem
7o./0
selecteditems
selectedItems
.m!"DDMACSalisVMacÒH+
Finder.appsZ߄	 CoreServicesÒZtQP*Mac:System:Library:CoreServices:Finder.app
Finder.appMac&System/Library/CoreServices/Finder.app/&EF
ElNNFGH
GlNNHIJ
IlNNKLK Handle URL selectionLMM* Handle URL selectionJNO
NlNUPQR
PrNUST
SmNQUUVV
To0theurltheURLQ Declare variableRWW" Declare variableOXY
XlVVYZ[
ZZV\]^
\=V[_`
_oVW0frontappfrontApp
`mWZaabbfirefox-bin
]O^|cd
ckd{eefg
flddhih(" Title is class pTit of window 1ijjD Title is class pTit of window 1gk
krd{lm
lJdwnnop
ocdrqr
qndnst
smjn

curl
t4dju

cwin
umhi
rmnq

TEXTpv
vmruwwxx
mo0theurltheURL
dm^ayyMOZBalis4MacÒH+Firefox.app_t;U	 ApplicationsÒt5Mac:Applications:Firefox.appFirefox.appMacApplications/Firefox.app/^z{
z=|}
|o0frontappfrontApp
}m~~
Opera{
O
r
I
.WWW!WNFOlist@long
4

cwin
m
o0theurltheURL
mOPRAalis,MacÒH+	Opera.appdr	 ApplicationsÒrMac:Applications:Opera.app	Opera.appMacApplications/Opera.app/
=
o0frontappfrontApp
mCamino
O
r
J
n
1

pURL
n
1

pCTb
4

BWin
m
n
1

pTtl
n
1

pCTb
4

BWin
m
o0theurltheURL
mMOZCalis2MacÒH+
Camino.apph+	 ApplicationsÒhMac:Applications:Camino.app
Camino.appMacApplications/Camino.app/
=
o0frontappfrontApp
mSafari
O
r
J
n
1

pURL
4

docu
m
n
1

pnam
4

docu
m
o0theurltheURL
msfrialis2MacÒH+
Safari.app/	 ApplicationsÒMac:Applications:Safari.app
Safari.appMacApplications/Safari.app/[
l
r
J
o0thefilestheFiles
o0theurltheURL
o0results
l

L

o

0results
l
	msevsalistMacÒH+System Events.appc	 CoreServicesÒCQP1Mac:System:Library:CoreServices:System Events.app$System Events.appMac-System/Library/CoreServices/System Events.app/
l
.aevtoappnull****
.aevtoappnull****
k0theitemtheItem%+D~U}ay|{zw~yxwvuts

pcap

pnam

pisf0frontappfrontApp0thefilestheFiles

sele0
selecteditems
selectedItems

kocl

cobj
.corecnte********

alis
~
psxp}0theurltheURL
|
cwin
{
curl
z
TEXT
y.WWW!WNFOlist@long
x
BWin
w
pCTb
v
pURL
u
pTtl
t
docus0results*k/,[,\Ze81EOjvEO-%*,EO[l
kh&,6G[OYUYhOaE`Oa#a*ak/a,a&alvE`UYaa*ak/jE`UYaa.a$*ak/a,a,*ak/a,a ,lvE`UY-a!$a"*a#k/a,*a#k/,lvE`UYhO_lvE`$O_$OPUascr
ޭ

FasdUAS 1.101.10
k
l
O
k

l

r
6
n

1

pnam
4

pcap
m
=
1

pisf
m
boovtrue
o0frontappfrontApp
l
l Handle file selection, Handle file selection
r!"
!J
"o0thefilestheFiles #$
#l$%&
%ZM'(
'=)*
)o0frontappfrontApp
*m++,,Finder
(O!I-.
-k%H//01
0r%*23
2l%(4
41%(

sele
3o0
selecteditems
selectedItems15
5X+H67
6s;C89
8l;@:
:n;@;<
;1>@

psxp
<l;>=
=c;>>?
>o;<0theitemtheItem
?m<=

alis
9l@
@nAB
A;AB
Bl@AC
Co@A0thefilestheFiles0theitemtheItem
7o./0
selecteditems
selectedItems
.m!"DDMACSalisVMacÒH+
Finder.appsZ߄	 CoreServicesÒZtQP*Mac:System:Library:CoreServices:Finder.app
Finder.appMac&System/Library/CoreServices/Finder.app/&EF
ElNNFGH
GlNNHIJ
IlNNKLK Handle URL selectionLMM* Handle URL selectionJNO
NlNUPQR
PrNUST
SmNQUUVV
To0theurltheUrlQ Declare variableRWW" Declare variableOXY
XlVVYZ[
ZZV\]^
\=V[_`
_oVW0frontappfrontApp
`mWZaabbfirefox-bin
]O^|cd
ckd{eefg
flddhih(" Title is class pTit of window 1ijjD Title is class pTit of window 1gk
krd{lm
lJdwnnop
ocdrqr
qndnst
smjn

curl
t4dju

cwin
umhi
rmnq

TEXTpv
vmruwwxx
mo0theurltheUrl
dm^ayyMOZBalis4MacÒH+Firefox.app_t;U	 ApplicationsÒt5Mac:Applications:Firefox.appFirefox.appMacApplications/Firefox.app/^z{
z=|}
|o0frontappfrontApp
}m~~
Opera{
O
r
I
.WWW!WNFOlist@long
4

cwin
m
o0theurltheUrl
mOPRAalis,MacÒH+	Opera.appdr	 ApplicationsÒrMac:Applications:Opera.app	Opera.appMacApplications/Opera.app/
=
o0frontappfrontApp
mSafari
O
r
J
n
1

pURL
4

docu
m
n
1

pnam
4

docu
m
o0theurltheUrl
msfrialis2MacÒH+
Safari.app/	 ApplicationsÒMac:Applications:Safari.app
Safari.appMacApplications/Safari.app/[
l
r
J
o0thefilestheFiles
o0theurltheUrl
o0results
l
L
o0results
l
	msevsalistMacÒH+System Events.appc	 CoreServicesÒCQP1Mac:System:Library:CoreServices:System Events.app$System Events.appMac-System/Library/CoreServices/System Events.app/
l
.aevtoappnull****
.aevtoappnull****
k0theitemtheItem +DUayw~

pcap

pnam

pisf0frontappfrontApp0thefilestheFiles

sele0
selecteditems
selectedItems

kocl

cobj
.corecnte********

alis

psxp0theurltheUrl

cwin

curl

TEXT
.WWW!WNFOlist@long

docu

pURL0results*k/,[,\Ze81EOjvEO-%*,EO[l
kh&,6G[OYUYhOaE`Oa#a*ak/a,a&alvE`UYMaa*ak/jE`UY-a$a*ak/a,*ak/,lvE`UYhO_lvE`O_OPUascr
ޭ


Complete refactoring! Solving issue #2

Complete refactoring! Solving issue #2

All code is rewritten and tidied up from the ground up. Commented
everything.
(issue #2) Spotify is no longer getting unpaused when it is paused on
an ad.

FasdUAS 1.101.10
k
l
j
0playing

m
****kPSPpj Setting the "playing" property to the constant returned by Spotify as a "player state" when it's playing.	 Setting the "playing" property to the constant returned by Spotify as a "player state" when it's playing.

l

l\
Z\
l
=
I 0isinloginitemsisInLoginItems
mSpotiFree
m6:Applications:SpotiFree.app
m
boovfals
lX
kX!!"#
"q$$%0dialogtitledialogTitle%&0
dialogmessage
dialogMessage&'"0dialogbuttonyesdialogButtonYes'("0dialogbuttonyesdialogButtonYes()$0spotifreeappnamespotifreeAppName)$0spotifreeapppathspotifreeAppPath#*+
*r,-
,m
..//SpotiFree
-o$0spotifreeappnamespotifreeAppName+01
0r23
2m44556:Applications:SpotiFree.app
3o$0spotifreeapppathspotifreeAppPath167
6r89
8m::;;.Open SpotiFree at login
9o0dialogtitledialogTitle7<=
<r>?
>m@@AADo you want SpotiFree to run automatically on startup? You'll never notice it, seriously.
?o0
dialogmessage
dialogMessage=BC
BrDE
DmFFGGNo, thanks
Eo 0dialogbuttonnodialogButtonNoCHI
Hr #JK
Jm !LLMMOK
Ko"0dialogbuttonyesdialogButtonYesINO
Nl$$OPQ
Pl$8RST
Rr$8UV
Ul$4W
WI$4XY
.sysodlogaskrTEXT
Xo$%0
dialogmessage
dialogMessageYZ[

appr
Zo&'0dialogtitledialogTitle[\]

disp
\m()]^_

btns
^J*.``ab
ao*+ 0dialogbuttonnodialogButtonNobc
co+,"0dialogbuttonyesdialogButtonYes_d

dflt
dm/0
Vo,0runatstartupquestionrunAtStartupQuestionS  Run the dialog to a user.Tee4 Run the dialog to a user.Qfg
fl9Dhij
hr9Dkl
kl9@m
mn9@no
n1<@

bhit
oo9<,0runatstartupquestionrunAtStartupQuestion
lo(0runatstartupanswerrunAtStartupAnsweri<6 Assign the result to the variable runAtStartupAnswer.jppl Assign the result to the variable runAtStartupAnswer.gq
qZEXrs
rlEJt
t=EJuv
uoEH(0runatstartupanswerrunAtStartupAnswer
voHI"0dialogbuttonyesdialogButtonYes
slMTwxy
wlMTz{|
znMT}~
}INT"0addtologinitemsaddToLoginItems
oNO$0spotifreeappnamespotifreeAppName
oOP$0spotifreeapppathspotifreeAppPath
~fMN{(" Add SpotiFree to the Login Items.|D Add SpotiFree to the Login Items.x Check if user agreed.y, Check if user agreed.)# Check if SpotiFree is login items. F Check if SpotiFree is login items.
l
l]
T]
kb
Qb
Ze
lev
Fev
Iej0	isrunning	isRunning
Imr0	isplaying	isPlaying
ly
ky
qyy0
currentvolume
currentVolume00currenttrackpopularitycurrentTrackPopularity,0currenttrackdurationcurrentTrackDuration,0currenttrackpositioncurrentTrackPosition
Oy
k
l
r
1

pVol
o0
currentvolume
currentVolume Get the current sound volume from Spotify and save it in a variable currentVolume. To prevent shocking a user with the volume of 100 when he had set it to 20.> Get the current sound volume from Spotify and save it in a variable currentVolume. To prevent shocking a user with the volume of 100 when he had set it to 20.
l
r
n
1

spPo
1

pTrk
o00currenttrackpopularitycurrentTrackPopularity^X Get the popularity of a current track and save it in a variable currentTrackPopularity. Get the popularity of a current track and save it in a variable currentTrackPopularity.
l
r
n
1

pDur
1

pTrk
o,0currenttrackdurationcurrentTrackDurationXR Get the duration of current track and save it in a variable currentTrackDuration. Get the duration of current track and save it in a variable currentTrackDuration.
l
r
1

pPos
o,0currenttrackpositioncurrentTrackPositionUO Get the current track position and save it in a variable currentTrackPosition. Get the current track position and save it in a variable currentTrackPosition.
my|sptyalisT
Mountain LioncYH+tSpotify.app	5.	 Applicationsc)t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/
l
Z
l
I0isanadisAnAd
o00currenttrackpopularitycurrentTrackPopularity
o,0currenttrackdurationcurrentTrackDuration
l
l
I0mutespotifymuteSpotify
o0
currentvolume
currentVolume
o,0currenttrackdurationcurrentTrackDuration
o,0currenttrackpositioncurrentTrackPosition'! If it's an ad, mute it to death!B If it's an ad, mute it to death!2, Check if current track is an advertisement.X Check if current track is an advertisement.)# Is Spotify running? Is it playing?F Is Spotify running? Is it playing?
R
.ascrerr ********
l
I
.sysodelanullnmbr
m?3333331+ Repeat this entire block every .3 seconds.V Repeat this entire block every .3 seconds.
l
i
I0mutespotifymuteSpotify
o0
currentvolume
currentVolume
o"0currentdurationcurrentDuration~
o}}"0currentpositioncurrentPosition~
Q7|
k.
O
k
I{zy
{.spfyPausnullnullzy
r

m
xx
1w
w
pVolv
Iuts
u.spfyPlaynullnulltsv
msptyalisT
Mountain LioncYH+tSpotify.app	5.	 Applicationsc)t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/
l#
I#r
q
r.sysodelanullnmbr

[
\

opp"0currentdurationcurrentDuration
ooo"0currentpositioncurrentPosition
mnnq<6 Wait until the end of an ad. Then run the code below.	l Wait until the end of an ad. Then run the code below.m
O$.
l(-
r(-
o()ll0
currentvolume
currentVolume
1),k
k
pVol4. Restore the volume to the level it was before\ Restore the volume to the level it was before
m$%sptyalisT
Mountain LioncYH+tSpotify.app	5.	 Applicationsc)t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/m
Rjih
j.ascrerr ********ih|
lgfegfe
i

Id cd0isanadisAnAd !"
!obb"0trackpopularitytrackPopularity"#a
#o``0
trackduration
trackDurationac
Q!$%_
$Z&'^(
&l)]\
)F*+
*=,-
,o[["0trackpopularitytrackPopularity
-mZZ
+A	./
.o
YY0
trackduration
trackDuration
/m
XX(]\
'l012
0L3
3mW
Wboovtrue1} If popularity is 0 and duration of current track is less then 40, then it's almost certainly an ad. If it is, return "true".244 If popularity is 0 and duration of current track is less then 40, then it's almost certainly an ad. If it is, return "true".^
(L5
5mV
Vboovfals
%RUTS
U.ascrerr ********TS_67
6lRQPRQP789
8i:;
:IONMO0	isplaying	isPlayingNM
;k*<<=>
=q??LKL0playerstateplayerStateK>@A
@Q(BCJ
BkDDEF
EO
GH
GlIJK
IrLM
L1
I
I
pPlS
MoHH0playerstateplayerStateJOI Hook the variable playerState to Spotify's state (playing, paused etc.).KNN Hook the variable playerState to Spotify's state (playing, paused etc.).
HmOOsptyalisT
Mountain LioncYH+tSpotify.app	5.	 Applicationsc)t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/FPQ
PlGFEGFEQRD
RZSTCU
S=VW
VoBB0playerstateplayerState
WoAA0playing
TlXYZ
XL[
[m@
@boovtrueYOI Compare Spotify's state with a constant saved in the property on line 1.Z\\ Compare Spotify's state with a constant saved in the property on line 1.C
UL]
]m?
?boovfalsD
CR>=<
>.ascrerr ********=<JA^;
^l)):98:98;9_`
_l765765`ab
aicd
cI43240	isrunning	isRunning32
dk3eefg
fqhh101$0spotifyprocessesspotifyProcesses0gi/
iQ3jk.
jk*llmn
mOop
olqrs
qrtu
tcvw
vlx-,
xI+y*
+.corecnte********
ylz)(
z6{|
{2
'
'
prcs
|=}~
}1&
&
bnid
~m$com.spotify.client)(*-,
wm%
%
TEXT
uo$$$0spotifyprocessesspotifyProcessesr0* Check if there are any Spotify processes.sT Check if there are any Spotify processes.
pmsevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/n
l#"!#"!
Z*
?
o$0spotifyprocessesspotifyProcesses
m
l#%
L#%
m#$
boovtrue# If there are, return "true".: If there are, return "true".
L(*
m()
boovfals
kR
.ascrerr ********./b
l
i
I 0isinloginitemsisInLoginItems
o0appnameappName
k(
q0
allloginitems
allLoginItems
Q(

k
l
O
r
c
n
1

pnam
2

logi
m

TEXT
o		0
allloginitems
allLoginItems
msevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/# Get all apps in Login Items.: Get all apps in Login Items.
Z
E
o0
allloginitems
allLoginItems
o0appnameappName
l
L
m
boovtrueB< Check if inputted app is in there. If it is, return "true".x Check if inputted app is in there. If it is, return "true".
L
m
boovfals
R
.ascrerr ********

l
i
I"0addtologinitemsaddToLoginItems
o0appnameappName
o0apppathappPath
k)
q0posixapppathposixAppPath
Q)
k
l
r
n
1

psxp
4

alis
o0apppathappPath
o0posixapppathposixAppPathTN Get the POSIX (Portable Operating System Interface) path of inputted appPath. Get the POSIX (Portable Operating System Interface) path of inputted appPath.
O
l
I
.corecrel****null
m

logi

insh
;

prdt
K

ppth
o0posixapppathposixAppPath

hidn
m
boovtrue+% Add inputted app to the Login Items.J Add inputted app to the Login Items.
m
sevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/
R
.ascrerr ********
0playing0mutespotifymuteSpotify0isanadisAnAd0	isplaying	isPlaying0	isrunning	isRunning 0isinloginitemsisInLoginItems"0addtologinitemsaddToLoginItems
.aevtoappnull****
****kPSP0mutespotifymuteSpotify0
currentvolume
currentVolume"0currentdurationcurrentDuration"0currentpositioncurrentPosition0
currentvolume
currentVolume"0currentdurationcurrentDuration"0currentpositioncurrentPosition
.spfyPausnullnull

pVol
.spfyPlaynullnull
.sysodelanullnmbr80*jOj*,FO*jUOkjO*,FUWXh0isanadisAnAd"0trackpopularitytrackPopularity0
trackduration
trackDuration"0trackpopularitytrackPopularity0
trackduration
trackDuration(

bool"j	&eYfWXh;0	isplaying	isPlaying0playerstateplayerStateO

pPlS+!*,EUObeYfWXhOPd0	isrunning	isRunning$0spotifyprocessesspotifyProcesses

prcs

bnid
.corecnte********

TEXT4,*-[,\Z81j&EUOjeYfWXh 0isinloginitemsisInLoginItems0appnameappName0appnameappName0
allloginitems
allLoginItems

logi

pnam

TEXT)!*-,&EUOeYfWXh"0addtologinitemsaddToLoginItems0appnameappName0apppathappPath0appnameappName0apppathappPath0posixapppathposixAppPath

alis

psxp

logi

insh

prdt

ppth

hidn
.corecrel****null*"*/,EO*6e	UWX
h
.aevtoappnull****
k	~}|{zyxwv~0dialogtitledialogTitle}0
dialogmessage
dialogMessage|"0dialogbuttonyesdialogButtonYes{$0spotifreeappnamespotifreeAppNamez$0spotifreeapppathspotifreeAppPathy0
currentvolume
currentVolumex00currenttrackpopularitycurrentTrackPopularityw,0currenttrackdurationcurrentTrackDurationv,0currenttrackpositioncurrentTrackPosition#u.4:@FtLsrqponmlkjihgfedcba`_^]u 0isinloginitemsisInLoginItemst 0dialogbuttonnodialogButtonNo
s
appr
r
disp
q
btns
p
dflto
n.sysodlogaskrTEXTm,0runatstartupquestionrunAtStartupQuestion
l
bhitk(0runatstartupanswerrunAtStartupAnswerj"0addtologinitemsaddToLoginItemsi0	isrunning	isRunningh0	isplaying	isPlaying
g
bool
f
pVol
e
pTrk
d
spPo
c
pDur
b
pPosa0isanadisAnAd`0mutespotifymuteSpotify_^
].sysodelanullnmbr*l+fQEOEOEOEOEOEOkȢlvlE`O_a,E`O_)l+YhYhOzhZb*j+	*j+a&Ja)*a,EO*a,a,EO*a,a,EO*a,EUO*l+
*m+YhYhWX hOa!j"[OYascrޭ

FasdUAS 1.101.10
k
i
I	40checkifappisinloginitemscheckIfAppIsInLoginItems

o0appnameappName
o0	pathofapp	pathOfApp
Q,

k
O
r
c
n
1

pnam
2

logi
m

TEXT
o0
allloginitems
allLoginItems
msevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/
Z
E !
 o0
allloginitems
allLoginItems
!o0appnameappName
L"
"m
boovtrue
L#
#m
boovfals
R$%
.ascrerr ********
$l&
&o0
error_message%'

errn
'l(
(o0error_number
I',)
.sysodelanullnmbr
)m'(**?+,
+l,-.
-i/0
/I1(0addapptologinitemsaddAppToLoginItems123
2o0appnameappName34
4o0	pathofapp	pathOfApp
0Q-567
5k 889:
9r;<
;n	=>
=1

psxp
>4?

alis
?o0	pathofapp	pathOfApp
<o0apppathappPath:@
@O AB
AICD
.corecrel****null
Cm

logiDEF

insh
E;FG

prdt
GKHHIJ

ppth
Io0apppathappPathJK

hidn
Km
boovtrue
Bm
LLsevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/
6RMN
.ascrerr ********
Mo0
error_messageNO

errn
OlP
Po0error_number
7l(-QRS
QI(-T
.sysodelanullnmbr
Tm()UU?ROn any errorSVVOn any error.WX
WlXYZ
Yl[
[r\]
\l^
^m__``6:Applications:SpotiFree.app
]o0my_pathZab
albcd
clFe
eZFfg
fl
h
h=
ij
iIk40checkifappisinloginitemscheckIfAppIsInLoginItemsklm
lmnnooSpotiFreemp
po0my_path
jm
boovfals
gkBqqrs
rr"tu
tl v
vI wx
.sysodlogaskrTEXT
wmyyzzDo yo want SpotiFree to run automatically on startup? You'll never notice it, seriously.x{|

appr
{m}}~~.Open SpotiFree at login|

disp
m

btns
J
mNo, thanks
mOK

dflt
m
uo,0runatstartupquestionrunAtStartupQuestions
r#*
l#&
n#&
1$&

bhit
o#$,0runatstartupquestionrunAtStartupQuestion
o(0runatstartupanswerrunAtStartupAnswer
Z+B
l+2
=+2
o+.(0runatstartupanswerrunAtStartupAnswer
m.1OK
n5>
I6>(0addapptologinitemsaddAppToLoginItems
m69SpotiFree
o9:0my_path
f56d
l
lGG
TGG
kLB
OLq
rRp
?Rl
lRj
IRj
.corecnte********
lRf
6Rf
2RW

prcs
=Ze
1[_

bnid
m`d$com.spotify.client
mjk
o0	isrunning	isRunning
mLOsevsalis
Mountain LioncYH+sSystem Events.app0(	 CoreServicesc)sss>Mountain Lion:System:Library:CoreServices:System Events.app$System Events.app
Mountain Lion-System/Library/CoreServices/System Events.app/
ZrB
oru0	isrunning	isRunning
Qx8
l{)
k{)
O{
k
lSetting variables"Setting variables
r
1

pVol
o~~0cur_vol
r
n
1}
}
pTrN
1|
|
pTrk
o{{
0trackk
r
n
1z
z
pnam
1y
y
pTrk
oxx	0namme
r
n
1w
w
spPo
1v
v
pTrk
ouu0pop
r
n
1t
t
pDur
1s
s
pTrk
orr0durq
r
1p
p
pPos
ooo0posq
m{~sptyalisT
Mountain LioncYH+tSpotify.app	6̜	 Applicationsc)̜t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/
lnmlnml
Z'k
F
=
ojj0pop
mii
A
ohh0dur
mgg(
l
k
O
l
k

	Ifed
f.spfyPausnullnulled

r

mcc
1b
b
pVola
I`_^
`.spfyPlaynullnull_^aDo our thingDo our thing
msptyalisT
Mountain LioncYH+tSpotify.app	6̜	 Applicationsc)̜t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/
l
I]\
].sysodelanullnmbr
[
\
o[[0dur
oZZ0pos
mYY\When an ad ends, When an ad ends,X
O

l !"
 r#$
#oWW0cur_vol
$1V
V
pVol!3-restore the volume to the level it was before"%%Zrestore the volume to the level it was before
m
&&sptyalisT
Mountain LioncYH+tSpotify.app	6̜	 Applicationsc)̜t'Mountain Lion:Applications:Spotify.appSpotify.app
Mountain LionApplications/Spotify.app/XF@If popularity is 0 and duration of current track is less then 40''If popularity is 0 and duration of current track is less then 40k
l '()*
(I 'U+T
U.sysodelanullnmbr
+m #,,?T)lfIf nothing worked (it must be a music track, not an ad), try and run this script again in 0.5 seconds.*--If nothing worked (it must be a music track, not an ad), try and run this script again in 0.5 seconds..S
.l((RQPRQPSNHTry to do this thing, and on error... (look at "on error" at the bottom)//Try to do this thing, and on error... (look at "on error" at the bottom)
RO0N
O.ascrerr ********
0oMM0errormessageerrorMessageN
l18123
1l18456
4I18L7K
L.sysodelanullnmbr
7m1488?K5*$Run this script again in 0.5 seconds699HRun this script again in 0.5 seconds2
On any error 3::On any error
I;BJ;I
J.sysodelanullnmbr
;m;><<?IH=>?@H=GFEG40checkifappisinloginitemscheckIfAppIsInLoginItemsF(0addapptologinitemsaddAppToLoginItems
E.aevtoappnull****>DCBABAD40checkifappisinloginitemscheckIfAppIsInLoginItemsC@C@C?>?0appnameappName>0	pathofapp	pathOfAppBA=<;:9=0appnameappName<0	pathofapp	pathOfApp;0
allloginitems
allLoginItems:0
error_message90error_numberB8765D*4
8
logi
7
pnam
6
TEXT50
error_messageD321
3
errn20error_number1
4.sysodelanullnmbrA-!*-,&EUOeYfWXj?00/.EF-0(0addapptologinitemsaddAppToLoginItems/,G,G+*+0appnameappName*0	pathofapp	pathOfApp.E)('&%)0appnameappName(0	pathofapp	pathOfApp'0apppathappPath&0
error_message%0error_numberF$#L"! HU
$
alis
#
psxp
"
logi
!
insh

prdt

ppth

hidn
.corecrel****null0
error_messageH

errn0error_number
.sysodelanullnmbr-."*/,EO*6e	UWX
j
@IJK
.aevtoappnull****
IkGLLYMMcNNJ0errormessageerrorMessageK1_ny}

	O,0my_path40checkifappisinloginitemscheckIfAppIsInLoginItems

appr

disp

btns

dflt

	.sysodlogaskrTEXT,0runatstartupquestionrunAtStartupQuestion

bhit(0runatstartupanswerrunAtStartupAnswer(0addapptologinitemsaddAppToLoginItems

prcsO

bnid
.corecnte********0	isrunning	isRunning

pVol0cur_vol

pTrk

pTrN
0trackk

pnam	0namme

spPo0pop

pDur0dur

pPos0pos(

bool
.spfyPausnullnull
.spfyPlaynullnull
.sysodelanullnmbr0errormessageerrorMessageHEO*l+f7klvl
EO,E`O_a)al+YhYhOhZa *a-a[a,\Za81jjE`UO_aM*a,E`O*a,a,E` O*a,a!,E`"O*a,a#,E`$O*a,a%,E`&O*a',E`(UO_$j
_&a)a*&>a*j+Oj*a,FO*j,UO_&_(kj-Oa_*a,FUY	a.j-OPWX/0a.j-Y	a.j-[OYascr
ޭ