Index: client/pkgd.eagle
==================================================================
--- client/pkgd.eagle
+++ client/pkgd.eagle
@@ -18,10 +18,15 @@
 # NOTE: Use our own namespace here because even though we do not directly
 #       support namespaces ourselves, we do not want to pollute the global
 #       namespace if this script actually ends up being evaluated in Tcl.
 #
 namespace eval ::PackageDownloader {
+  #
+  # NOTE: This procedure sets up the default values for all configuration
+  #       parameters used by the package downloader client.  There are no
+  #       arguments.
+  #
   proc setupDownloadVars {} {
     #
     # NOTE: Prevent progress messages from being displayed while downloading
     #       from the repository, etc?  By default, this is enabled.
     #
@@ -58,18 +63,31 @@
     if {![info exists persistentDirectory]} then {
       set persistentDirectory [getPersistentRootDirectory]
     }
   }
 
+  #
+  # NOTE: This procedure returns the root directory where any packages that
+  #       are downloaded should be saved to permanent storage for subsequent
+  #       use.  There are no arguments.
+  #
   proc getPersistentRootDirectory {} {
     #
     # NOTE: Return a directory parallel to the one containing the library
     #       directory.
     #
     return [file join [file dirname [info library]] pkgr]
   }
 
+  #
+  # NOTE: This procedure adds a directory to the auto-path of the specified
+  #       language (i.e. native Tcl or Eagle).  The directory will not be
+  #       added if it is already present.  The language argument must be the
+  #       literal string "eagle" or the literal string "tcl".  The directory
+  #       argument is the fully qualified path for the directory to add to
+  #       the auto-path.
+  #
   proc addToAutoPath { language directory } {
     #
     # NOTE: Add the specified directory to the auto-path if not already
     #       present.
     #
@@ -106,15 +124,40 @@
     } else {
       error "unsupported language, no idea how to modify auto-path"
     }
   }
 
