OS X Automation Update What’s New in Automation

Session 417 Sal Soghoian Chris Nebel Product Manager Automation Technologies Senior Automation Engineer

These are confidential sessions—please refrain from streaming, blogging, or taking pictures What You Will Learn What’s new in Automation? What You Will Learn What’s new in Automation? • AppleScript and Automator What You Will Learn What’s new in Automation? • AppleScript and Automator ■ Dramatic new features What You Will Learn What’s new in Automation? • AppleScript and Automator ■ Dramatic new features ■ Multicomputer file access What You Will Learn What’s new in Automation? • AppleScript and Automator ■ Dramatic new features ■ Multicomputer file access ■ Security transparency What You Will Learn What’s new in Automation? • AppleScript and Automator ■ Dramatic new features ■ Multicomputer file access ■ Security transparency ■ New OS X Integration What You Will Learn What’s new in Automation? • AppleScript and Automator ■ Dramatic new features ■ Multicomputer file access ■ Security transparency ■ New OS X Integration ■ Getting your computer to pay attention iCloud Support Documents in the Cloud iCloud iCloud iCloud iCloud

iCloud Support Documents in the Cloud • Automator and AppleScript Editor • Organize script, workflow, and service collections • Search cloud and local collections by tags • Distribute items across computers iCloud Support Documents in the Cloud • Automator and AppleScript Editor • Organize script, workflow, and service collections • Search cloud and local collections by tags • Distribute items across computers iCloud Support Documents in the Cloud • Automator and AppleScript Editor • Organize script, workflow, and service collections iCloud Support Documents in the Cloud • Automator and AppleScript Editor • Organize script, workflow, and service collections • Search cloud and local collections by tags iCloud Support Documents in the Cloud • Automator and AppleScript Editor • Organize script, workflow, and service collections • Search cloud and local collections by tags • Distribute items across computers Automation Applets and Security Identifying Applets and Droplets

Automation Applets and Security

• Automator and AppleScript applets/droplets are applications Automation Applets and Security

• Automator and AppleScript applets/droplets are applications

= Automation Applets and Security

• Automator and AppleScript applets/droplets are applications

= Automation Applets and Security

• Automator and AppleScript applets/droplets are applications Automation Applets and Security

• Automator and AppleScript applets/droplets are applications • Require code signing to be compatible with Gatekeeper Automation Applets and Security

• Automator and AppleScript applets/droplets are applications • Require code signing to be compatible with Gatekeeper Code Signing Integration Applets Signed on Export Code Signing Integration Applets Signed on Export • Automator—AppleScript Editor Code Signing Integration Applets Signed on Export • Automator—AppleScript Editor • Requires installed identity certificate Code Signing Integration Applets Signed on Export • Automator—AppleScript Editor • Requires installed Apple Developer identity certificate • UNIX tools

Demo Code Signing

Chris Nebel Senior Automation Engineer Code Signing Applets and Droplets • Automator and AppleScript applets/droplets are applications Code Signing Applets and Droplets • Automator and AppleScript applets/droplets are applications • Code Sign for default Gatekeeper compatibility Code Signing Applets and Droplets • Automator and AppleScript applets/droplets are applications • Code Sign for default Gatekeeper compatibility • Integrated signing support in AppleScript Editor and Automator Extending the power of AppleScript AppleScript Libraries Extending the power of AppleScript AppleScript Libraries Extending the power of AppleScript Why Libraries? You’ll like AppleScript Libraries if you… Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” • Want to simplify your scripts Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” • Want to simplify your scripts

on findAndReplaceStringInText(sourceText, searchString, replacementString) set the sourceString to ¬ current application's NSString's stringWithString_(sourceText) set the adjustedString to the sourceString's ¬ stringByReplacingOccurrencesOfString_withString_(searchString, replacementString) return (adjustedString as Unicode text) end findAndReplaceStringInText Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” • Want to simplify your scripts

