From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms0.migadu.com with LMTPS id UCvKKBnKMmJDCQEAgWs5BA (envelope-from ) for ; Thu, 17 Mar 2022 06:41:45 +0100 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id 0Nr8IBnKMmKj4AAAG6o9tA (envelope-from ) for ; Thu, 17 Mar 2022 06:41:45 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 87810257DE for ; Thu, 17 Mar 2022 06:41:44 +0100 (CET) Received: from localhost ([::1]:42334 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nUitI-0007bA-1U for larch@yhetil.org; Thu, 17 Mar 2022 01:41:40 -0400 Received: from eggs.gnu.org ([209.51.188.92]:53010) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nUiUU-0001AK-NK for guix-patches@gnu.org; Thu, 17 Mar 2022 01:16:02 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:58870) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1nUiUU-0003uZ-ES for guix-patches@gnu.org; Thu, 17 Mar 2022 01:16:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1nUiUU-0005dT-3K for guix-patches@gnu.org; Thu, 17 Mar 2022 01:16:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#54344] [PATCH 3/3] guix home: Implement the 'extension-graph' and 'shepherd-graph' actions. Resent-From: Andrew Tropin Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 17 Mar 2022 05:16:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 54344 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: Ludovic =?UTF-8?Q?Court=C3=A8s?= , 54344@debbugs.gnu.org Cc: Ludovic =?UTF-8?Q?Court=C3=A8s?= Received: via spool by 54344-submit@debbugs.gnu.org id=B54344.164749410521583 (code B ref 54344); Thu, 17 Mar 2022 05:16:02 +0000 Received: (at 54344) by debbugs.gnu.org; 17 Mar 2022 05:15:05 +0000 Received: from localhost ([127.0.0.1]:52766 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nUiTV-0005bO-5W for submit@debbugs.gnu.org; Thu, 17 Mar 2022 01:15:04 -0400 Received: from mail-lf1-f45.google.com ([209.85.167.45]:36714) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1nUiTS-0005b8-De for 54344@debbugs.gnu.org; Thu, 17 Mar 2022 01:14:59 -0400 Received: by mail-lf1-f45.google.com with SMTP id bt26so7191882lfb.3 for <54344@debbugs.gnu.org>; Wed, 16 Mar 2022 22:14:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=trop-in.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:in-reply-to:references:date:message-id :mime-version; bh=QxPfbSHeM/D9ZE3yO0Ned23c+JzwDW7gCIDzD33MC50=; b=LgbJ7f/RgmGMw79Fh7a4D6ld+v4S21tOLm6/XXzg0ikOqdGTqalI4lToypt0lrRBFQ O4R0fmC2Z12StTx1LjHtv2gy7a8v/Bgxi5HbNRqxfDVAQVAe2nBnGIpySgxsU0npPFft ZHRrii6CysVA7/QuY22htOPGNYDZ2HNzhklazGaG6A2WWEwfugloX+NlLACPE7tCbjFG bkv6aUsIs/AXxc7+sfJr7vgoAJmcSpYYYxEEYcpwsDvH/GW1yRWxFKVlMTbbsDZt2nSX 8JDYTAc/njvYkdDRE6P9QPDilWWR3Sfc+5+8TUpg02Lg9zNzqA6KdJWAwGzWanc5N+tK 0iIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:in-reply-to:references:date :message-id:mime-version; bh=QxPfbSHeM/D9ZE3yO0Ned23c+JzwDW7gCIDzD33MC50=; b=6xrm0L1E5Yt72/tNIwmF4J+0tUqaMWoRgKFVq03YMutYBCMZR5DjMLWdevTfSxJoNe k/WZjnfKJ6CQ0QTHAxzsWY6WzmTXduf/bSFKTVGYNn/XGUevxSbcB+xuQWpXSAo9PJ4n RCVML8h1oyx1wYXBx9QytLwa9Th5X+qvSDzjhoXnd+8LkshuaBbks8QARczI2MA9ajUP /LwgFz9vGGH4ISze5aF37H9csGDyjCGhmCKQHNSv5+8y4MBpJj22CAyBYCQk0NjoT7rW hyjon9SEEAXpcTK6NRCaZ42D6KFAnTu5PrF5gkMg8L03EIydTQaDZxJbsMwnuM2ymXyq 9kRQ== X-Gm-Message-State: AOAM530Zj4avgu3A3lRquyUB+L0P02fSqxwR6fZ/mVHGst6jMn6UKuiR GATVrKkUWMwbf4f51RaRhUERZ/kNPvYd2c7X X-Google-Smtp-Source: ABdhPJxEzXwHsN3xjeKDGEH3NvrLO5ymxDrKBnefu55MXRSnBF+SYk0hfEHl8JLecRfF+Wx2uRcDVw== X-Received: by 2002:a05:6512:2383:b0:448:1d9e:589f with SMTP id c3-20020a056512238300b004481d9e589fmr1743360lfv.649.1647494091943; Wed, 16 Mar 2022 22:14:51 -0700 (PDT) Received: from localhost (109-252-132-136.dynamic.spd-mgts.ru. [109.252.132.136]) by smtp.gmail.com with ESMTPSA id u19-20020a197913000000b00448a1f20261sm339322lfc.34.2022.03.16.22.14.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Mar 2022 22:14:51 -0700 (PDT) From: Andrew Tropin In-Reply-To: <20220311213418.12472-3-ludo@gnu.org> References: <20220311213418.12472-1-ludo@gnu.org> <20220311213418.12472-3-ludo@gnu.org> Date: Thu, 17 Mar 2022 08:14:47 +0300 Message-ID: <874k3xjh2w.fsf@trop.in> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha512; protocol="application/pgp-signature" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: "Guix-patches" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1647495704; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=zBOvz9Nwpk8et74Xidh/S7Rb8tPV6m+73VKi4QPR+Hg=; b=Cde5BSJFdKK4/HuuasBuCjGhpPeTP/7hzt7AlkO2KuVqo1BnrhUSwZAcley3fs9cduaNGB QolfEbd9y4Re0A5TBHfHeLzOxSs2AwblZyZsDJ1LilVhilG5cpCZnTwtKtWE3OwwAeOKgL EPh98kFtKev0EZTfiW0Wt1fV2ijotu9SjB+JFIAY4c8aI5ylK590+bdrdKOLp5vcuh6AtG mW4aK/LAgzOW7MLow66AHrU5V175i7KZZ2iHsxAgOSHQy8yVXZ6+w7LXxA8DxLQ9nU4JX2 9SpQoEN9fVrHw40X8Igm0F/Ewh5k2ibtP0pkSqdqPj1XGGyD+xgMDyA7F4uBnQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1647495704; a=rsa-sha256; cv=none; b=ZkDc+CZAn3q3tAhAD2zH8F/U7mPfTNhACfxQx8w3SIF2zsa2oJTB+7vZW2oihDSYSX5X9/ e5jSAC3NIcGkAreSOVp7f71AMy4b8CdUQNIDLH1wGCLXyiHxeitYTO/eFbxt7EvxNoIggl P+VK+pCCFjF/BA87xIgr9B8LRxdAMcrU9UUfZ9vYOB8eVFopeRK+2biLcoaytOBv+Fqbl0 y2hMkeW41C6lI7fMWLbVjerQ+sNGTbFowZK82kGhPCZFEKQtewr7Dp8vy+UDUXJ2FXnmdH D6C1vcY/hmBBsEVEGF7v8G+lA8JBq7otzeDXL9L8BqXQnNpoA5lNQ52KAWsA5g== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=trop-in.20210112.gappssmtp.com header.s=20210112 header.b="LgbJ7f/R"; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -1.96 Authentication-Results: aspmx1.migadu.com; dkim=fail ("body hash did not verify") header.d=trop-in.20210112.gappssmtp.com header.s=20210112 header.b="LgbJ7f/R"; dmarc=none; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 87810257DE X-Spam-Score: -1.96 X-Migadu-Scanner: scn0.migadu.com X-TUID: CBPX5aoFUo8Z --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 2022-03-11 22:34, Ludovic Court=C3=A8s wrote: > Until now these two actions were silently ignored. > > * guix/scripts/home.scm (show-help, %options): Add "--graph-backend". > (%default-options): Add 'graph-backend' key. > (export-extension-graph, export-shepherd-graph): New procedures. > (perform-action): Add #:graph-backend parameter. Add cases for the > 'extension-graph' and 'shepherd-graph' actions. > (process-action): Pass #:graph-backend to 'perform-action'. > * guix/scripts/system.scm (service-node-type) > (shepherd-service-node-type): Export > * tests/guix-home.sh: Add tests. > * doc/guix.texi (Invoking guix home): Document it. > --- > doc/guix.texi | 31 +++++++++++ > guix/scripts/home.scm | 117 ++++++++++++++++++++++++++++++---------- > guix/scripts/system.scm | 5 +- > tests/guix-home.sh | 8 +++ > 4 files changed, 131 insertions(+), 30 deletions(-) > > diff --git a/doc/guix.texi b/doc/guix.texi > index 4b71fb7010..e7d862f5be 100644 > --- a/doc/guix.texi > +++ b/doc/guix.texi > @@ -38848,7 +38848,38 @@ environment. Note that not every home service t= hat exists is supported > $ guix home import ~/guix-config > guix home: '/home/alice/guix-config' populated with all the Home configu= ration files > @end example > +@end table >=20=20 > +And there's more! @command{guix home} also provides the follow s/follow/following > +sub-commands to visualize how the services of your home environment > +relate to one another: > + > +@table @code > +@cindex service extension graph, of a home environment > +@item extension-graph > +Emit to standard output the @dfn{service extension graph} of the home > +environment defined in @var{file} (@pxref{Service Composition}, for more > +information on service extensions). By default the output is in > +Dot/Graphviz format, but you can choose a different format with > +@option{--graph-backend}, as with @command{guix graph} (@pxref{Invoking > +guix graph, @option{--backend}}): > + > +The command: > + > +@example > +$ guix home extension-graph @var{file} | xdot - > +@end example > + > +shows the extension relations among services. > + > +@cindex Shepherd dependency graph, for a home environment > +@item shepherd-graph > +Emit to standard output the @dfn{dependency graph} of shepherd services > +of the home environment defined in @var{file}. @xref{Shepherd > +Services}, for more information and for an example graph. > + > +Again, the default output format is Dot/Graphviz, but you can pass > +@option{--graph-backend} to select a different one. > @end table >=20=20 > @var{options} can contain any of the common build options (@pxref{Common > diff --git a/guix/scripts/home.scm b/guix/scripts/home.scm > index 837fd96361..db98a1df48 100644 > --- a/guix/scripts/home.scm > +++ b/guix/scripts/home.scm > @@ -3,6 +3,7 @@ > ;;; Copyright =C2=A9 2021 Xinglu Chen > ;;; Copyright =C2=A9 2021 Pierre Langlois > ;;; Copyright =C2=A9 2021 Oleg Pykhalov > +;;; Copyright =C2=A9 2022 Ludovic Court=C3=A8s > ;;; > ;;; This file is part of GNU Guix. > ;;; > @@ -25,6 +26,9 @@ (define-module (guix scripts home) > #:use-module (gnu packages) > #:use-module (gnu home) > #:use-module (gnu home services) > + #:autoload (gnu home services shepherd) (home-shepherd-service-type > + home-shepherd-configuration= -services > + shepherd-service-requiremen= t) > #:use-module (guix channels) > #:use-module (guix derivations) > #:use-module (guix ui) > @@ -33,13 +37,16 @@ (define-module (guix scripts home) > #:use-module (guix profiles) > #:use-module (guix store) > #:use-module (guix utils) > + #:autoload (guix graph) (lookup-backend export-graph) > #:use-module (guix scripts) > #:use-module (guix scripts package) > #:use-module (guix scripts build) > #:autoload (guix scripts system search) (service-type->recutils) > #:use-module (guix scripts system reconfigure) > #:autoload (guix scripts pull) (channel-commit-hyperlink) > - #:use-module (guix scripts home import) > + #:autoload (guix scripts system) (service-node-type > + shepherd-service-node-type) > + #:autoload (guix scripts home import) (import-manifest) > #:use-module ((guix status) #:select (with-status-verbosity)) > #:use-module ((guix build utils) #:select (mkdir-p)) > #:use-module (guix gexp) > @@ -87,6 +94,10 @@ (define (show-help) > build build the home environment without installing anyt= hing\n")) > (display (G_ "\ > import generates a home environment definition from dotfi= les\n")) > + (display (G_ "\ > + extension-graph emit the service extension graph\n")) > + (display (G_ "\ > + shepherd-graph emit the graph of shepherd services\n")) >=20=20 > (show-build-options-help) > (display (G_ " > @@ -97,6 +108,9 @@ (define (show-help) > channel revisions")) > (display (G_ " > -v, --verbosity=3DLEVEL use the given verbosity LEVEL")) > + (display (G_ " > + --graph-backend=3DBACKEND > + use BACKEND for 'extension-graph' and 'shepherd= -graph'")) > (newline) > (display (G_ " > -h, --help display this help and exit")) > @@ -136,6 +150,10 @@ (define %options > (alist-cons 'validate-reconfigure > warn-about-backward-reconfigure > result))) > + (option '("graph-backend") #t #f > + (lambda (opt name arg result) > + (alist-cons 'graph-backend arg result))) > + > %standard-build-options)) >=20=20 > (define %default-options > @@ -147,18 +165,49 @@ (define %default-options > (multiplexed-build-output? . #t) > (verbosity . #f) ;default > (debug . 0) > - (validate-reconfigure . ,ensure-forward-reconfigure))) > + (validate-reconfigure . ,ensure-forward-reconfigure) > + (graph-backend . "graphviz"))) >=20=20 > > ;;; > ;;; Actions. > ;;; >=20=20 > +(define* (export-extension-graph home port > + #:key (backend (lookup-backend "graphvi= z"))) > + "Export the service extension graph of HOME to PORT using BACKEND." > + (let* ((services (home-environment-services home)) > + (home (find (lambda (service) > + (eq? (service-kind service) home-service-type= )) > + services))) > + (export-graph (list home) (current-output-port) s/current-output-port/port > + #:backend backend > + #:node-type (service-node-type services) > + #:reverse-edges? #t))) > + > +(define* (export-shepherd-graph home port > + #:key (backend (lookup-backend "graphviz= "))) > + "Export the graph of shepherd services of HOME to PORT using BACKEND." > + (let* ((services (home-environment-services home)) > + (root (fold-services services > + #:target-type home-shepherd-service-t= ype)) > + ;; Get the list of . > + (shepherds (home-shepherd-configuration-services > + (service-value root))) > + (sinks (filter (lambda (service) > + (null? (shepherd-service-requirement servi= ce))) > + shepherds))) > + (export-graph sinks (current-output-port) s/current-output-port/port > + #:backend backend > + #:node-type (shepherd-service-node-type shepherds) > + #:reverse-edges? #t))) > + > (define* (perform-action action he > #:key > dry-run? > derivations-only? > use-substitutes? > + (graph-backend "graphviz") > (validate-reconfigure ensure-forward-reconfigur= e)) > "Perform ACTION for home environment. " >=20=20 > @@ -169,35 +218,43 @@ (define println > (check-forward-update validate-reconfigure > #:current-channels (home-provenance %guix-home= ))) >=20=20 > - (mlet* %store-monad > - ((he-drv (home-environment-derivation he)) > - (drvs (mapm/accumulate-builds lower-object (list he-drv))) > - (% (if derivations-only? > - (return > - (for-each (compose println derivation-file-name) d= rvs)) > - (built-derivations drvs))) > + (case action > + ((extension-graph) > + (export-extension-graph he (current-output-port) > + #:backend (lookup-backend graph-backend))) > + ((shepherd-graph) > + (export-shepherd-graph he (current-output-port) > + #:backend (lookup-backend graph-backend))) > + (else > + (mlet* %store-monad > + ((he-drv (home-environment-derivation he)) > + (drvs (mapm/accumulate-builds lower-object (list he-drv))) > + (% (if derivations-only? > + (return > + (for-each (compose println derivation-file-name= ) drvs)) > + (built-derivations drvs))) >=20=20 > - (he-out-path -> (derivation->output-path he-drv))) > - (if (or dry-run? derivations-only?) > - (return #f) > - (begin > - (for-each (compose println derivation->output-path) drvs) > + (he-out-path -> (derivation->output-path he-drv))) > + (if (or dry-run? derivations-only?) > + (return #f) > + (begin > + (for-each (compose println derivation->output-path) drvs) >=20=20 > - (case action > - ((reconfigure) > - (let* ((number (generation-number %guix-home)) > - (generation (generation-file-name > - %guix-home (+ 1 number)))) > + (case action > + ((reconfigure) > + (let* ((number (generation-number %guix-home)) > + (generation (generation-file-name > + %guix-home (+ 1 number)))) >=20=20 > - (switch-symlinks generation he-out-path) > - (switch-symlinks %guix-home generation) > - (setenv "GUIX_NEW_HOME" he-out-path) > - (primitive-load (string-append he-out-path "/activate")) > - (setenv "GUIX_NEW_HOME" #f) > - (return he-out-path))) > - (else > - (newline) > - (return he-out-path))))))) > + (switch-symlinks generation he-out-path) > + (switch-symlinks %guix-home generation) > + (setenv "GUIX_NEW_HOME" he-out-path) > + (primitive-load (string-append he-out-path "/activate"= )) > + (setenv "GUIX_NEW_HOME" #f) > + (return he-out-path))) > + (else > + (newline) > + (return he-out-path))))))))) >=20=20 > (define (process-action action args opts) > "Process ACTION, a sub-command, with the arguments are listed in ARGS. > @@ -256,7 +313,9 @@ (define (ensure-home-environment file-or-exp obj) > #:derivations-only? (assoc-ref opts 'derivat= ions-only?) > #:use-substitutes? (assoc-ref opts 'substitu= tes?) > #:validate-reconfigure > - (assoc-ref opts 'validate-reconfigure)))))) > + (assoc-ref opts 'validate-reconfigure) > + #:graph-backend > + (assoc-ref opts 'graph-backend)))))) > (warn-about-disk-space))) >=20=20 >=20=20 > diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm > index 6f7dcd4643..55e9b8ba30 100644 > --- a/guix/scripts/system.scm > +++ b/guix/scripts/system.scm > @@ -88,7 +88,10 @@ (define-module (guix scripts system) > #:use-module (ice-9 match) > #:use-module (rnrs bytevectors) > #:export (guix-system > - read-operating-system)) > + read-operating-system > + > + service-node-type > + shepherd-service-node-type)) >=20=20 > > ;;; > diff --git a/tests/guix-home.sh b/tests/guix-home.sh > index f054d15172..48dbcbd28f 100644 > --- a/tests/guix-home.sh > +++ b/tests/guix-home.sh > @@ -93,6 +93,14 @@ trap 'chmod -Rf +w "$test_directory"; rm -rf "$test_di= rectory"' EXIT > "# the content of bashrc-test-config.sh")))))))) > EOF >=20=20 > + # Check whether the graph commands work as expected. > + guix home extension-graph "home.scm" | grep 'label =3D "home-activat= ion"' > + guix home extension-graph "home.scm" | grep 'label =3D "home-symlink= -manager"' > + guix home extension-graph "home.scm" | grep 'label =3D "home"' > + > + # There are no Shepherd services so the one below must fail. > + ! guix home shepherd-graph "home.scm" > + > guix home reconfigure "${test_directory}/home.scm" > test -d "${HOME}/.guix-home" > test -h "${HOME}/.bash_profile" =2D-=20 Best regards, Andrew Tropin --=-=-= Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQJDBAEBCgAtFiEEKEGaxlA4dEDH6S/6IgjSCVjB3rAFAmIyw8gPHGFuZHJld0B0 cm9wLmluAAoJECII0glYwd6wuu4P/ie/6Ooyx8vn1a1G0dztbAr1nJsjoLkk5Wnc VE4hPa2l3bYnSLUW2cPNmKBT1+IqMIqL1QhGqTIpIed+rLsSvDWmj4RSW8JVCJt7 m4YomVdTiyKNQq2sl2T0iKeZeBBkepkQX3X+3Vz4/tRKLUTy/nMBAWDuakHLDkqx 5VmR0YaN8LGc62ft5r94vgredgw8+m3o2do7sh4l7aJkLoHSXsgytGFPQxO5qWY5 rs641XqqcP1xH5nMXamY8ATWhoUqKekhH0wPYrTzJi5TA5nKBKzlHb6EmAX3mBW0 K9EeFQB1ycenJRkPZM9z5ERoBnSsxh/4wr85FZ3d+tukmQ2fhY/TabkuD57Q3CCs RbmB3GSgD4N10KbBHN1wqiOrM9sRixVyugqffs5n9C85QPIj9ORk9JO19zRxDQ4r JPA7bye3Bo8A6SIILDSwJU20pI2NvIMr4rGjmVQ8PU7bl9j+UiToNGp1QvA+FSop rOw5TwzvQTvZxF1iuEpb7FDi2kHkPeyUd/7k3ExQc7bbdUJakG1H+A36NWUUvEJN rGKoAoWf/AF1CRIQDEi4x5t+TyUlDa3wN7imEeeJ0+LPFUu9CbnGFOXXm0c9bEDH w9Xh+6LnEfY0LPhLFm5KcKnmNRkjzNlkP6gjAtHRBZ+mX0VYF188Xorz9rXukTKg pnrCNXXo =fcYw -----END PGP SIGNATURE----- --=-=-=--