+  #
+  # NOTE: This procedure attempts to download a list of files, optionally
+  #       persistening them for subsequent uses by the target language.
+  #       The language argument must be the literal string "eagle" or the
+  #       literal string "tcl".  The version argument must be the literal
+  #       string "8.4", "8.5", or "8.6" when the language is "tcl" -OR-
+  #       the literal string "1.0" when the language is "eagle".  The
+  #       fileNames argument must be a well-formed list of file names to
+  #       download, each one relative to the language/version-specific
+  #       directory on the package file server.  The persistent argument
+  #       should be non-zero if the downloaded files should be saved to
+  #       permanent storage for subsequent use.
+  #
   proc downloadFiles { language version fileNames persistent } {
     variable baseUri
     variable downloadUri
     variable persistentDirectory
     variable quiet
+
+    if {[string length $language] == 0 || $language eq "eagle"} then {
+      if {$version ne "1.0"} then {
+        error "unsupported Eagle version"
+      }
+    } elseif {$language eq "tcl"} then {
+      if {$version ne "8.4" && $version ne "8.5" && $version ne "8.6"} then {
+        error "unsupported Tcl version"
+      }
+    } else {
+      error "unsupported language"
+    }
 
     if {$persistent} then {
       set downloadRootDirectory [file join $persistentDirectory]
     } else {
       global env
Index: client/pkgd.eagle.harpy
==================================================================
--- client/pkgd.eagle.harpy
+++ client/pkgd.eagle.harpy
@@ -19,32 +19,32 @@
 
   None
   Mistachkin Systems
-  36e6e8e4-39ac-4f29-928e-5c10e32cb1eb
+  2c09ab50-08d8-47a0-8d50-96529e4cf6fd
   SHA512
   Script
-  2016-08-16T23:11:46.2517109Z
+  2016-08-17T22:38:23.1247578Z
   -1.00:00:00
   0x2c322765603b5278
   
-    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
+    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
   
 
Index: client/pkgr.eagle
==================================================================
--- client/pkgr.eagle
+++ client/pkgr.eagle
@@ -27,15 +27,25 @@
   #       be modified to include the "Eagle1.0" directory (i.e. the one
   #       containing the Eagle core script library file "init.eagle").
   #
   package require Eagle.Library
 
+  #
+  # NOTE: This procedure returns a formatted, possibly version-specific,
+  #       package name, for use in logging.
+  #
   proc formatPackageName { package version } {
     return [string trim [appendArgs \
         $package " " [getLookupVersion $version]]]
   }
 
+  #
+  # NOTE: This procedure returns a formatted script result.  If the string
+  #       result is empty, only the return code is used.  The code argument
+  #       must be an integer Tcl return code (e.g. from [catch]) and the
+  #       result argument is the script result or error message.
+  #
   proc formatResult { code result } {
     switch -exact -- $code {
       0 {set codeString ok}
       1 {set codeString error}
       2 {set codeString return}
@@ -49,16 +59,26 @@
     } else {
       return $codeString
     }
   }
 
+  #
+  # NOTE: This procedure emits a message to the package repository client
+  #       log.  The string argument is the content of the message to emit.
+  #
+  # 
   proc pkgLog { string } {
     catch {
       tclLog [appendArgs [pid] " : " [clock seconds] " : pkgr : " $string]
     }
   }
 
+  #
+  # NOTE: This procedure attempts to determine if a string is a valid list
+  #       and returns non-zero when that is true.  The value argument is
+  #       the string to check.
+  #
   proc stringIsList { value } {
     if {[isEagle]} then {
       return [string is list $value]
     } else {
       global tcl_version
@@ -71,10 +91,16 @@
         return false
       }
     }
   }
 
+  #
+  # NOTE: This procedure returns non-zero if the specified string value
+  #       looks like a Harpy (script) certificate.  The value argument
+  #       is the string to check.
+  #
+  # 
   proc isHarpyCertificate { value } {
     if {[string length $value] == 0 || [string first [string trim {
       
   proc isPgpSignature { value } {
     if {[string length $value] == 0 || [string first [string trim {
       -----BEGIN PGP SIGNATURE-----
     }] $value] != -1} then {
       return true
@@ -91,10 +123,15 @@
     } else {
       return false
     }
   }
 
+  #
+  # NOTE: This procedure returns a unique temporary file name.  A script
+  #       error is raised if this task cannot be accomplished.  There are
+  #       no arguments.
+  #
   proc getFileTempName {} {
     if {[isEagle]} then {
       return [file tempname]
     } else {
       global env
@@ -122,10 +159,18 @@
         incr counter
       }
     }
   }
 
+  #
+  # NOTE: This procedure attempts to verify the PGP signature contained in
+  #       the specified (named) file.  Non-zero is only returned if the PGP
+  #       signature is verified successfully.  A script error should not be
+  #       raised by this procedure.  The fileName argument must be the fully
+  #       qualified path and file name of the PGP signature file to verify.
+  #
+  # 
   proc verifyPgpSignature { fileName } {
     variable pgpCommand
 
     if {[isEagle]} then {
       set fileName [appendArgs \" $fileName \"]
@@ -144,20 +189,38 @@
     }
 
     return false
   }
 
+  #
+  # NOTE: This procedure returns the prefix for fully qualified variable
+  #       names that MAY be present in the global namespace.  There are
+  #       no arguments.
+  #
   proc getLookupVarNamePrefix {} {
     return ::pkgr_; # TODO: Make non-global?
   }
 
+  #
+  # NOTE: This procedure returns a unique suffix for a fully qualified
+  #       variable name that MAY be present in the global namespace.
+  #       It is used (internally) to avoid any name collisions with
+  #       variables and commands in the global namespace.  There are
+  #       no arguments.
+  #
   proc getLookupVarNameSuffix {} {
     return [appendArgs \
         [string trim [pid] -] _ [string trim [clock seconds] -] _ \
         [string trim [clock clicks -milliseconds] -]]; # TODO: Bad?
   }
 
+  #
+  # NOTE: This procedure returns the list of API keys to use when looking
+  #       up packages via the package repository server.  An empty list
+  #       is returned if no API keys are currently configured.  There are
+  #       no arguments.
+  #
   proc getLookupApiKeys {} {
     set varName [appendArgs [getLookupVarNamePrefix] api_keys]
 
     if {[info exists $varName]} then {
       return [set $varName]
@@ -188,10 +251,20 @@
     }
 
     return https://urn.to/r/pkg; # NOTE: System default.
   }
 
+  #
+  # NOTE: This procedure returns the full URI to use when looking up a
+  #       specific package via the package repository server.  The apiKey
+  #       argument is the API key to use -OR- an empty string if a public
+  #       package is being looked up.  The package argument is the name
+  #       of the package being looked up, it cannot be an empty string.
+  #       The version argument is the specific version being looked up
+  #       -OR- an empty string for any available version.  No HTTP request
+  #       is issued by this procedure; it just returns the URI to use.
+  #
   proc getLookupUri { apiKey package version } {
     set baseUri [getLookupBaseUri]
 
     if {[string length $baseUri] == 0} then {
       return ""
@@ -214,18 +287,33 @@
           $baseUri ? [http::formatQuery raw 1 method lookup apiKey $apiKey \
           package $package version $version]]
     }
   }
 
+  #
+  # NOTE: This procedure returns the version of the package that should be
+  #       used to lookup the associated [package ifneeded] script -OR- an
+  #       empty string if no such version exists.  The package argument is
+  #       the name of the package, it cannot be an empty string.  The
+  #       version argument is the specific version being looked up -OR- an
+  #       empty string for any available version.
+  #
   proc getIfNeededVersion { package version } {
     if {[string length $version] > 0} then {
       return $version
     }
 
     return [lindex [package versions $package] 0]
   }
 
+  #
+  # NOTE: This procedure accepts a package requirement (spec) and returns
+  #       a simple package version, if possible.  An empty string will be
+  #       returned, if appropriate (i.e. any version should be allowed).
+  #       The requirement argument must be a package specification that
+  #       conforms to TIP #268.
+  #
   proc getLookupVersion { requirement } {
     if {[set index [string first - $requirement]] != -1} then {
       incr index -1; set requirement [string range $requirement 0 $index]
     }
 
@@ -241,10 +329,20 @@
     }
 
     return $requirement
   }
 
+  #
+  # NOTE: This procedure issues an HTTP request that should return metadata
+  #       that can be used to load and/or provide the specified package.
+  #       The apiKey argument is the API key to use -OR- an empty string if
+  #       a public package is being looked up.  The package argument is the
+  #       name of the package, it cannot be an empty string.  The version
+  #       argument is the specific version being looked up -OR- an empty
+  #       string for any available version.  This procedure may raise script
+  #       errors.
+  #
   proc getLookupData { apiKey package version } {
     variable verboseUriDownload
 
     set uri [getLookupUri $apiKey $package $version]
 
@@ -258,12 +356,11 @@
     }
 
     if {[isEagle]} then {
       set data [uri download -inline $uri]
     } else {
-      variable quiet
-
+      set quiet [expr {!$verboseUriDownload}]
       set data [getFileViaHttp $uri 10 stdout $quiet]
     }
 
     if {$verboseUriDownload} then {
       pkgLog [appendArgs \
@@ -276,34 +373,57 @@
     set data [string trim $data]
 
     return $data
   }
 
+  #
+  # NOTE: This procedure attempts to extract the lookup code from the raw
+  #       HTTP response data.  The data argument is the raw HTTP response
+  #       data.  An empty string is returned if no lookup code is available.
+  #
   proc getLookupCodeFromData { data } {
     if {![stringIsList $data] || [llength $data] < 1} then {
       return ""
     }
 
     return [lindex $data 0]
   }
 
+  #
+  # NOTE: This procedure attempts to extract the lookup result from the raw
+  #       HTTP response data.  The data argument is the raw HTTP response
+  #       data.  An empty string is returned if no lookup result is available.
+  #
   proc getLookupResultFromData { data } {
     if {![stringIsList $data] || [llength $data] < 2} then {
       return ""
     }
 
     return [lindex $data 1]
   }
 
+  #
+  # NOTE: This procedure returns non-zero if the specified lookup response
+  #       code indicates success.  The code argument is the extracted HTTP
+  #       lookup response code.
+  #
   proc isLookupCodeOk { code } {
     #
     # NOTE: The code must be the literal string "OK" for the package lookup
     #       request to be considered successful.
     #
     return [expr {$code eq "OK"}]
   }
 
+  #
+  # NOTE: This procedure attempts to extract the package lookup metadata from
+  #       the lookup result.  The result argument is the lookup result.  The
+  #       varName argument is the name of an array variable, in the call frame
+  #       of the immediate caller, that should receive the extracted package
+  #       lookup metadata.  The caller argument must be an empty string -OR-
+  #       the literal string "handler".
+  #
   proc extractAndVerifyLookupMetadata { result varName caller } {
     variable strictUnknownLanguage
 
     #
     # NOTE: Grab the language for the package script.  It must be an empty
@@ -358,12 +478,12 @@
         }
       }
     }
 
     #
-    # NOTE: If the caller wants the package metadata, use their array
-    #       variable name.
+    # NOTE: If the caller wants the package lookup metadata, use their
+    #       array variable name.
     #
     if {[string length $varName] > 0} then {
       upvar 1 $varName metadata
 
       set metadata(language) $language
@@ -370,10 +490,15 @@
       set metadata(script) $script
       set metadata(certificate) $certificate
     }
   }
 
+  #
+  # NOTE: This procedure, which may only be used from an Eagle script, checks
+  #       if a native Tcl library is loaded and ready.  If not, a script error
+  #       is raised.
+  #
   proc tclMustBeReady {} {
     #
     # NOTE: This procedure is not allowed to actually load a native Tcl
     #       library; therefore, one must already be loaded.
     #
@@ -384,10 +509,15 @@
     if {![tcl ready]} then {
       error "cannot use Tcl language, supporting library is not loaded"
     }
   }
 
+  #
+  # NOTE: This procedure, which may only be used from a native Tcl script,
+  #       checks if Garuda and Eagle are loaded and ready.  If not, a script
+  #       error is raised.
+  #
   proc eagleMustBeReady {} {
     #
     # NOTE: This procedure is not allowed to actually load Garuda (and
     #       Eagle); therefore, they must already be loaded.
     #
@@ -398,10 +528,15 @@
     if {[llength [info commands eagle]] == 0} then {
       error "cannot use Eagle language, supporting package is not loaded"
     }
   }
 
+  #
+  # NOTE: This procedure returns non-zero if the current script is being
+  #       evaluated in Eagle with signed-only script security enabled.
+  #       There are no arguments.
+  #
   proc eagleHasSecurity {} {
     #
     # NOTE: If possible, check if the current interpreter has security
     #       enabled.
     #
@@ -414,10 +549,26 @@
     }
 
     return false
   }
 
+  #
+  # NOTE: This procedure uses the package lookup metadata.  If the package
+  #       script is properly signed, an attempt will be made to evaluate it
+  #       in the target language.  If the script was signed using PGP, then
+  #       a conforming implementation of the OpenPGP specification (e.g.
+  #       gpg2) must be installed locally.  If the script was signed using
+  #       Harpy then Garuda, Eagle, and Harpy must be installed locally.
+  #       This procedure is designed to work for both native Tcl and Eagle
+  #       packages.  Additionally, it is designed to work when evaluated
+  #       using either native Tcl or Eagle; however, it is up to the package
+  #       script itself to either add the package or provide the package to
+  #       the language(s) supported by that package.  The varName argument
+  #       is the name of an array variable in the call frame of the
+  #       immediate caller, that contains the package lookup metadata.  This
+  #       procedure may raise script errors.
+  #
   proc processLookupMetadata { varName } {
     #
     # NOTE: If the metadata variable name appears to be invalid, fail.
     #
     if {[string length $varName] == 0} then {
@@ -738,10 +889,17 @@
     } else {
       error "unsupported script certificate"
     }
   }
 
+  #
+  # NOTE: This procedure performs initial setup of the package repository
+  #       client, using the current configuration parameters.  There are
+  #       no arguments.  It may load the Garuda package when evaluated in
+  #       native Tcl.  It may load a native Tcl library when evaluated in
+  #       Eagle.  It may install the [package unknown] hook.
+  #
   proc setupPackageUnknownHandler {} {
     variable autoHook
     variable autoLoadTcl
     variable autoRequireGaruda
 
@@ -768,15 +926,27 @@
       #
       hookPackageUnknownHandler
     }
   }
 