on findAndReplaceStringInText(sourceText, searchString, replacementString) set the sourceString to ¬ current application's NSString's stringWithString_(sourceText) on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) return (adjustedStringcurrent application's as Unicode NSString'stext) stringWithString_(sourceText) on findAndReplaceStringInText(sourceText, searchString, replacementString) end findAndReplaceStringInTextset the adjustedString to the sourceString's ¬ setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) on findAndReplaceStringInText(sourceText,return (adjustedStringcurrent application's as Unicode searchString, NSString'stext) stringWithString_(sourceText) replacementString) on findAndReplaceStringInText(sourceText, searchString, replacementString) set theend sourceString findAndReplaceStringInTextset the toadjustedString ¬ to the sourceString's ¬ setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) current application'sreturn (adjustedStringcurrent NSString's application's as Unicode stringWithString_(sourceText) NSString'stext) stringWithString_(sourceText) set the adjustedStringend findAndReplaceStringInTextset theto adjustedStringthe sourceString's to the sourceString's ¬ ¬ stringByReplacingOccurrencesOfString_withString_(searchString, replacementString) stringByReplacingOccurrencesOfString_withString_(searchString,return (adjustedString as Unicode text) replacementString) return (adjustedStringend findAndReplaceStringInText as Unicode text) end findAndReplaceStringInText Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” • Want to simplify your scripts