+  #
+  # NOTE: This procedure returns non-zero if the [package unknown] handler
+  #       has already been hooked by the package repository client.  There
+  #       are no arguments.
+  #
   proc isPackageUnknownHandlerHooked {} {
     return [info exists [appendArgs \
         [getLookupVarNamePrefix] saved_package_unknown]]
   }
 
+  #
+  # NOTE: This procedure attempts to hook the [package unknown] handler.  It
+  #       will raise a script error if this has already been done.  The old
+  #       [package unknown] handler is saved and will be used by the new one
+  #       as part of the overall package loading process.  There are no
+  #       arguments.
+  #
   proc hookPackageUnknownHandler {} {
     set varName [appendArgs [getLookupVarNamePrefix] saved_package_unknown]
 
     if {[info exists $varName]} then {
       error "package unknown handler already hooked"
@@ -784,10 +954,17 @@
 
     set $varName [package unknown]
     package unknown [appendArgs [namespace current] ::packageUnknownHandler]
   }
 
+  #
+  # NOTE: This procedure attempts to unhook the [package unknown] handler.
+  #       It will raise a script error if the [package unknown] handler is
+  #       not hooked.  The old [package unknown] handler is restored and
+  #       the saved [package unknown] handler is cleared.  There are no
+  #       arguments.
+  #
   proc unhookPackageUnknownHandler {} {
     set varName [appendArgs [getLookupVarNamePrefix] saved_package_unknown]
 
     if {![info exists $varName]} then {
       error "package unknown handler is not hooked"
@@ -795,10 +972,15 @@
 
     package unknown [set $varName]
     unset $varName
   }
 
+  #
+  # NOTE: The procedure runs the saved [package unknown] handler.  Any script
+  #       errors are raised to the caller.  The package and version arguments
+  #       are passed in from the current [package unknown] handler verbatim.
+  #
   proc runSavedPackageUnknownHandler { package version } {
     #
     # NOTE: See if there is a saved [package unknown] handler.  If so, then
     #       attempt to use it.
     #
@@ -809,13 +991,17 @@
       lappend oldHandler $package $version; uplevel #0 $oldHandler
     }
   }
 
   #
-  # NOTE: This version argument to this procedure must be optional, because
-  #       Eagle does not add a version argument when one is not supplied to
-  #       the [package require] sub-command itself.
+  # NOTE: This procedure is the [package unknown] handler entry point called
+  #       by native Tcl and Eagle.  The package argument is the name of the
+  #       package being sought, it cannot be an empty string.  The version
+  #       argument must be a specific version -OR- a package specification
+  #       that conforms to TIP #268.  This version argument must be optional
+  #       here, because Eagle does not add a version argument when one is
+  #       not explicitly supplied to the [package require] sub-command.
   #
   proc packageUnknownHandler { package {version ""} } {
     variable verboseUnknownResult
 
     #
@@ -881,10 +1067,17 @@
             "\" was not loaded"]
       }
     }
   }
 
+  #
+  # NOTE: This procedure evaluates the package repository client settings
+  #       script file, if it exists.  Any script errors raised are not
+  #       masked.  The script argument must be the fully qualified path
+  #       and file name for the primary package repository client script
+  #       file.
+  #
   proc maybeReadSettingsFile { script } {
     if {[string length $script] == 0 || \
         ![file exists $script] || ![file isfile $script]} then {
       return
     }
@@ -895,21 +1088,16 @@
     if {[file exists $fileName] && [file isfile $fileName]} then {
       uplevel 1 [list source $fileName]
     }
   }
 
+  #
+  # NOTE: This procedure sets up the default values for all configuration
+  #       parameters used by the package repository client.  There are no
+  #       arguments.
+  #
   proc setupPackageUnknownVars {} {
-    #
-    # NOTE: Prevent progress messages from being displayed while downloading
-    #       from the repository, etc?  By default, this is enabled.
-    #
-    variable quiet; # DEFAULT: true
-
-    if {![info exists quiet]} then {
-      set quiet true
-    }
-
     #
     # NOTE: Automatically install our [package unknown] handler when this
     #       package is loaded?
     #
     variable autoHook; # DEFAULT: true
@@ -976,10 +1164,20 @@
     if {![info exists verboseUriDownload]} then {
       set verboseUriDownload false
     }
   }
 