on findAndReplaceStringInText(sourceText, searchString, replacementString) set the sourceString to ¬ current application's NSString's stringWithString_(sourceText) on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) return (adjustedStringcurrent application's as Unicode NSString'stext) stringWithString_(sourceText) on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) on trimWhiteSpaceAroundString(sourceText)end findAndReplaceStringInText setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) set the sourceString to on¬ findAndReplaceStringInText(sourceText,return (adjustedStringcurrent application's as Unicode searchString, NSString'stext) stringWithString_(sourceText) replacementString) on findAndReplaceStringInText(sourceText, searchString, replacementString) set theend sourceString findAndReplaceStringInTextset the toadjustedString ¬ to the sourceString's ¬ current application's NSString's stringWithString_(sourceText)setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) set the trimmedCocoaString to ¬current application'sreturn (adjustedStringcurrent NSString's application's as Unicode stringWithString_(sourceText) NSString'stext) stringWithString_(sourceText) set the adjustedStringend findAndReplaceStringInTextset theto adjustedStringthe sourceString's to the sourceString's ¬ ¬ sourceString's stringByTrimmingCharactersInSet_(currentstringByReplacingOccurrencesOfString_withString_(searchString, application's replacementString) NSCharacterSet's whitespaceCharacterSet) stringByReplacingOccurrencesOfString_withString_(searchString,return (adjustedString as Unicode text) replacementString) return (trimmedCocoaString asreturn Unicode (adjustedString text)end findAndReplaceStringInText as Unicode text) end trimWhiteSpaceAroundStringend findAndReplaceStringInText Why Libraries? You’ll like AppleScript Libraries if you… • Use the same script routines in multiple scripts • Rely on scripting additions for “missing commands” • Want to simplify your scripts

on trimWhiteSpaceAroundString(sourceText)

set the sourceString to ¬on trimWhiteSpaceAroundString(sourceText) current application's NSString'sset stringWithString_(sourceText)the sourceString to ¬ set the trimmedCocoaString to ¬ current application's NSString's stringWithString_(sourceText) on findAndReplaceStringInText(sourceText, searchString, replacementString) sourceString's stringByTrimmingCharactersInSet_(currentset the trimmedCocoaString application'sto ¬ NSCharacterSet's whitespaceCharacterSet) on trimWhiteSpaceAroundString(sourceText)set the sourceString to ¬ sourceString's stringByTrimmingCharactersInSet_(current application's NSCharacterSet's current application's NSString's stringWithString_(sourceText) return (trimmedCocoaString as whitespaceCharacterSet)Unicodeset the text) sourceString to ¬ on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) on trimWhiteSpaceAroundString(sourceText)end trimWhiteSpaceAroundString returncurrent (trimmedCocoaString application's NSString's as Unicode stringWithString_(sourceText) text) setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) set the sourceString to ¬ set the trimmedCocoaString to ¬ end trimWhiteSpaceAroundStringreturn (adjustedStringcurrent application's as Unicode NSString'stext) stringWithString_(sourceText) sourceString'son stringByTrimmingCharactersInSet_(currentfindAndReplaceStringInText(sourceText, searchString, application's replacementString) NSCharacterSet's current application's NSString's stringWithString_(sourceText)end findAndReplaceStringInTextset the adjustedString to the sourceString's ¬ on trimWhiteSpaceAroundString(sourceText)whitespaceCharacterSet) set the sourceString to ¬ set the trimmedCocoaString to ¬ stringByReplacingOccurrencesOfString_withString_(searchString, replacementString) onreturn findAndReplaceStringInText(sourceText, (trimmedCocoaString as Unicodecurrent text) application's searchString, NSString's stringWithString_(sourceText) replacementString) sourceString'sset the stringByTrimmingCharactersInSet_(currentsourceString to ¬ application'sreturn (adjustedString NSCharacterSet's as Unicode text) on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) whitespaceCharacterSet) end trimWhiteSpaceAroundString set theend sourceString findAndReplaceStringInText to ¬ current application's NSString's stringWithString_(sourceText)setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) return (trimmedCocoaString as Unicode text) set the trimmedCocoaString to ¬current application'sreturn (adjustedStringcurrent NSString's application's as Unicode stringWithString_(sourceText) NSString'stext) stringWithString_(sourceText) end trimWhiteSpaceAroundString set the adjustedStringend findAndReplaceStringInTextset theto adjustedStringthe sourceString's to the sourceString's ¬ ¬ sourceString's stringByTrimmingCharactersInSet_(currentstringByReplacingOccurrencesOfString_withString_(searchString, application's replacementString) NSCharacterSet's whitespaceCharacterSet) stringByReplacingOccurrencesOfString_withString_(searchString,return (adjustedString as Unicode text) replacementString) return (trimmedCocoaString asreturn Unicode (adjustedString text)end findAndReplaceStringInText as Unicode text) end trimWhiteSpaceAroundStringend findAndReplaceStringInText on RGBtoHTML(RGBColorValues) on extractTaggedData(thisFile, openingTag, closingTag, returnContentsOnly) -- NOTE: this sub-routine expects the RBG values to be from 0 to 65535 try set the hex_list to ¬ set thisFile to thisFile as text {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"} set thisFile to open for access file thisFile set the the hex_value to "" set the combinedResults to "" repeat with i from 1 to the count of the RGBColorValues set the open_tag to "" set this_value to (item i of the RGBColorValues) div 256 repeat if this_value is 256 then set this_value to 255 read thisFile before "<" -- start of a tag set x to item ((this_value div 16) + 1) of the hex_list set this_tag to read thisFile until ">" -- end of a tag set y to item (((this_value / 16 mod 1) * 16) + 1) of the hex_list --on to RGBtoHTML(RGBColorValues)make up for a bug in the "read before" command on extractTaggedData(thisFile, openingTag,set the hex_valueclosingTag, to (the returnContentsOnly) hex_value & x & y) as string if this_tag-- NOTE:does not this start sub-routinewith "<" then set expects this_tag theto ("<" RBG & valuesthis_tag) toas be fromend repeat 0 to 65535 string Why Libraries?try return ("#" & the hex_value) as string -- EXAMINEset THE the TAG hex_list to ¬ set thisFile to thisFileend RGBtoHTML as text if this_tag begins{"0", with "1", the openingTag"2", "3", then "4", "5", "6", "7", "8", "9", "A", "B", "C",on extractTaggedData(thisFile,"D", "E", "F"} openingTag, closingTag, returnContentsOnly) You’ll like AppleScriptset LibrariesthisFile to open iffor you…access file thisFile --storeset the the thecomplete hex_value tag, not justto ""the search string try on lowestNumber(numericValuesList) set the combinedResults to "" set thisFile to thisFile as text setrepeat the open_tag with toi fromthis_tag 1 to the count of the RGBColorValues set the lowAmount to "" set the open_tagon to lowestNumber(numericValuesList) "" set thisFile to open for access file thisFile repeat with i from 1 setto the this_value count of the tonumericValuesList (item i of the RGBColorValues) div 256 • Use the same script routinesrepeat in multipleset the scriptslowAmount to ""set the combinedResults to "" set thisItem toif item this_value i of the numericValuesList is 256 then set this_value to 255 set the open_tag to "" on RGBtoHTML(RGBColorValues)read thisFile beforerepeat "<" with -- istart from of1 toa tagthe count of the numericValuesList set the itemClassset tox theto classitem of ((this_value thisItem div 16) + 1) of the hex_list repeat if the itemClass is in {integer, --real} NOTE: then this sub-routine setexpects this_tag the RBG valuesto read to be setthisFile from thisItem 0 to 65535until to ">"item -- i endof theof anumericValuesList tag • Rely seton y scriptingto item (((this_value additions / 16 mod for 1) * “missing 16) + 1) of thecommands” hex_listread thisFile before "<" -- start of a tag set the hex_list to ¬ if the lowAmount is "" then-- to make up for a bugset inthe the itemClass "read before" to the set commandclass this_tag of tothisItem read thisFile until ">" -- end of a tag set the hex_value to{"0", (the "1", hex_value "2", "3", "4", & x"5", & y)"6", as "7", string "8", "9", "A", "B", "C", "D", "E", "F"} set the lowAmount to thisItem -- to make up for a bug in the "read before" command on RGBtoHTML(RGBColorValues) if this_tag does not start with "<" then set this_tag to set the the hex_value to "" if the itemClass is in {integer, real} then • Wantend repeat to simplify ("<"your & this_tag) scripts as string if this_tag does not start with "<" then set this_tag to ("<" & this_tag) as -- NOTE: this sub-routine expects the RBG values to be from 0 to 65535 repeat with i from 1 to the count of the RGBColorValuesif thestring lowAmount is "" then set the hex_list to ¬ return ("#" & the hex_value) as string-- EXAMINE THE TAG on trimWhiteSpaceAroundString(sourceText)set this_value to (item i of the RGBColorValues) div 256set the lowAmount-- EXAMINE to thisItem THE TAG {"0", "1", "2", "3", "4",end "5", RGBtoHTML "6", "7", "8", "9", "A", "B",on lowestNumber(numericValuesList) "C", "D", "E", "F"} set the sourceString to ¬on trimWhiteSpaceAroundString(sourceText)if this_value is 256if then this_tag set this_value begins to 255with the openingTag thenif this_tag begins with the openingTag then set the the hex_value to "" set the lowAmount to "" current application's NSString'ssetset xstringWithString_(sourceText)the to sourceStringitem ((this_value to ¬--store div 16) + the1) of complete the hex_list tag, not just the search--store string the complete tag, not just the search string repeat with i from 1 to the count of the RGBColorValues repeat with i from 1 to the count of the numericValuesList set the trimmedCocoaString to ¬set y tocurrent item (((this_value application'sset / NSString's 16the mod open_tag1) *stringWithString_(sourceText) 16) + 1)to of this_tag the hex_listset the open_tag to this_tag set this_value to (item i of the RGBColorValues)sourceString's stringByTrimmingCharactersInSet_(currentdiv 256onset findAndReplaceStringInText(sourceText, thisItem to item application's i of the numericValuesList NSCharacterSet's searchString, replacementString) setset thethe hex_valuetrimmedCocoaString to (the hex_value to ¬ & x & y) as string on lowestNumber(numericValuesList) if this_value is 256 whitespaceCharacterSet)then set this_value to 255on trimWhiteSpaceAroundString(sourceText)set theset itemClassthe sourceString to the classto ¬ of thisItem end repeatsourceString's stringByTrimmingCharactersInSet_(current application'sset the NSCharacterSet's lowAmount to "" set x to item ((this_value returndiv 16) (trimmedCocoaString + 1) of the hex_list as Unicodeset the text) sourceString to current¬ application's NSString's stringWithString_(sourceText) returnwhitespaceCharacterSet) ("#" & theif thehex_value) itemClass as isstring in {integer, real} then on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString)repeat with i from 1 to the count of the numericValuesList set y to onitem trimWhiteSpaceAroundString(sourceText) (((this_valueend trimWhiteSpaceAroundString / 16 mod 1) * 16) + 1) of the hex_listreturncurrent (trimmedCocoaString application'sif the lowAmount NSString's as Unicodeis "" stringWithString_(sourceText) then text) end RGBtoHTML setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ set replacementString)thisItem to item i of the numericValuesList set the hex_valueset tothe (the sourceString hex_value to& x¬ & y) as stringendset trimWhiteSpaceAroundString the trimmedCocoaStringset tocurrent the¬ lowAmount application's to thisItem NSString's stringWithString_(sourceText) return (adjustedString as Unicode text) set the itemClass to the class of thisItem sourceString'son stringByTrimmingCharactersInSet_(currentfindAndReplaceStringInText(sourceText, searchString, application's replacementString) NSCharacterSet's end repeatcurrent application's NSString's stringWithString_(sourceText)end findAndReplaceStringInTextset the adjustedString to the sourceString's ¬ on trimWhiteSpaceAroundString(sourceText)whitespaceCharacterSet) set the sourceString to ¬ if the itemClass is in {integer, real} then return ("#" & the hex_value)set the astrimmedCocoaString string to ¬ stringByReplacingOccurrencesOfString_withString_(searchString, replacementString) onreturn findAndReplaceStringInText(sourceText, (trimmedCocoaString as Unicodecurrent text) application's searchString, NSString's stringWithString_(sourceText) replacementString)if the lowAmount is "" then end RGBtoHTML sourceString'sset the stringByTrimmingCharactersInSet_(currentsourceString to ¬ application'sreturn (adjustedString NSCharacterSet's as Unicode text)on extractTaggedData(thisFile, openingTag, closingTag, returnContentsOnly) on extractTaggedData(thisFile, openingTag, closingTag, returnContentsOnly) on setfindAndReplaceStringInText(sourceText, the adjustedString to the sourceString's searchString, ¬ replacementString) whitespaceCharacterSet) end trimWhiteSpaceAroundString set theend sourceString findAndReplaceStringInText to ¬ tryset the lowAmount to thisItem try current application's NSString's stringWithString_(sourceText)setstringByReplacingOccurrencesOfString_withString_(searchString, the sourceString to ¬ replacementString) on RGBtoHTML(RGBColorValues) return (trimmedCocoaString as Unicode text) current application'scurrent NSString's application's stringWithString_(sourceText) NSString'sset stringWithString_(sourceText) thisFile to thisFile as text set thisFileset to thethisFile trimmedCocoaString as text to ¬ return (adjustedString as Unicode text) end trimWhiteSpaceAroundString-- NOTE: this sub-routine expects the RBG values to be fromset 0 tothe 65535 adjustedString to the sourceString'sset thisFile ¬ to open for access file thisFile set thisFile to opensourceString's for access file thisFilestringByTrimmingCharactersInSet_(current set the adjustedStringend findAndReplaceStringInText to the sourceString's application's ¬ set the hex_list to ¬ stringByReplacingOccurrencesOfString_withString_(searchString,set the combinedResults to "" replacementString) set NSCharacterSet'sthe combinedResults to whitespaceCharacterSet)"" stringByReplacingOccurrencesOfString_withString_(searchString,return (adjustedString as Unicode text) replacementString) {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"}set the open_tag to "" set the open_tag to "" return (adjustedStringend findAndReplaceStringInText as Unicode text) returnset the (trimmedCocoaString the hex_value to "" as Unicode text) repeat repeat on lowestNumber(numericValuesList) end trimWhiteSpaceAroundStringrepeat with i from 1 to the endcount findAndReplaceStringInText of the RGBColorValues read thisFile before "<" -- start of a tag read thisFile before "<" -- start of a tag set the lowAmount to "" set this_value to (item i of the RGBColorValues) div 256 set this_tag to read thisFile until ">" -- end of a tag set this_tag to read thisFile until ">" -- end of a tagrepeat with i from 1 to the count of the numericValuesList if this_value is 256 then set this_value to 255 -- to make up for a bug in the "read before" command -- to make up for a bug in the "read before" commandset thisItem to item i of the numericValuesList set x to item ((this_value div 16) + 1) of the hex_list if this_tag does not start with "<" then set this_tag to ("<" & this_tag) as if this_tag does not start with "<" then set this_tag to ("<" & setthis_tag) the itemClass as to the class of thisItem set y to item (((this_value / 16 mod 1) * 16) + 1) of the hex_list string string if the itemClass is in {integer, real} then set the hex_value to (the hex_value & x & y) as string -- EXAMINE THE TAG -- EXAMINE THE TAG if the lowAmount is "" then end repeat if this_tag begins with the openingTag then if this_tag begins with the openingTag then set the lowAmount to thisItem return ("#" & the hex_value) as string --store the complete tag, not just the search string --store the complete tag, not just the search string end RGBtoHTML set the open_tag to this_tag set the open_tag to this_tag AppleScript Libraries New in OS X AppleScript Libraries New in OS X AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology () AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology (Dictionary) • New Script Library reference automatically locates libraries AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology (Dictionary) • New Script Library reference automatically locates libraries • The new use clause automatically loads a library for global access AppleScript Libraries Creating a Simple AppleScript Library AppleScript Libraries Creating a Simple AppleScript Library

on changeCaseOfText(sourceText, caseIndicator) !if caseIndicator is 0 then !!set the comparisonCharacters to "ABCDEFGHIJKLMNOPQRSTUVWXYZ" !!set the sourceCharacters to "abcdefghijklmnopqrstuvwxyz" !else !!set the comparisonCharacters to "abcdefghijklmnopqrstuvwxyz" !!set the sourceCharacters to "ABCDEFGHIJKLMNOPQRSTUVWXYZ" !end if !set the newText to "" !repeat with thisCharacter in sourceText !!set x to the offset of thisCharacter in the comparisonCharacters !!if x is not 0 then !!!set the newText to ¬ !!!!(the newText & character x of the sourceCharacters) as string !!else !!!set the newText to (the newText & thisCharacter) as string !!end if !end repeat !return the newText end changeCaseOfText

Case Change.scpt

Script Libraries Case Change.scpt

Script Libraries Case Change.scpt

Script Libraries Script Libraries Case Change.scpt Script Libraries Case Change.scpt Script Libraries Script Libraries Script Libraries

Script Library Identifier Script Library Identifier Script Library Identifier Script Library Identifier Script Library Identifier Script Library Identifier Script Library Identifier Script Library Identifier

AppleScript Library Changing Case of the Names of Selected Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell

edited movies smith project AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell

EDITED MOVIES SMITH PROJECT AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell

EDITED MOVIES SMITH PROJECT AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items

tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library Changing Case of the Names of Selected Finder Items

tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the adjustedName to transform text thisName to upper case !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the adjustedName to transform text thisName to upper case !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the adjustedName to transform text thisName to upper case !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell AppleScript Library New “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell AppleScript Library Without “use” Clause tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!tell script "Case Change" !!!set the adjustedName to transform text thisName to upper case !!end tell !!set the name of thisItem to the adjustedName !end repeat end tell AppleScript Library With “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell AppleScript Library With “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell

edited movies smith project AppleScript Library With “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell

EDITED MOVIES SMITH PROJECT AppleScript Library With “use” Clause use script "Case Change" tell application "Finder" !set the selectedItems to the selection !repeat with thisItem in the selectedItems !!set thisName to the name of thisItem !!set the name of thisItem to transform text thisName to upper case !end repeat end tell

EDITED MOVIES SMITH PROJECT The “use” Clause Importing Terminology The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script • Can be used to specify minimum version The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script • Can be used to specify minimum version ■ AppleScript The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script • Can be used to specify minimum version ■ AppleScript ■ Applications The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script • Can be used to specify minimum version ■ AppleScript ■ Applications ■ AppleScript Script Libraries The “use” Clause Importing Terminology • Imports terminology from Script Libraries and Applications • Imported commands are available globally in the script • Can be used to specify minimum version ■ AppleScript ■ Applications ■ AppleScript Script Libraries • Streamline script syntax Demo The “use” Clause

Chris Nebel Senior AppleScript Engineer AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology (Dictionary) AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology (Dictionary) • New Script Library reference automatically locates libraries AppleScript Libraries New in OS X • Libraries are a new plugin architecture for AppleScript, enabling easy development and access to custom sets of handlers. • AppleScript Libraries differ from Scripting Additions: ■ They can be written in AppleScript! ■ Libraries are managed by the script • AppleScript Libraries can: ■ Use AppleScript/Objective-C ■ Publish their own Scripting Terminology (Dictionary) • New Script Library reference automatically locates libraries • The new use clause automatically loads a library for global access Related Session Related Session

416: Introducing AppleScript Libraries Russian Hill, Level 2 3:15 p.m. to 4:15 p.m. Notifications Informing the User Notifications in OS X Subtitle placeholder Notifications in OS X Subtitle placeholder • Notifications appear in the same location, organized by application Notifications in OS X Subtitle placeholder • Notifications appear in the same location, organized by application • Disappear quickly so they don’t clutter up your screen Notifications in OS X Subtitle placeholder • Notifications appear in the same location, organized by application • Disappear quickly so they don’t clutter up your screen • Provide a mechanism for action or response Notifications in OS X Subtitle placeholder • Notifications appear in the same location, organized by application • Disappear quickly so they don’t clutter up your screen • Provide a mechanism for action or response • Designed to inform, not annoy or distract attention Notifications in OS X Subtitle placeholder • Notifications appear in the same location, organized by application • Disappear quickly so they don’t clutter up your screen • Provide a mechanism for action or response • Designed to inform, not annoy or distract attention • Should not leap, jump, or hop. Definitely not bounce! Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs • Now “100% Bounce-Free” Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs • Now “100% Bounce-Free” Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs • Now “100% Bounce-Free”

? Automator New Display Notification action Automator New Display Notification action • Causes a notification to occur Automator New Display Notification action • Causes a notification to occur • Place at the start, end, or within a workflow Automator New Display Notification action • Causes a notification to occur • Place at the start, end, or within a workflow • Provides optional input options for messaging Automator New Display Notification action • Causes a notification to occur • Place at the start, end, or within a workflow • Provides optional input options for messaging • Supports Automator variables

AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert display notification v : Display a notification. At least one of the body text and the title must be specified. display notification [text] : the body text of the notification [with title text] : the title of the notification (default is the name of the calling application). [subtitle text] : the subtitle of the notification [sound name text] : the name of the sound to play AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat !on error errorMessage !!display dialog errorMessage !end try end open AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat

!on error errorMessage !!display dialog errorMessage !end try end open AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat

!on error errorMessage !!display dialog errorMessage !end try end open AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat !!display notification ((count of theseItems) as string) & " images were processed." !on error errorMessage !!display dialog errorMessage !end try end open AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat !!display notification ((count of theseItems) as string) & " images were processed." !on error errorMessage !!display dialog errorMessage !end try end open AppleScript Display notification alert on open theseItems !set the defaultRBGColor to {0, 0, 65535} !set the frameThickness to 48 !try !!repeat with thisItem in theseItems !!!tell application "Image Events" !!!!launch !!!!set thisImage to open file (thisItem as string) !!!!copy dimensions of thisImage to {W, H} !!!!pad thisImage to dimensions {W + frameThickness, H + frameThickness} ¬ !!!!!with pad color defaultRBGColor !!!!save thisImage with icon !!!!close thisImage !!!end tell !!end repeat !!display notification ((count of theseItems) as string) & " images were processed." !on error errorMessage !!display dialog errorMessage !end try end open

Demo Notifiations

Chris Nebel Senior Automation Engineer Notification Support Automator and AppleScript Notification Support Automator and AppleScript • Integrated notification support Notification Support Automator and AppleScript • Integrated notification support ■ Automator Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs Notification Support Automator and AppleScript • Integrated notification support ■ Automator ■ AppleScript • No need for modal “completion” dialogs • Now “100% Bounce-Free” Accessibility Integration

Reader Speakable Items

“Audio chat with Sue” “Minimize window” “Switch to ” “Merge all windows”

“Switch to Finder” “What time is it?”

“Quit ” “Zoom Window” “Tell me a joke” “Close Window”

“Hide all windows” “Open iPhoto”

“Phone for Trudy Anchover” “Mail this to Mom”

“Go to Apple website” “Share Menu” “Connect to server”

“Set alarm to 20 minutes” “Meet with Carl Wayland” Reader

Reader Speakable Items Speakable Items

Speakable-Workflows

“Eject Digital Briefcase”

Speakable-Workflows Speakable-Workflows www.speakableworkflows.com Summary Great OS Release for Automation Summary Great OS Release for Automation • iCloud Support Summary Great OS Release for Automation • iCloud Support • Code Signing Summary Great OS Release for Automation • iCloud Support • Code Signing • AppleScript Libraries Summary Great OS Release for Automation • iCloud Support • Code Signing • AppleScript Libraries • The ”use” Clause Summary Great OS Release for Automation • iCloud Support • Code Signing • AppleScript Libraries • The ”use” Clause • Notifications Summary Great OS Release for Automation • iCloud Support • Code Signing • AppleScript Libraries • The ”use” Clause • Notifications • Speakable-Workflows More Information

Paul Danbold Core OS Technology Evangelist [email protected]

Dave Delong App Frameworks Evangelist [email protected]

Documentation AppleScript Libraries Overview http://macosautomation.com/applescript

Apple Developer Forums http://devforums.apple.com/community/tools/auto/applescript Related Session

Russian Hill Introducing Apple Script Libraries Thursday 3:15PM Related Session #416

Russian Hill Introducing Apple Script Libraries Thursday 3:15PM TODAY!

3:15-4:15 PM

RUSSIAN HILL Labs

Tools Lab C Automation Lab Thursday 4:30PM Labs

Tools Lab C Automation Lab Thursday 4:30PM TODAY!

4:30-6:00 PM

TOOLS LAB-C And, did you know… AA!!leScleSc""ptpt

20# Thank You!

20#