+  #
+  # NOTE: This procedure is the primary entry point to the package repository
+  #       client.  It attempts to lookup the specified package using the
+  #       currently configured package repository server.  The package
+  #       argument is the name of the package being sought, it cannot be an
+  #       empty string.  The version argument must be a specific version -OR-
+  #       a package specification that conforms to TIP #268.  The caller
+  #       argument must be an empty string -OR- the literal string "handler".
+  #
+  # 
   proc main { package version caller } {
     #
     # NOTE: Get the list of API keys and try each one, in order, until
     #       the package is found.
     #
@@ -1050,31 +1248,58 @@
     ###########################################################################
     ############################# BEGIN Tcl ONLY ##############################
     ###########################################################################
 
     #
-    # NOTE: This procedure was stolen from the "getEagle.tcl" script.
+    # NOTE: This procedure was stolen from the "getEagle.tcl" script.  It is
+    #       designed to emit a progress indicator while an HTTP request is
+    #       being processed.  The channel argument is the Tcl channel where
+    #       the progress indicator should be emitted.  The type argument is
+    #       the single-character progress indicator.  The milliseconds
+    #       argument is the number of milliseconds to wait until the next
+    #       periodic progress indicator should be emitted.  This procedure
+    #       reschedules its own execution.
     #
     proc pageProgress { channel type milliseconds } {
+      #
+      # NOTE: This variable is used to keep track of the currently scheduled
+      #       (i.e. pending) [after] event.
+      #
+      variable afterForPageProgress
+
       #
       # NOTE: Show that something is happening...
       #
       catch {puts -nonewline $channel $type; flush $channel}
 
       #
-      # NOTE: Make sure that we are scheduled to run again.
+      # NOTE: Make sure that we are scheduled to run again, if requested.
       #
       if {$milliseconds > 0} then {
-        after $milliseconds [namespace code [list pageProgress \
-            $channel $type $milliseconds]]
+        set afterForPageProgress [after $milliseconds \
+            [namespace code [list pageProgress $channel $type \
+            $milliseconds]]]
+      } else {
+        unset afterForPageProgress
       }
     }
 
     #
-    # NOTE: This procedure was stolen from the "getEagle.tcl" script.
+    # NOTE: This procedure was stolen from the "getEagle.tcl" script.  It is
+    #       designed to process a single HTTP request, including any HTTP
+    #       3XX redirects (up to the specified limit), and return the raw
+    #       HTTP response data.  It does not contain special code to handle
+    #       HTTP status codes other than 3XX (e.g. 4XX, 5XX, etc).
     #
+    # 
     proc getFileViaHttp { uri redirectLimit channel quiet args } {
+      #
+      # NOTE: This variable is used to keep track of the currently scheduled
+      #       (i.e. pending) [after] event.
+      #
+      variable afterForPageProgress
+
       #
       # NOTE: This procedure requires the modern version of the HTTP package,
       #       which is typically included with the Tcl core distribution.
       #
       package require http 2.0
@@ -1204,10 +1429,17 @@
             set data [::http::data $token]
             ::http::cleanup $token; break
           }
         }
       }
+
+      #
+      # NOTE: If there is a currently scheduled [after] event, cancel it.
+      #
+      if {[info exists afterForPageProgress]} then {
+        catch {after cancel $afterForPageProgress}
+      }
 
       #
       # NOTE: If progress messages were emitted, start a fresh line.
       #
       if {!$quiet} then {
Index: client/pkgr.eagle.harpy
==================================================================
--- client/pkgr.eagle.harpy
+++ client/pkgr.eagle.harpy
@@ -19,32 +19,32 @@
 
   None
   Mistachkin Systems
-  3568d473-0bb6-4f90-be5f-8b450f8736d7
+  46bd3e67-77bb-4fa4-a28a-7c83625d9f52
   SHA512
   Script
-  2016-08-17T20:05:49.0964375Z
+  2016-08-17T22:22:41.5866719Z
   -1.00:00:00
   0x2c322765603b5278
   
-    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
+    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
   
 
Index: client/pkgr.settings.eagle
==================================================================
--- client/pkgr.settings.eagle
+++ client/pkgr.settings.eagle
@@ -12,8 +12,11 @@
 #
 # RCS: @(#) $Id: $
 #
 ###############################################################################
 
+# TODO: Set this to your list of API keys.
+# set ::pkgr_api_keys [list 0000000000000000000000000000000000000000]
+
 variable strictUnknownLanguage false
 variable verboseUnknownResult true
 variable verboseUriDownload true
Index: client/pkgr.settings.eagle.harpy
==================================================================
--- client/pkgr.settings.eagle.harpy
+++ client/pkgr.settings.eagle.harpy
@@ -19,32 +19,32 @@
 
   None
   Mistachkin Systems
-  32fce62e-9899-4d81-b1d8-2fac61bb26fb
+  b44b4ef2-76ad-4786-b4b7-e1d604e15e8b
   SHA512
   Script
-  2016-08-17T19:24:49.1950703Z
+  2016-08-17T22:22:56.6608906Z
   -1.00:00:00
   0x2c322765603b5278
   
-    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
+    efFtWFrnFkJeMBafjl1MxA1lygnogjoQHoS8qP4ptK+GuB7mvyJbSgtjYyUVJ0Nj9W88qJ0eGtQ3
+    5yd2fZrTX7nXmEkXaRFcSBiB/S6dtUrc6GGDO1PlOB7w3JGfSkh/4MgfRTrZyN+sRN6ODWPjFU4s
+    m1+HXSXynBUKyPaJ8qNd/0foXvNC/rGbHyZ+Z4FkbAfYZZSTiIz57kv9ZvlmxjSoZNffYpOGD0kQ
+    mFXkvDkoM4JxE3b19M/VFcKJ6NIn7o6Vqc3Xt40+9W5OTKjLVfpeV8gK01rU1d9+KuBnC3hQWyqZ
+    V0fF2mkyGnxO0LAZpOiQ82b8Myld/vl79iGcMLb9F5+SdnYeqBrT8VFRaiZz12MS+8BP+3JItBqn
+    WNFjKVWFXG5SI6aTaqbTDtiKRADqoJyb6HN5imfZll2tcK2ruICy4zYo79mDAolBEnwp4TnNcwKA
+    h5oQTnc44dQht8xeZdT5Ah2SNRBx0GA3nHmJO9AP68JMYbPWLABQQ6hZf2b6u6zB3ZzU8RN/+NIa
+    3Y5jfKVD/f2BCJumU1jWh2R4785SNXfFT5Id5U0II9I9WhTdiylFXP3hiN/dNW0GAWq9v6TLG+pi
+    vfJrr/26RQfEwIiNa8keQkfJ/HgTmille05ct7DycbHu9Edq9NxWgfTtWDsAnlERTG+WhRc5hZyc
+    VegPWnHpoXeUHgEe5d4bkmmRfePnH+eWeibRveMErlv16jeTv4H28ftp3Vq8n0n+hkVHpYOHMV6i
+    J3/RhJ4G1Se/adEPdVUQRfYrP5HwI/szeR5DQoZ+zAsB34cfwWn0hsj21FeqitSE/rQ0j8pcD3yy
+    OIH07uf/sOqQ8hSEFnxVPTvQYp9H7QTBxFAxaMbpIUTpB6DyroPWzi4uSa+JXWSkf5sQOo2SLCoX
+    t3w7tpZ6o2FZNd3O519FiX3+cM78vyfIMkbT4ZFEHpFkccuG6g9nVgUDCTgMwNldSKQAC7JtwjOZ
+    tSQ9YjRTgZSGcJ+TjLnXJfWo8u0SM+J3K9o+zRcN+6zDZsCAo6inrxgICEFN+lTabJxyWas6MYeX
+    hkq7CnGT9nsDtynLniiF4FUsKTVlgHfR1ZVPwWGb0Ow/L4PdPMTlzPVttsE4bcrii6xnf85O9ijU
+    zfgBhDtRsst9TLXb514J8t4zT54AQPLav2DjXjDjChbm+/JF8ywAfq/v8/A0B3PIeDPgmRTouH48
+    0MFanzDYI3r75OC0ZMuS8EoseqkcC2C3IvJY9ZtsgnuIPbpxzsdooCCaHXUWL2mHZ+QOk8Q+jn7J
+    1V0BeUNi0hU9SZeAai1co8ehsCw3vUkOPUoYginn2ry5ALf/jEBHW+1CX3+jlT/snSZba0GPDg==