diff --git a/README.md b/README.md index 0241fd40..9f6dc7c5 100644 --- a/README.md +++ b/README.md @@ -34,17 +34,10 @@ Make ttracer run once. ### ttctl ```shell-session -$ ttctl --level 2 --dest-ipv4 10.0.0.21 -10.0.0.21:80 -└<-- 10.0.0.22:many ('nginx', pgid=2000, connections=30) -└<-- 10.0.0.23:many ('nginx', pgid=891, connections=30) -└<-- 10.0.0.24:many ('nginx', pgid=1002, connections=30) - └<-- 10.0.0.30:many ('python', pgid=1889 connections=1) - └<-- 10.0.0.31:many ('python', pgid=1998 connections=1) -└<-- 10.0.0.25:many (connections:30) - -10.0.0.21:22 -└<-- 10.0.0.100:many +$ ttctl --dbhost 10.0.0.20 --ipv4 10.0.0.10 10.0.0.10:80 (’nginx’, pgid=4656) +└<-- 10.0.0.11:many (’wrk’, pgid=5982) 10.0.0.10:80 (’nginx’, pgid=4656) +└--> 10.0.0.12:8080 (’python’, pgid=6111) 10.0.0.10:many (’fluentd’, pgid=2127) +└--> 10.0.0.13:24224 (’fluentd’, pgid=2001) ``` ## License diff --git a/cmd/ttctl/cli.go b/cmd/ttctl/cli.go index 0ea58b26..b63bf01b 100644 --- a/cmd/ttctl/cli.go +++ b/cmd/ttctl/cli.go @@ -6,7 +6,6 @@ import ( "io" "log" "net" - "strings" "github.com/yuuki/transtracer/db" "github.com/yuuki/transtracer/statik" @@ -125,58 +124,64 @@ func (c *CLI) doIPv4(ipv4 string, depth int, opt *db.Opt) int { return exitCodeErr } addr := net.ParseIP(ipv4) - portsbyaddr, err := db.FindListeningPortsByAddrs([]net.IP{addr}) + + // print thet flows of passive nodes + pflows, err := db.FindPassiveFlows([]net.IP{addr}) if err != nil { - log.Printf("find listening ports by addrs error: %v\n", err) + log.Printf("find active flows error: %v\n", err) return exitCodeErr } - for _, addrports := range portsbyaddr { - for _, addrport := range addrports { - fmt.Fprintf(c.outStream, "%s:%d ('%s', pgid=%d)\n", addrport.IPAddr, addrport.Port, addrport.Pname, addrport.Pgid) - if err := c.printIPv4(db, addrport, 1, depth); err != nil { - log.Printf("print dest ipv4 error: %v\n", err) - return exitCodeErr - } - } + for _, flows := range pflows { + pnode := flows[0].PassiveNode + fmt.Fprintf(c.outStream, + "%s:%d ('%s', pgid=%d)\n", pnode.IPAddr, pnode.Port, pnode.Pname, pnode.Pgid) + + c.printPassiveFlows(flows) + } + + // print the flows of active nodes + aflows, err := db.FindActiveFlows([]net.IP{addr}) + if err != nil { + log.Printf("find active flows error: %v\n", err) + return exitCodeErr } + for _, flows := range aflows { + anode := flows[0].ActiveNode + fmt.Fprintf(c.outStream, + "%s ('%s', pgid=%d)\n", anode.IPAddr, anode.Pname, anode.Pgid) + + c.printActiveFlows(flows) + } + return exitCodeOK } -func (c *CLI) printIPv4(db *db.DB, addrport *db.AddrPort, curDepth, depth int) error { - addrports, err := db.FindSourceByDestAddrAndPort(addrport.IPAddr, addrport.Port) - if err != nil { - return err - } - if len(addrports) == 0 { - return nil - } - indent := strings.Repeat("\t", curDepth-1) - curDepth++ - depth-- - for _, addrport := range addrports { - fmt.Fprint(c.outStream, indent) - fmt.Fprint(c.outStream, "└<-- ") - fmt.Fprint(c.outStream, addrport) - fmt.Fprintln(c.outStream) - if err := c.printIPv4(db, addrport, curDepth, depth); err != nil { - return err - } +func (c *CLI) printPassiveFlows(flows []*db.Flow) { + // No implementation of printing tree with depth > 1 + for _, flow := range flows { + fmt.Fprintf(c.outStream, "└<-- %s\n", flow.ActiveNode) + } +} + +func (c *CLI) printActiveFlows(flows []*db.Flow) { + // No implementation of printing tree with depth > 1 + for _, flow := range flows { + fmt.Fprintf(c.outStream, "└--> %s\n", flow.PassiveNode) } - return nil } var helpText = `Usage: ttctl [options] -ttctl is a CLI controller for mftracer system. +ttctl is a CLI controller for transtracer. Options: - --create-schema create mftracer table schema for postgres + --create-schema create transtracer table schema for postgres --dbuser postgres user --dbpass postgres user password --dbhost postgres host --dbport postgres port --dbname postgres database name - --dest-ipv4 filter by destination ipv4 address + --ipv4 print trees regarding the ipv4 address as a root node --version, -v print version --help, -h print help ` diff --git a/db/db.go b/db/db.go index f23e4769..12b70647 100644 --- a/db/db.go +++ b/db/db.go @@ -309,114 +309,191 @@ func (db *DB) InsertOrUpdateHostFlows(flows []*tcpflow.HostFlow) error { return nil } -// AddrPort are IP addr and port. -type AddrPort struct { - IPAddr net.IP - Port int - Pgid int - Pname string - Connections int +// Node represents a minimum unit of a graph tree. +type Node struct { + IPAddr net.IP + Port int // 0 if active node + Pgid int // Process Group ID (Linux) + Pname string // Process Name (Linux) } -func (a *AddrPort) String() string { - port := fmt.Sprintf("%d", a.Port) - if a.Port == 0 { +func (n *Node) String() string { + port := fmt.Sprintf("%d", n.Port) + if n.Port == 0 { port = "many" } - return fmt.Sprintf("%s:%s ('%s', pgid=%d, connections=%d)", a.IPAddr, port, a.Pname, a.Pgid, a.Connections) + return fmt.Sprintf("%s:%s ('%s', pgid=%d)", + n.IPAddr, port, n.Pname, n.Pgid) } -// FindListeningPortsByAddrs find listening ports for multiple `addrs`. -func (db *DB) FindListeningPortsByAddrs(addrs []net.IP) (map[string][]*AddrPort, error) { +// Flows represents a flow between a active node and a passive node. +type Flow struct { + ActiveNode *Node + PassiveNode *Node + Connections int +} + +// Flows represents a collection of flow. +type Flows map[string][]*Flow // flows group by + +// FindPassiveFlows queries passive flows to CMDB by the slice of ipaddrs. +func (db *DB) FindPassiveFlows(addrs []net.IP) (Flows, error) { ipv4s := make([]string, 0, len(addrs)) for _, addr := range addrs { ipv4s = append(ipv4s, addr.String()) } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() + rows, err := db.QueryContext(ctx, ` - SELECT ipv4, port, pgid, pname FROM passive_nodes - INNER JOIN processes ON processes.process_id = passive_nodes.process_id - WHERE processes.ipv4 = ANY($1) + SELECT + DISTINCT ON (pipv4, pn.pname) + pn.ipv4 AS pipv4, + pn.pname AS ppname, + pn.port AS pport, + pn.pgid AS ppgid, + active_processes.ipv4 AS aipv4, + active_processes.pname AS apname, + active_processes.pgid AS apgid, + connections, + flows.updated AS updated + FROM flows + INNER JOIN active_nodes ON active_nodes.node_id = flows.source_node_id + INNER JOIN processes AS active_processes ON active_nodes.process_id = active_processes.process_id + INNER JOIN ( + SELECT passive_nodes.node_id, passive_nodes.port, passive_processes.* FROM passive_nodes + INNER JOIN processes AS passive_processes ON passive_processes.process_id = passive_nodes.process_id + WHERE passive_processes.ipv4 = ANY($1) + ) AS pn ON pn.node_id = flows.destination_node_id + ORDER BY pn.ipv4, pn.pname, flows.updated DESC `, pq.Array(ipv4s)) - if err == sql.ErrNoRows { - return map[string][]*AddrPort{}, nil - } - if err != nil { - return nil, xerrors.Errorf("query error: %v", err) + switch { + case err == sql.ErrNoRows: + return Flows{}, nil + case err != nil: + return Flows{}, xerrors.Errorf("find passive flows query error: %v", err) } defer rows.Close() - portsbyaddr := make(map[string][]*AddrPort) + flows := make(Flows, 0) for rows.Next() { var ( - addr string - port int - pgid int - pname string + pipv4 string + ppname string + pport int + ppgid int + aipv4 string + apname string + apgid int + connections int + updated time.Time ) - if err := rows.Scan(&addr, &port, &pgid, &pname); err != nil { - return nil, xerrors.Errorf("query error: %v", err) - } - if port == 0 { // port == 0 means 'many' - continue + if err := rows.Scan( + &pipv4, &ppname, &pport, &ppgid, &aipv4, &apname, &apgid, &connections, &updated, + ); err != nil { + return nil, xerrors.Errorf("rows scan error: %v", err) } - portsbyaddr[addr] = append(portsbyaddr[addr], &AddrPort{ - IPAddr: net.ParseIP(addr), - Port: port, - Pgid: pgid, - Pname: pname, + key := fmt.Sprintf("%s-%s", pipv4, ppname) + flows[key] = append(flows[key], &Flow{ + ActiveNode: &Node{ + IPAddr: net.ParseIP(aipv4), + Port: 0, + Pgid: apgid, + Pname: apname, + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP(pipv4), + Port: pport, + Pgid: ppgid, + Pname: ppname, + }, + Connections: connections, }) } - return portsbyaddr, nil + if err := rows.Err(); err != nil { + return nil, xerrors.Errorf("rows error: %v", err) + } + + return flows, nil } -// FindSourceByDestAddrAndPort find source nodes. -func (db *DB) FindSourceByDestAddrAndPort(addr net.IP, port int) ([]*AddrPort, error) { +// FindActiveFlows queries active flows to CMDB by the slice of ipaddrs. +func (db *DB) FindActiveFlows(addrs []net.IP) (Flows, error) { + ipv4s := make([]string, 0, len(addrs)) + for _, addr := range addrs { + ipv4s = append(ipv4s, addr.String()) + } + ctx, cancel := context.WithCancel(context.Background()) defer cancel() + rows, err := db.QueryContext(ctx, ` SELECT - connections, flows.updated AS updated, processes.ipv4 AS source_ipv4, pn.port AS source_port, processes.pgid AS pgid, processes.pname AS pname + DISTINCT ON (aipv4, an.pname) + an.ipv4 AS aipv4, + an.pname AS apname, + passive_nodes.port AS pport, + an.pgid AS apgid, + passive_processes.ipv4 AS pipv4, + passive_processes.pname AS ppname, + passive_processes.pgid AS ppgid, + connections, + flows.updated AS updated FROM flows - INNER JOIN active_nodes ON active_nodes.node_id = flows.source_node_id - INNER JOIN processes ON processes.process_id = active_nodes.process_id - INNER JOIN ( - SELECT passive_nodes.node_id, passive_nodes.port FROM passive_nodes - INNER JOIN processes ON processes.process_id = passive_nodes.process_id - WHERE processes.ipv4 = $1 AND passive_nodes.port = $2 - ) AS pn ON flows.destination_node_id = pn.node_id -`, addr.String(), port) + INNER JOIN passive_nodes ON passive_nodes.node_id = flows.destination_node_id + INNER JOIN processes AS passive_processes ON passive_nodes.process_id = passive_processes.process_id + INNER JOIN ( + SELECT node_id, active_processes.* FROM active_nodes + INNER JOIN processes AS active_processes ON active_processes.process_id = active_nodes.process_id + WHERE active_processes.ipv4 = ANY($1) + ) AS an ON an.node_id = flows.source_node_id + ORDER BY an.ipv4, an.pname, flows.updated DESC +`, pq.Array(ipv4s)) switch { case err == sql.ErrNoRows: - return []*AddrPort{}, nil + return Flows{}, nil case err != nil: - return []*AddrPort{}, xerrors.Errorf("find source nodes error: %v", err) + return Flows{}, xerrors.Errorf("find active flows query error: %v", err) } defer rows.Close() - addrports := make([]*AddrPort, 0) + + flows := make(Flows, 0) for rows.Next() { var ( + aipv4 string + apname string + pport int + apgid int + pipv4 string + ppname string + ppgid int connections int updated time.Time - sipv4 string - sport int - spgid int - spname string ) - if err := rows.Scan(&connections, &updated, &sipv4, &sport, &spgid, &spname); err != nil { + if err := rows.Scan(&aipv4, &apname, &pport, &apgid, &pipv4, &ppname, &ppgid, &connections, &updated); err != nil { return nil, xerrors.Errorf("rows scan error: %v", err) } - addrports = append(addrports, &AddrPort{ - IPAddr: net.ParseIP(sipv4), - Port: sport, - Pgid: spgid, - Pname: spname, + key := fmt.Sprintf("%s-%s", aipv4, apname) + flows[key] = append(flows[key], &Flow{ + ActiveNode: &Node{ + IPAddr: net.ParseIP(aipv4), + Port: 0, + Pgid: apgid, + Pname: apname, + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP(pipv4), + Port: pport, + Pgid: ppgid, + Pname: ppname, + }, Connections: connections, }) } if err := rows.Err(); err != nil { return nil, xerrors.Errorf("rows error: %v", err) } - return addrports, nil + + return flows, nil } diff --git a/db/db_test.go b/db/db_test.go index 67fa1f51..e9600499 100644 --- a/db/db_test.go +++ b/db/db_test.go @@ -2,7 +2,6 @@ package db import ( "database/sql" - "log" "net" "testing" "time" @@ -244,34 +243,85 @@ func TestInsertOrUpdateHostFlows_empty_process(t *testing.T) { } } -func TestFindListeningPortsByAddrs(t *testing.T) { +func TestFindPassiveFlows(t *testing.T) { db, mock := NewTestDB() defer db.Close() - straddrs := pq.Array([]string{"192.0.2.1", "192.0.2.2"}) - columns := sqlmock.NewRows([]string{"ipv4", "port", "pgid", "pname"}) - mock.ExpectQuery("SELECT (.+) FROM passive_nodes").WithArgs(straddrs).WillReturnRows( - columns.AddRow("192.0.2.1", 80, 833, "nginx").AddRow("192.0.2.2", 443, 1001, "nginx"), - ) + paddrs := []net.IP{net.ParseIP("192.168.3.1"), net.ParseIP("192.168.3.2")} + + columns := sqlmock.NewRows([]string{ + "pipv4", + "ppname", + "pport", + "ppgid", + "aipv4", + "apname", + "apgid", + "connections", + "updated", + }) + + // flow1 + pipv4, ppname, ppgid, pport := "192.168.3.1", "unicorn", 10021, 8000 + aipv4, apname, apgid := "192.168.2.1", "nginx", 4123 + connections := 10 + columns.AddRow(pipv4, ppname, pport, ppgid, aipv4, apname, apgid, connections, time.Now()) - addrs := []net.IP{ - net.ParseIP("192.0.2.1"), - net.ParseIP("192.0.2.2"), - } - portsbyaddr, err := db.FindListeningPortsByAddrs(addrs) + // flow2 + pipv4, ppname, ppgid, pport = "192.168.3.1", "unicorn", 10021, 8000 + aipv4, apname, apgid = "192.168.5.1", "varnish", 13456 + connections = 20 + columns.AddRow(pipv4, ppname, pport, ppgid, aipv4, apname, apgid, connections, time.Now()) + + mock.ExpectQuery("SELECT (.+) FROM flows").WithArgs( + pq.Array([]string{"192.168.3.1", "192.168.3.2"}), + ).WillReturnRows(columns) + + flows, err := db.FindPassiveFlows(paddrs) if err != nil { t.Fatalf("%+v", err) } - if len(portsbyaddr) != 2 { - t.Errorf("portsbyaddr should be 2, but %v", len(portsbyaddr)) + if len(flows) != 1 { + t.Errorf("flows should be 2, but %v", len(flows)) } - if ports, ok := portsbyaddr[addrs[0].String()]; !ok || ports[0].Port != 80 { - log.Println(ports) - t.Errorf("portsbyaddr should have '192.0.2.1' as key. value should be 80: %v", ports) + + want := Flows{ + "192.168.3.1-unicorn": []*Flow{ + { + ActiveNode: &Node{ + IPAddr: net.ParseIP("192.168.2.1"), + Port: 0, + Pgid: 4123, + Pname: "nginx", + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP("192.168.3.1"), + Port: 8000, + Pgid: 10021, + Pname: "unicorn", + }, + Connections: 10, + }, + { + ActiveNode: &Node{ + IPAddr: net.ParseIP("192.168.5.1"), + Port: 0, + Pgid: 13456, + Pname: "varnish", + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP("192.168.3.1"), + Port: 8000, + Pgid: 10021, + Pname: "unicorn", + }, + Connections: 20, + }, + }, } - if ports, ok := portsbyaddr[addrs[1].String()]; !ok || ports[0].Port != 443 { - t.Errorf("portsbyaddr should have '192.0.2.2' as key. value should be 443: %v", ports) + if diff := cmp.Diff(want, flows); diff != "" { + t.Errorf("FindDestNodes() mismatch (-want +got):\n%s", diff) } if err := mock.ExpectationsWereMet(); err != nil { @@ -279,39 +329,85 @@ func TestFindListeningPortsByAddrs(t *testing.T) { } } -func TestFindSourceByDestAddrAndPort(t *testing.T) { +func TestFindActiveFlows(t *testing.T) { db, mock := NewTestDB() defer db.Close() - addr, port := net.ParseIP("192.0.10.1"), 0 - pgid, pname := 3008, "nginx" + aaddrs := []net.IP{net.ParseIP("192.168.2.1"), net.ParseIP("192.168.2.2")} + + columns := sqlmock.NewRows([]string{ + "aipv4", + "apname", + "pport", + "apgid", + "pipv4", + "ppname", + "ppgid", + "connections", + "updated", + }) + + // flow1 + aipv4, apname, apgid := "192.168.2.1", "unicorn", 4123 + pipv4, ppname, ppgid, pport := "192.168.3.1", "mysqld", 10021, 3306 connections := 10 + columns.AddRow(aipv4, apname, pport, apgid, pipv4, ppname, ppgid, connections, time.Now()) - columns := sqlmock.NewRows([]string{"connections", "updated", "source_ipv4", "source_port", "source_pgid", "source_pname"}) - mock.ExpectQuery("SELECT (.+) FROM flows").WithArgs(addr.String(), port).WillReturnRows( - columns.AddRow(connections, time.Now(), addr.String(), port, pgid, pname), - ) + // flow2 + aipv4, apname, apgid = "192.168.2.1", "unicorn", 4123 + pipv4, ppname, ppgid, pport = "192.168.4.1", "memcached", 21199, 11211 + connections = 20 + columns.AddRow(aipv4, apname, pport, apgid, pipv4, ppname, ppgid, connections, time.Now()) - addrports, err := db.FindSourceByDestAddrAndPort(addr, port) + mock.ExpectQuery("SELECT (.+) FROM flows").WithArgs( + pq.Array([]string{"192.168.2.1", "192.168.2.2"}), + ).WillReturnRows(columns) + + flows, err := db.FindActiveFlows(aaddrs) if err != nil { t.Fatalf("%+v", err) } - if len(addrports) != 1 { - t.Errorf("addrports should be 1, but %v", len(addrports)) + if len(flows) != 1 { + t.Errorf("flows should be 2, but %v", len(flows)) } - want := []*AddrPort{ - { - IPAddr: addr, - Port: port, - Pgid: pgid, - Pname: pname, - Connections: connections, + want := Flows{ + "192.168.2.1-unicorn": []*Flow{ + { + ActiveNode: &Node{ + IPAddr: net.ParseIP("192.168.2.1"), + Port: 0, + Pgid: 4123, + Pname: "unicorn", + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP("192.168.3.1"), + Port: 3306, + Pgid: 10021, + Pname: "mysqld", + }, + Connections: 10, + }, + { + ActiveNode: &Node{ + IPAddr: net.ParseIP("192.168.2.1"), + Port: 0, + Pgid: 4123, + Pname: "unicorn", + }, + PassiveNode: &Node{ + IPAddr: net.ParseIP("192.168.4.1"), + Port: 11211, + Pgid: 21199, + Pname: "memcached", + }, + Connections: 20, + }, }, } - if diff := cmp.Diff(want, addrports); diff != "" { - t.Errorf("FindSourceByDestAddrAndPort() mismatch (-want +got):\n%s", diff) + if diff := cmp.Diff(want, flows); diff != "" { + t.Errorf("FindDestNodes() mismatch (-want +got):\n%s", diff) } if err := mock.ExpectationsWereMet(); err != nil { diff --git a/statik/genstatik/statik.go b/statik/genstatik/statik.go index f27cbafa..4f67be1c 100644 --- a/statik/genstatik/statik.go +++ b/statik/genstatik/statik.go @@ -8,6 +8,6 @@ import ( ) func init() { - data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00 \x00CREDITSUT\x05\x00\x01\x80Cm8\xec}\xddr#\xb9\x95\xe6=\x9e\xe2\xac\"6,MdQ\xd5e{\xec\xee\x9eu\x0cKdUq-\x91Z\x92j\xb9\xc2\xe1\x98\x003A\x12\xa3d\"\x1bHJE_\xf9Af\x1e`_c\x1f\xc5O\xb2q\x0e\x80\xfc!S\"%\xa2\xdd]\x0e\xf1\xa2[\x123\xf1sp\xcew~\x00|\xf5Q\xc1i\xb1\x14`\n\x9e%\\'\x90\xca\x99\xe6zs\xc6\x96E\x91\x9b\xef\xce\xcf\x17*\xe5\xd9\xa2\xa3\xf4\xe2\x9c\xbd9\xf2\xc3.T\xbe\xd1r\xb1,\xe04>\x83wo\xdf~\x0b\xd3\xa5\x80\x8f\n\xba\xebb\xa9\xb4\xe9@7M\x81\x1e1\xa0\x85\x11\xfa^$\x1d\xc6\xc6\"\x91\xa6\xd0r\xb6.\xa4\xca\x80g \xac\x8d\x00\x99\x81Qk\x1d\x0b\xfa\xcbLf\\o`\xae\xf4\xcaD\xf0 \x8b%(M\xffW\xeb\x82\xadT\"\xe72\xe6\xd8@\x04\\\x0b\xc8\x85^\xc9\xa2\x10 \xe4Z\xdd\xcbD$P,y\x01(\x90\xb9JS\xf5 \xb3\x05\xc4*K$\xbed\xf0%\xb6\x12\xc5w\x8c\x01\xc0\xbf@sP\x06\xd4\xdc\x8f&V\x89\x80\xd5\xda\x14\xa0E\xc1eFM\xf2\x99\xba\xc7\xaf\x9c\x08X\xa6\n\x19\x8b\x08\x8a\xa54\x90JS`\x03\xf5\xde\xb2dk(\x894q\xca\xe5J\xe8N\xfb\x08dV\x17\x82\x1fA\xaeU\xb2\x8eE5\x08V\x0e\x02\x8e\x19\x04s\x13KT\xbc^\x89\xac\xe0~m\xce\x95\x06U,\x85\x86\x15/\x84\x96<5\x95\x88i]\x8a\xa5`\xf5\xa1\xbb\xf9\x0c\x85\xa4\xd7\xb0\xd5\x8c\xaf\x04\x0e\xe6\xa3R\x8bT\xc0 \x8b;\x90\xa9\xea;\x92\xb7,\x0c\x8bUf\xdbQ\xda\xc0\x8ao`&P9\x12(\x14\x88,Q\xda\x08\xd4\x83\\\xab\x95*\x04Xi\x14\x06\x12\xa1\xe5\xbdH`\xae\xd5\x8a\xd1\xfc\x8d\x9a\x17\x0f\xa8\x19Ng\xc0\xe4\"F\xa5\x81\\KT%\x8d\xea\x92Y\xc51\x86\xc6\xcd\xa6\x9f\x06\x13\x98\x8c>Lo\xbb\xe3>\x0c&p=\x1e\xfd0\xe8\xf5{\xf0\xfe3L?\xf5\xe1bt\xfdy<\xf8\xf8i\n\x9fF\x97\xbd\xfex\x02\xdda\x0f.F\xc3\xe9x\xf0\xfef:\x1aO\xd8Iw\x02\x83\xc9 }\xd1\x1d~\x86\xfe\x9f\xae\xc7\xfd\xc9\x04Fc\x18\\]_\x0e\xfa=\xb8\xed\x8e\xc7\xdd\xe1t\xd0\x9fD0\x18^\\\xde\xf4\x06\xc3\x8f\x11\xbc\xbf\x99\xc2p4e\x97\x83\xab\xc1\xb4\xdf\x83\xe9(\xa2Nw_\x83\xd1\x07\xb8\xea\x8f/>u\x87\xd3\xee\xfb\xc1\xe5`\xfa\x99\xfa\xfb0\x98\x0e\xb1\xaf\x0f\xa31\xeb\xc2uw<\x1d\\\xdc\\v\xc7p}3\xbe\x1eM\xfa\x80\xd3\xea\x0d&\x17\x97\xdd\xc1U\xbf\xd7\x81\xc1\x10\x86#\xe8\xff\xd0\x1fNa\xf2\xa9{y\xd9\x9c%\x1b\xdd\x0e\xfbc\x1cz}\x8a\xf0\xbe\x0f\x97\x83\xee\xfb\xcb>vD\x93\xec\x0d\xc6\xfd\x8b)\xce\xa6\xfa\xe9b\xd0\xeb\x0f\xa7\xdd\xcb\x88M\xae\xfb\x17\x83\xeee\x04\xfd?\xf5\xaf\xae/\xbb\xe3\xcf\x91ks\xd2\xff?7\xfd\xe1t\xd0\xbd\x84^\xf7\xaa\xfb\xb1?\x81\xd3=\x12\xb9\x1e\x8f.n\xc6\xfd+\x1c\xf2\xe8\x03Ln\xdeO\xa6\x83\xe9\xcd\xb4\x0f\x1fG\xa3\x1e\xc9y\xd2\x1f\xff0\xb8\xe8O\xbe\x87\xcb\xd1\x84\x84u3\xe9G\xac\xd7\x9dv\xa9\xe3\xeb\xf1\xe8\xc3`:\xf9\x1e\x7f~\x7f3\x19\x90\xcc\x06\xc3i\x7f<\xbe\xb9\x9e\x0eF\xc33\xf84\xba\xed\xff\xd0\x1f\xc3E\xf7f\xd2\xef\x91pGC\x9c*\x9b~\xea\x8f\xc6\x9f\xb1Q\x94\x01\xc9>\x82\xdbO\xfd\xe9\xa7\xfe\x18\xe5I\x92\xea\xa2\x08&\xd3\xf1\xe0bZ\x7fl4\x86\xe9h\xb1\xd5\xda-u\xca\xb5\x98\x0b\xadEb\xbf\x9d\x93\x88\xef\xb0\xfdz\x19\xdb\xd0ZV\xa5\x80\xd9\x9a|\xaf-\x05\xd8\x14\xbbt\xf6\xb5\xe2t\xb4S\xb2u\xdfF\xde\xa4\xe7r\xb1\xd6\xb5j\x85\x1b\xf1\x88\xf2\xf4\xdd\x11\xf3\xcc\xd5\x9c\xb50\xeb\x94t\x9f\xaa\xaf+\x11/y&cN\xca_h\x9e\x19|\x8c{\xad\xa1\xbf\xa4\xee\xd79p\xb0\"\xa1\xb6\xa2\xe6\xbc\xb0\x81\xad\xa9\xc5j\x95K\xb4\x14e\xcb\x07vj\x0b\x91 \xbd[u)q(V\xd9\xbd\x05^*R\xb8*\xb5H$\x87b\x93\x97S\xbdU\xfan\xc7\xc8\x1f\x94\xbe\xa3\x81\xda\xbd\xf8\xa5\xcc+\xf5\x96\x99\x1f\xbdUn++7\x95\x15O\x04\xf0{.S>K\xbd=\xd7\x10&BDD\x15\x8b\xb9\xd3\x17n\xed|+\xa2\xf2(U/f F\x14\x05:\x84\xc4WPp\x9c\xf8\xfe)\xcf@|\xe1\xab<\xa5@\xae\x0c\xdc\\\xe1\xbe\x9b\xe7\"K\xe4\x17\x98\x89T=\x9c\xb9\x99\xf7\x84\x96\xf7\xbc\x90\xf7\x02P\x08\xe6d{\xa5\xb1\xf5\xf6y\xbbIc3v\xde~\xbc3np\x9d22\xb0z\x81\xde\xa2\x0e\xf6C\x8b\x83z\xfe\xb0\x94\xf1\xd2\x1b\xb7Hd\xa14\x9a\xaf\x16\xf7\x92V\x0d\x954S\x853\x00\x10)\x9f)\xed\x7f\xab\xf6\x1d\xeaf\x82-\xa1S\x12Fd\x05\xc9\x9a\xc3\xc3R\xa5\xa4\xf0\xa0\xb4\\\xc8\x8c\xa7-\xcb\xbb\x0b\xa8\x848\xf3\x869G\xb0-2'1\xd4W\xb7R\xd4\xb6\x03|-V\\Z\xab\x139\xd7\xa4\x11(\x0b\x1a\xfdJh\x91n \x95\xd9\x1d k&3\xd2\x07\x8c\xf9\xcf\xfc\xfa\xca\xac\x10z\xcec\xc2\xf7\xc8\xbb\xb4R\x8a;\xc3A\x89\x085w\x0b|\xe1\x8f\x03H\x95\xb5.\xee\xb6\x8a\x97\x86\xe8{*%\xe6,\xc9\xfb\xbdr\x04\xd8Rc\x05HK\x13\x17)P3\xca\n\x83^Q\xfa\xd11G5\x9d/\x10\xb0U\xc6\xd3\x94@\xd7\xacgn\xfb\xaeP\xe0\xe3\x02R!\x1a\xb0\xad\xedf\xd5\xc0\x08\x85wN1\x1bS\x88\x95)1X\x1a\xb3\x16\x88\xfe1\xb94\xf7\xb5]i\xdac\xa5h\xa2\x0c\x81\xeaR\x8e<24\x16\xbc&^\x94U\"M\xbc6\xe4\x8e\xa9\xbb\x15!\x9f\x0b\xean \xbe\x9cK\x11_\xfc\xc4\x9bS\xf4J\x17\xab\xcc\xe42^\xab\xb5I7\xb0\xe2\xfa\x0eqLW\xa1\x0b6\x92\x08#\x17\x19!\xb7\xcchEH\x92\xad\xea\x86\xe0s2T\x05p\xa8\xdba\xe7d\xcb6\xb7\"\xdcr\xb6\xde\xba\x9e\x8eG\xea\x12\xb3u\xf8fw\xb0\xe4\x06fBd\xa0E,\x08\x8dg\x9bF'\xce\xc0\x8c\xf8q-\xb2\"\xc5\x0ec\xa5se]+\x06\x9e5\xd3\xea0\xf6\xae\x03\x1f1\xda\xc1\x0e\xab\x82\x86\x0fx`\xd2,\xf1\xb7\xe6\x0f\xde\x84\xea\xc8*x\xbc\x84\x9aP\x1a\xc5\x08r\xe0\x9f\xd5\x1a8F]\xb9(\xd6<%\x1d{P:M\x1e$\x86\x03\x99\xca\xde\xd0\"\x1byO\xbf\xbe\xf1{:ZmxZl\xde\xcc\xb5\x10\x11H\xad\xc5\xbd\x8a\x11\x8c\x9b\x9e\xd7\x9fu(T\xb5\x99\x1ea|\x96\xa3\xa6\xee\xc0\x96\xc3c\xdaY\x89\xd3\x0d\xaab\x9e\xf2MT\xfd%\x17\xda:\xc7\xad\x8d\x96f\x9d\x86FQ\xe2)\x85\xab;}\xb5\xb8^\x82\x8b\x0ec\xbf\xae-\xc75G\xe0\xfcz\xd7\xe2T|\x89E^\xa0\xe5\x98\xc2[\x99\xadd\xd9\x04\xe4\x0cr;\xc5\xdaZ\xad\xf8\x9d\x88`\xc9\xef\x05\x05_4\x14JN\xd5|\x8e\xb1\x97\xa2M\xad\xc8\xfdW\xaer\xa5\x0b\xbb\x0c\xa5i\xbb\x80\xd5Ej\x04\x1b4!\x9c\xb6]\x11\xdf\x1f\xcf\xf3\x946\x93\xb2tc\xc5\x8a@\xe4\x06E\xa7%\x8c{\xd6\xcfi\xb6\xb1-\xd4\xc5Y\xc2_&ba\x0c\xd7\x92\xccn\xaee\xb6\xf0I\x84\x90\xe4\xb0\xea\xb6|j\xce\x80\xa7*\x13\xce\x8d\xc5j5\x93Y\x19T\xd3;\xdb/\xd0<\xfc1\x0c\xd22\xda\xaf\xc3\xc0\xab9,\xd7\xfe\x03\xca\xde;\xa8\x0e\x0c\xe6\xb8\xd4\x8cr\x0fS\xc8\x02U\xb6\\\x82B.\xdc9\xc7\x05\xc7\xaf \xae\\*|Z9\x1a\x1b\xe0je\xcc\x1b\x92\x10\x8e>Vk\x8cl\xec\xef2\x03\x0e)\x7f0kY\xe0\x0cS\xb1\xb0\x10\xee\x8a\x8e\xb7.\xc8E\xbcj\x82\xdbSPE\x88n\x87l\\\n\xeb\x1a\xa9\x9d\x92\xdc\xf8\xd9x\xe9\xaf(n,\x96\xc2\x06IMu\xa3x\xc6\xa7z\xce\n|\x84_\xd9\x8f\xf3S>\xe4\xb1\xd8\x8e\xb6\x87kE:\xc1\xcb]\xc7\x84\x17\xa5\x86\x95\xe2\x94\x86r\xb1\xa4\xc3\xd8o:[\x87\x7f:\xd4\xe9\x8aoj\x07~\xb6 \xa5\xdc\xbem\x80\xcb\x13\x91\x17-\x00\xc6q\"\x91\xeb\xd5\xeey*\x8cR\x1a\xb9\xa8\xf5\xb5\x8f`\xd2v\xd9\xd8\xe9\xcfJ\x88\xc7\xcf[\xd9c\xc4\xa7\xfc\xcc\xcenm\nX\xe00qT6\xca\xd7\"\x96\xb9\x14\x08?\xf5\x10\xd4f`\xf8\xd9\x99\\\xb9c\xdfX\x9c\xef\xc9\xe5Qo\xb3Zo\xb6\xdeQ\x05\xb3\x98\xb4\xd0\xe6=\xd5B4\xea\x89V+\x99\xa12\xd8\x0c\xcd\xf8\x8e\x11\xa9Ju\xc5\x06\xed\xc1\x03w\x9a\n\x1b\xa9\xf5\x19\xd7\xfa\xb4g\xc6\"\x1f\xb9\xd62b\n\xcb\xb3\xcd\xce\x9c|\x97eW\xf5\xdd|W^\xb7\xce,r\x9a\x1b!\xb4%\x02\xc3\x99\xc8;{\xfc\xf0\xa22\"7\x1f\x7f\x8cjg$\x0dL\x84F(e\xe1\xcf7@\xc3J\x14E\x95\xb9\xd0\xf6D\x9c;O\xc1u\xe1\\\x0d\xb8\xe8y{r5)%g\x08<\xe5\"\xbb\xcc\n\x97\xf4d8\x9a\x0e.\xfa'P\x88/\x05I\x17\x8d\xc9\xb5NG\xa0]\x0fu\x9b\xa9\xd9s\x8b \xec\x88\x92V\xc7\xb7\xe3\xb3:\x0eZ\xf0\x842\xb8J\xadD\xab\x1c\x11^\xb8\xccD)l\x07Ld\xe6v\xfc4\xf2\xe8\x10A\xfa6\xda\xe5\xd9*H\xd2(^@*\xb8\xc1\xc4\xa5\xacK\xbb\xe7+\x03\xccS\xcc,\xbf\xf3\x03\xe4~t\x95p+\xa9T\xaac\x9e\xec\xfd\xfb:\x0e74\xa94\xd5f\xb9\x06\xe4\xbcB\x0cto\x8b\xcaa\xed6\xaet\xb4%V\xee#\xafZA\xc8E\xe4-\x92\x99\xd7\xad\x80\x1c\xfc\xbd\xd0vi\x8a\xa5\xd4\xc9\x1b\x9c\xdb\xa6\\\x89L\xe9\x15f\xa1n\x1b\xabC\x07\x17q\x81\x11\x89\xb6\xe4Z[Z\xf0\x9bn2+\xcb`<\xad\xe5\x85\x18>\xd4\x06\xe2\x8c\xc6n\xe7AQ+H\x97p\xcf\x93\x04\x7f\xd6\x98\\\xd4\xd5\xce7\xe1G\xec\xa4r\x88\xa2GV\xdcF&\x95\x8aP\xda\xc23\xecNd\xc9z\xe5c\xc7\x86fx\xa0\xb0 \x96_\xbc\x06:\x91D}\x1d\x80\xa7\xed\x86B\xe5\x1d\x98 \xeb\xaa\xf5\xba\xa1dV\x18\xad\x05\xfaV\x99T\x81<\xc5\x8eT\xa1\xb6>z\xabF\xe4\x05\x8f-\xb8\xb1\xd7GJ\xfb\xa8\x18:6\xe2\xcc\x96\xd0\x99\xd9\xe2W\xcbN\x08\xd4\xf7b]t\xb6;\x8e\xc8\x99\x84\xdb\x9c}$\xf4\xaf\x97\xb0J3\xa1\xc6\xb0_\xe6\xea]U\xd7;;0\x0dwYF\xbc\xb1Z\xd9H\x16\xf5\x85\x95\x05\x8d2-\xd8\x8a\xbf+\xf1\xff\x96\xd2\n\xbf\xc9K9`\x15\x90\x99\x0e\xdcd\xa90\x86\x96H|\xc9S\x19K\xcc)\xa9\xb9\xda6\x00\xa3\xfa\xc0f;\x9a\xab\xd5}jE\x9fG\x0b=\xcc\xc6\xd7\xd8\xd7v\xfd\xa3<\x0dVU`\x0fN\x7f\xfc\xae8\x0e\xb0\xa6\x18\xf6}\x1b?&~\xf3\x0c\x00\x86\xaa\xc07\xca\xad\x89\xc2\xef\x93c\xe2\x83\xc6\xb8\xa0\xfc =\x00\x0d\xca\xacs\xa1\x8dH\x84\xdd\xe2@-\xf7\x0b\xe0\xba\xb0\xde\xdf\xd6\x0c\x0bQ%\x1f\x0b-\xac^o\x9c\x01P\xd6#\xbe\x88\xd8\x034!g)\x04-\x16\\\xdb\xed\x92\xedX\xdft\x18\xfb\xd7\x0eL}t`\x10\xdaj1l\xa2\x08\xfd\n\x1b\xee\xd6\xf7\xf5\xed \x04;\\|\x1b\xbb\xa5KH\xb5X\xc3`\xba\xa5\xefe,\xc0\xfdjOp\xa3\x96V7\x96\xea\x0bF\x1aQ\xa5\x7fZ\xfc\xb8\x96nS\x04=\xafQ\x19\xf9^Z\xbd\xb5)\xd4\x8a\xeb\x8d\xbf\x18\x90\x08\x13k9s\xb2g\x04cr!w\x8b\x95\xdeR\xfc*9 o\x01\xf0\x0ec\xbf\xeb@\xaf:\x01\xaf\xe6p\xcb5\xcabS\xeax9\xc8\xd9\xc6&\x86\x94\xc8b&\xe3,\x9b\x16\x8c2\x85\xaaZ\x14U\xcb\xe3\xcc\xd9T\x83<\xc5Qb\xf6\xcd\xea\xa9_\xfdQY\x98\xe6:\x9e\x01\xdd\x92(\xcfM\xbc\xefN\x06\x13\x92\xe6\xd6!\xc5\x81=kP\xdb1n\x1cZt\xd7\xcd\xc4\x97\\\xe3\xdc\xec\x04$\x81DR+\x1bF-\xa7P#[O\xb6\xe2qG-\x9b0\xa9\xe60\x1dL/\xfb\x11\x0cG\xc37\xf53\x8a\xd1\xeeQG\xa5\x9bG\xda\xb1\x81\xdd\x03\x8f\xd63\xda\xfd\xaeT\xa4\x98\x0f\x99\\eFR\x91\x9d6\x1fl\xceUS\x0b\x9e\xe7Z\xe5ZbhL\x93\x9c\xc3\x9aj\x87\xa4d\x15j\xd6\xea\x87\xe0\x0e\xf8\xaeW\x94\x1e\x10\xdeJC\xb8\\\x1e\xfa%\xa3#Hv\xbb\x83T\x9a\xaco\x0f\xee&\x89\x1d\xc6~\xdf\x81\xcb\xea$\xaf\x9a\xc3\xa5\xe43\x99\xd2\xee\xee\x00\xbd$\x88{\xd4N\x1c\x81m S\x90R\xfd\xafX\n\xa57\xbeH\xe1wg\n\xa5\x8bz\xe2\x9d\x89E*\x17\"\x8b\xc5YT\xee\xc8F\x8d\xa2\xa6\xad\x96\xecU\xe7S\xeb\xce\x0d$\"\x953\n\xb2hX\x0b\xcc\xeam\x8d\xdewV\x00\x8f\x0bC\xdb\xb7\xed\xeaoA\xb0\x01\xfeJ\xc3\x8c\x16(\x95\xd4\xa5K\xadi\x15\xf9\x8a/\x9a\x85k|\xd5oUW\x9b\xd6t\xd3\xc3U\xa2d\x16\xcb\x04\x03L[9\xc7\xe8\xc2V7%O}\x8b\x1ee\xe3%G\xb1\x08\x0d\\\xdb}]\xf4\xb8\xd6\xaf\x9auZl'\x90$\xbeu\x89\x19k\xfb\x17\x99\xb9\xa5\xab\xc1#\xf3\xa9\xf7\xe9\x93\xfb\xb6~<8\xdbTY\xad\\(\x95<\xc8\xb4\xac\xab\xdd\x81)T\x9e\xf3\x05\x9d\xfcZ\xe5k\x1c\xef\x9c\xcbt\xad\xad\x17\xe1\xe9|\x9dU\xc1\x07y\xae\xed\xc3\x08\xb1Z\xadP=\xeb2\xb0]\ns\x16\x91\xb2a|\xbc]\xad\xc2\x06\xca\"2O\xee%m\xf0\xd9\xd9\xe7\xca\x18\xe9&\xee\xf7\xda]\xdb\x1d\xc6\xbe\xed@7FD\xc7\x99{\xf4\xc4>\xbb\x95S\xad\xe9\xfc\xed\x12#\xe7\xa6\x1d\xb2\xfa\x8e\xd7\x93\x9bG>&\x8c\x97J\xd9\xc2 \xd5\xff\xaa\xdd`*@\x02\xa7\xb3ns\xa5#\xe046\x9e\xc5\xc2\x8e=\xb7\x95A\x87c\x1bR.\xb1\xcada\x0d\xad\xdcpL\xfd\x90A\xcdRW\xb3\xa1\xb8\xe2\x1ca\xc4\x1e\xc6G\x95\x93\x86\x9c\x8bKf\xe8\xf2W\x15\xd6\x7fR\x0f\x98y\xd8\\\xad\x14\x12 \xb0\xd6j5-:K\x91\xa5\xbe\xe6_F\xbd\xae\xf8O\xe5L\xf7g\xc4\xc3\n\x0di\xa4\x14\x89T{\x05\x0e\x92\xab\xeaJm\xb9]i\x14\x13\x149\xb7\x18\x8bfl\xad\x98\xe41\xb7\xf2H\xc4\\d\x89}|\xa9\xd2\xa4\xa5j\xcc\xf5\x8a\x90\xc5G\xb8\xa5\xe4\x9c\x91\xae\xb5\xae\xf6~\\\xf5\x94\x1b#4\x9a\x86+*F\xbb\xe5\xd3\xd9\xc6\x85\x04n\x1e\x1b\x9cu%\xc42\x96~\xa8\xa9\\-\x8e+G\xd1a\xac?\xb4whZ\x0eT1\xd6\xbd\xbe\xee\x0f{\x83?}\x87\xabE\x99w\x9e\xa76=k\x1e\xfc\xc2\xefh\x10\x0fv\x8b\x04\x00\xa6\x07>\x1d\xb9-}hd\xe6\xd8\xc2L\xc9T\xe8\xf0\xdb\xf7\xd9\xbd\xef\xf3\xbbW\x8e\xa7\x17\x11P\xbcr<\xbdr<\xbdr<\xbdr<=\x97A\xe3\x97\xc8\xf1\x94\xca\xd9y\xfec\x9b\xf7q\xdf\xecs+\xfb>\xbbn\xe7\x1b\x8c\xbe\x7f\x1d\xc1\xaf\xf2\x1f\x7fU\xaf\xa4\x18v\xedc\xa9\xda;\x17\xf6\x1dx\x9f\xf2;\x01W\xf2\xafB\xf3l\x13<$\x87\x97\x85\xe4\x8f\x10i@\xc8p\xbc\xed\x8a\xed\xcb\xc3\xf1\xed8\xf5\xc8p\x1c~\xaep\x1c\xc2\x85\xe3\xcf&\xd2\x80P\xa1\xf8\x01lI\x07\x87\xe2\x10&\x14\x7f\x04$_\x18\x8aC\xd0P\xfc'\xbb\xcb\x9b\xdf-\xce\x85\xd6\x88A-HX\xfbv\x1f\xda\xed\xfb\xec\xa2\xe1o#w\xe1~)2\xb1q\xf7\xedc\xfa\xa5\x93\x89\xe2\x0f\xaf\xc4t\x87D\xc3\xff\x94\xc4t\x01\x82\xdb\xaf\x9d\n\xaem\x96\x8fG\xb7\xec\xa0\xe8\xf6 ~8\xf6Dt\xfbL~8\xd6\x1e\xdd\xc2\x0b\xa2[\xf6\x18?\xdc\x8b\xa2[\xb6\xcb\x0f\xf7O\x16\xdd\xe6+\xf1W\xae\x93\xf3\x85z\x93\xc8\xf9<\x95\xb3V|\xdf}j\x1f\x8e\xef\xfb\xb4P\xc1Ep\xcd1\xfc\xbb\x83+\xea\xee\x97\x0e\xecU\xb1\xe5Hh?\xbe\xd6r<\xb2\x1f5\x06\x87\xeb\xece\xa5\x16\xd8)\xb5\x94|\xa3\xbe\x8a\x02;U\x94\xbd\xcc\xa3\xac\xb5\x92\x02\xcf\xa9\xa4\xb0\xd0\x95\x14t6\xec\xa8J\x8aGVvT%\x05\xba,@%e\x9f\xb3\xf9\x07\x95R\x1a\"\xd9\xefl\x1e)\xa5\x94\xce\x86\x1d\xeel\x1e%#\x85\xd1\x87G\n\xf6\x07\x94R\xc2\x92\x91\xb2_\x90\xb3\xd1\xfcn\x93\xa6\xe7t\x03\xa7\x95(\xbb\xf9\xc0>\x17\xb2\xefc\xa1\xf9\xc9\xcf\x81\x84@\xcf\xe7\x04\xda\xbf\x0do\x8f\x9d\x1c\xc5\x0c\x04\x00m\xe4@\x01\xf9\x81\x82R\x04\x85b z1QP \xae\xa0ptAA\x18\x83\xc2\x90\x06\x05\xe1\x0d\nF\x1d\x14\x8c=\xe8h\x02\xa1\x17r\x08\x85\xa4\x11\n\xc4$t(\x99\xd0\xf1|B!(\x85B\xb0\n=\x8bX(\x08\xb7P z\xa1\x00\x0cC/$\x19\n\xc73\x14\x8ej((\xdbPX\xc2\xa1\x90\x9cCAi\x87\x9e\xc7Q\xc0\xf4\x0f$~2K\xa9\xd5\xfa|\xa1r\xb3.d\xdav\x1az\xfb\x91}\xe7\x9d\xf7}\x98oi{\x8d\xecd\xdfOzeZ]n\xe0$\xf6tX\xa7\xe5\x1fC\xfeM\x04\xb7\xdd?v?w\xaf\xba0\xa1\xa1\xfed\x17v\x1a\xf5\xa3\x88\xbd\xf4\xc2\x8e\xbb\x89y47\xca\xf6U\xcc\xe7^\x97\xe9\xb4\x0d\xe1\xd97vjw1\x8f\xb9\xb4\xb3{P\xf4\xa5\xf7v\xda R\xf0\xe7R\xf1\xdc\xf9\xb1V\xa6\x94\xc6\x1d\x1f\xe6J\x95/ Ki\xbf\xe2\x83\x0d\xfe\x83\xf8R\xea\xff&6;\xea\x96\xcf6_\n{\xe6-\x9f\x10WJ\x0f\xe0Ka{/\xf9\x1ct\xa3\xb4\xfc7\xb5\x8f\xbfQZ]\xf2a\xc7\xde(m^\xf2aG\xde(\x0d\xcb\x97\x12\xe8\x92\x8f\xf7,\x8c\xce\x91f<=\xb7W\x14\xce- u\x16\xcacE\xdd\x83\xd0^~B\x10c\xe1\xd9\x99\xdfB\xa1\xbb=\x17Y\xac0;\xaf\x1a\xc1\x9ev\xdc\xc8\xdbo_9\xb6^\x04\xdf\xaf\x1c[\xaf\x1c[\xaf\x1c[\xaf\x1c[\xcf\xf5\x19aX\x08\xf6\xe5:\xfb>\xcd\\\xa8\xd0\xa2\x88\x97\xfa\xbc\x10\xa6\x90\xf3Mk2\xb4\xfd\xcc\x9edg\xef\x87\xd5hp[\xb2\x9bwo\xde\xbd\xfd\xe6\xf7p\xc5\x0b\x18o\x84=:=\xdd\xa4\x98'\xad\xb3L\xa4iX\x82-\x16\x94`\x8b\x85$\xd8b\xc1\x08\xb6X\x10\x82-\xf6K!\xd8\n\xc8w\xfbl\x82\xadW\xae\xdbC \xb6\xbe\x12\xae\xdb\xcdz}'\xcfSS\xcc\xdb\xd0\xaf\xf6\xed>\\\xdb\xf7\xd9\x85\xba\xdf\xc3\xe6?\xb0}\xd6\x84\xc4 \xf0\xc6\x8e\xe4\x0fd\x01\xf8\x03\xd9\x93\xf0\x06\x07\xc1\x1b;\x00\xde\xf6\xf0\x07\xb2\xc3\xe0m\x0f\x7f \xfb\xc9\xe0\x8d\xfd\xdc\xfc\x81\xecx\xfe@\xf6\"\xfe@v\x18\xbc\xed\xe3\x0fd\x87\xc1\xdb>\xfe@\xf6,x{\x8c?\x90\xbd\x08\xde\x02\xf3\x07R%\x80\xf6$\xbe\x9c\x9bM\x8d:p\xfb\x8b}\xa0\xb5\xef\xf3ZVx-+\xbc\x96\x15^\xcb\n\xafe\x85\xaf\xbb\xac\xf0\xeat^\x9d\xce\xab\xd3yu:\xafN\xe7\xd5\xe9|\xb5N\xe7\xcb6Qz\xdb\x97\xfb\x9c\xcb\xbe\xcfn\x19\xe7\xd5\xf9\xbc\x0c\xf7_\x9d\xcf\xab\xf3yu>\xaf\xce\xe7\xabu>\xff?\x00\x00\xff\xffPK\x07\x08\xbad\xea\xfc{\x1c\x00\x00\n\xb9\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00 \x00schema/flows.sqlUT\x05\x00\x01\x80Cm8\xbcTQo\x9b0\x10~\xe7W\xdc[\x83F\xa4!\x17.\x995\xb0\x91\xedd\xda\xbf\x9f0\xa1\xc4YF\xbaU\x9a_0\xba\xfb\xee\xfc}\xf7\xd9QJBJ\x80\x86\x9f\x16\x04\xe2;HV\x14\xc8c\xbc\xa6kh\x94,Pk\xd40\xf1\x00\xa0\xff\xcfy \xcf|\xabQqV\xd9\xfc$[,\xe0!\x8d\x97a\xfa\x04\xf7\xe4)\xb0\xe9\xbc\xd9\xbf\xb7_\x81\xe6%\xad\x0b5[^v!\x83[TC\x91\xe8\x0b\x89\xeeab\xe3\xb770\xf3aN\xee\xc2lAa\x16\xc0tj\x8173\xa8\x91 \x0d\x1b\xc6\xab\x9dB0\x12\n\xd6\x98v{8\"p\xb1\x91\xaaf\x86K\xd15\x14\xacF\x00\xd83U|cj\xf2a\xe6\x0fM\xfb\x16WW\xb6\x07]\xcdW\x1f\xe1]Q\x97\x15\x17h\xe1\x85Bf\xb0\x04\xc3k\xd4\x86\xd5\xcd\xef\xe0(KS\x92\xd0\x9c\xc6K\xb2\xa6\xe1\xf2\xa1c\xbak\xca\x7f@Zh\x96\xc4_3\x02\x93V\xc7\xc02\x0f:\x1e\xbe\xe7_{\xdet\n\x85\x14\x02\x0b\x03\x9a\x97\xe8\x8d\x0c\x92\x15\x86\xef1\x17\xb2|\x99e\xbb\x7f\xed \xdd\xb9s1L\x13RrGR\x92D\xc4q\xcb\x00\xf0a\x95\xc0\x9c,\x08%\x10\x85\xeb(\x9c\x93\x13vG\xb9=\xad\x8ak\x83\xe2\"\xab\x86i\xfd&ZR\x99Q\x13\xb6\xf1[\x98\xf9\xffU\x85\xc0\x9e\xcbjq\xe0\x1e's\xf28\xc6=o\x11\xf9w\xfc\xd9\xb6qU\xc9\xd6q\xf2\x19\x9e\x8dB\xec\x08\xb5\x12\x8fh\xba\xa9\xe4\x8f^\xcbv\x9fw\xf7\xd4Y\xaf\xd1V\xcb\x9d*\xbaC8%F\x94sMz@\x9eU\xae-T\xa26\\\xd8\x0b\xeet\x19\x1b\x8d\xeb\x97K\x1d\x0e\x97\x8bK\xa1\x1d\xfa\x7f\xb2\xcbq\xfe\xe0\x9a\xfe\xe58]\x7f\xf7\x1e\xc0\xd1K\xf2\xb6J\x8e\xeb\xdc)\x05\xe7D\xbddDk\x98\xfc\x0c0w\x8b\xf7\xf6\xec\x0c\xe6\xd8\xf2\x0c881\x90\x7f\xed\xfd\n\x00\x00\xff\xffPK\x07\x08\xa2#+\xbd\xf8\x01\x00\x00\xa8\x06\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xbad\xea\xfc{\x1c\x00\x00\n\xb9\x00\x00\x07\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00CREDITSUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xa2#+\xbd\xf8\x01\x00\x00\xa8\x06\x00\x00\x10\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\xb9\x1c\x00\x00schema/flows.sqlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\x85\x00\x00\x00\xf8\x1e\x00\x00\x00\x00" + data := "PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x07\x00 \x00CREDITSUT\x05\x00\x01\x80Cm8\xec}\xddr#\xb9\x95\xe6=\x9e\xe2\xac\"6,MdQ\xd5e{\xec\xee\x9eu\x0cKdUq-\x91Z\x92j\xb9\xc2\xe1\x98\x003A\x12\xa3d\"\x1bHJE_\xf5\x83\xcc<\xc0\xbe\xc6>J?\xc9\xc69\x00\xf2\x87L\x89\x94\x88vw;\xc4\x8bnI\xcc\xc4\xcf\xc19\xdf\xf9\x01\xf0\xd5G\x05\xa7\xc5R\x80)x\x96p\x9d@*g\x9a\xeb\xcd\x19[\x16En\xbe9?_\xa8\x94g\x8b\x8e\xd2\x8bs\xf6\xe6\xc8\x0f\xbbP\xf9F\xcb\xc5\xb2\x80\xd3\xf8\x0c\xde\xbd}\xfb5L\x97\x02>*\xe8\xae\x8b\xa5\xd2\xa6\x03\xdd4\x05z\xc4\x80\x16F\xe8{\x91t\x18\x1b\x8bD\x9aB\xcb\xd9\xba\x90*\x03\x9e%\xb06\x02d\x06F\xadu,\xe8/3\x99q\xbd\x81\xb9\xd2+\x13\xc1\x83,\x96\xa04\xfd_\xad\x0b\xb6R\x89\x9c\xcb\x98c\x03\x11p- \x17z%\x8bB$\x90ku/\x13\x91@\xb1\xe4\x05\xa0@\xe6*M\xd5\x83\xcc\x16\x10\xab,\x91\xf8\x92\xc1\x97\xd8J\x14\xdf0\x06\x00\xff\x02\xcdA\x19Ps?\x9aX%\x02VkS\x80\x16\x05\x97\x195\xc9g\xea\x1e\xbfr\"`\x99*d,\"(\x96\xd2@*M\x81\x0d\xd4{\xcb\x92\xad\xa1$\xd2\xc4)\x97+\xa1;\xed#\x90Y]\x08~\x04\xb9V\xc9:\x16\xd5 X9\x088f\x10\xccM,Q\xf1z%\xb2\x82\xfb\xb59W\x1aT\xb1\x14\x1aV\xbc\x10Z\xf2\xd4T\"\xa6u)\x96\x82\xd5\x87\xee\xe63\x14\x92^\xc3V3\xbe\x128\x98\x8fJ-R\x01\x83,\xee@\xa6\xaa\xefH\xde\xb20,V\x99mGi\x03+\xbe\x81\x99@\xe5H\xa0P \xb2Di#P\x0fr\xadV\xaa\x10`\xa5Q\x18H\x84\x96\xf7\"\x81\xb9V+F\xf37j^<\xa0f8\x9d\x01\x93\x8b\x18\x95\x06r-Q\x954\xaaKf\x15\xc7\x18\x1a7\x9b~\x1aL`2\xfa0\xbd\xed\x8e\xfb0\x98\xc0\xf5x\xf4\xdd\xa0\xd7\xef\xc1\xfb\xcf0\xfd\xd4\x87\x8b\xd1\xf5\xe7\xf1\xe0\xe3\xa7)|\x1a]\xf6\xfa\xe3 t\x87=\xb8\x18\x0d\xa7\xe3\xc1\xfb\x9b\xe9h\x8c\xc6\xac\x0b\xd7\xdd\xf1tpqs\xd9\x1d\xc3\xf5\xcd\xf8z4\xe9\x03N\xab7\x98\\\\v\x07W\xfd^\x07\x06C\x18\x8e\xa0\xff]\x7f8\x85\xc9\xa7\xee\xe5es\x96lt;\xec\x8fq\xe8\xf5)\xc2\xfb>\\\x0e\xba\xef/\xfb\xd8\x11M\xb27\x18\xf7/\xa68\x9b\xea\xa7\x8bA\xaf?\x9cv/#6\xb9\xee_\x0c\xba\x97\x11\xf4\xff\xd2\xbf\xba\xbe\xec\x8e?G\xae\xcdI\xff\xff\xdc\xf4\x87\xd3A\xf7\x12z\xdd\xab\xee\xc7\xfe\x04N\xf7H\xe4z<\xba\xb8\x19\xf7\xafp\xc8\xa3\x0f0\xb9y?\x99\x0e\xa67\xd3>|\x1c\x8dz$\xe7I\x7f\xfc\xdd\xe0\xa2?\xf9\x16.G\x13\x12\xd6\xcd\xa4\x1f\xb1^w\xda\xa5\x8e\xaf\xc7\xa3\x0f\x83\xe9\xe4[\xfc\xf9\xfd\xcdd@2\x1b\x0c\xa7\xfd\xf1\xf8\xe6z:\x18\x0d\xcf\xe0\xd3\xe8\xb6\xff]\x7f\x0c\x17\xdd\x9bI\xbfG\xc2\x1d\x0dq\xaal\xfa\xa9?\x1a\x7f\xc6FQ\x06$\xfb\x08n?\xf5\xa7\x9f\xfac\x94'I\xaa\x8b\"\x98L\xc7\x83\x8bi\xfd\xb1\xd1\x18\xa6\xa3\xf1\x94Us\x84a\xff\xe3\xe5\xe0c\x7fx\xd1\xc7oG\xd8\xca\xed`\xd2?\x83\xeex0\xc1\x07\x06\xd4-\xdcv?\xc3\xe8\x86\xa6\x8cKt3\xe93\xfa\xb1\xa6\xb0\x11-$\x0c>@\xb7\xf7\xdd\x00\x87\xed\x1e\xbe\x1eM&\x03\xa7&$\xb2\x8bON\xdc\x1d\xc6\xfe\xd7\x91\x1f\xc6\x16\xb2X\xaeg\x9dX\xad\xceQ\xc4oz\xa3\x8f\xe7\x0b\xf5\xc6|\x9f\xaeT|Wy\x9f\xa7\x1f\xdb\xe7p\xf6}\x18z\x9fb\xa9\x85\x808\xe5\xe8Q\xdeOz\x90\xcaXdF\xc0)\x8e\xe2\x9b\xf3s\x91u\x1e\xe4\x9d\xccE\"99B\xfc\xed\xfc\xfd\xa4\xf7\x1f\xeeIs\xc6v\\\xdbW\xbf}\xf3\xee\xedW_G\xe0\xc7\x0d\x85\xe0+\xf6\x0bwo`\xdd\xdb\xb1\xbe\xad\xe1V\x18<\xd7\xb1t\xdaFp\xa0o\xdb\x1d\x04\x83\x17y7h\xf3n\x0c\x0e\xf6o\xd0\xf4o\xec_(\xd4!\xaf\xd6\xe3\x05\xef\xa9E'-\xc8_e\xaa8\xd0g1hx-\xf8Y\xbd\x168\xaf\xc5^\xec\xb5`\xcbk\xb1\x17y-x\xcck\xb1\xa7\xbd\xd6\xd5\xe0\xe2S\xb7\x7f \xefG\x93\xe9\xe8\xe2\xcf\x8f{(\xd6\xea\xa1\xe0\xa5\x1e\x8a\xb5\xcd\xfeg\xf6P`=\x14;\xc6C\xd5\xe6\xc8^\xee\xa1`\xc7C\xb1\x9f\xddCM\n\x1e\xdf\xf5\xbf\xc4K\x9e-\xc4\xf9\xc3J\xb6\xf9\xa7\xdd\x87\xf6y\x9f}\x1f\xf2NW\x83)\\z\x87t5\x98\xb6\xba\x1a\xa0\xce\xc1\xf7\xce\xd8ui\xeb \x0d,\x85\x16\xb3\x0d,4\xcf\n\x91D0G\x87\x87H\xb8\xe4z\x81(\xad\x80g\x1b\x04\x08\xa32P3\x84u\x04CN`\nj\xbe\x15\x1e#lrcT,9\xba\x97f\xfc?\x97\xa906\xab<\x99\xb87N\xce\xa8\x93D\xf0\x14d\xc6\xf0\xbb\xc96ji\x81p\x19[\xff%\xb38]'8\x06\xffu*W\xd2\xf5\x80\xaf;\x1fZ(\xb66\"\xa2qF@>\x10\xff/hZ\xf9z\x96J\xb3\x8c*$\x16\x11\x18\xfc#\x893\xf2PnD\x9ab\x0b\x92r\x8a\xc6\xe8\"\xeb\"\x94s\xa6ND\xd8/<, \x80k3\x91\x06\xe6k\x9dI\xb3\xb4@\x9e(0*bf=\xfbO\x11\x17\xf8\x97\xc7\\\xef7\x8c\xd6\xba\xdd\x819/%M\x0d\xc1\xfdWf\xc9\xd3\x14\x9d\x87\x15\x98H\xd0k\xf14e~:\x1a'\x8c\xd9}!y\n\xb9\xd2\xa5;\xaf\x0f\x9d\x1cB\xbf\xdd\x1f8\x94\x8f\xe0v0\xfd\x84\xb6\xea\xc0\x99\x8c\x0em\xf8\xcf\x83a/\xaa\x81\xbfG\xf1\x1a\xe2\xb7\x00>\x99\xf0\x938\x1fy\x90g\x8f\x83\xfc\xb0\x07\xc3\xd1p0\xfc0\x1e\x0c?\x12z>\x96\x9fto\xa6\x9f\xd0i\x8d\xc6l\xd7\xb5\xedB?\xf9\x8d\xa8\x84o\x0fb-\xe8\xc8\x08\xca\xa0{\x81\x10\x8b\xd3\xa8\xa0\x92P\xb1\x8e\x7fQ\x89\x7f\x1f\xc6\xa3\xab\xc8C\x1f:\xcc!\xbb\x18\x0d\x87}\xdb\n\x8a\x1a\x1a+\x82\x18\xeb\x01\xd2\x8f\xa5\xd7\xef^\x0e\x86\x1f\x11\xe4\x1b\x0f\x87\x86\xbf\x84\xdf\x8bx\xb1\xa4\xc0;\x17\x0fm\xe0\xb7\xfd\xc8>h\xdb\xf7a\x83\xc9\x85\x87\xbd\x16\xc0{\x87\xb1\xf5\xbfB\x8f\xdf\x0b\xb8Pi*3\x03\xff\x86c\xf8w\x1aH\x07\xa3\xac?5P\xb0P\xd0\x02\x14\x0e\x00*|\xd8\x8a\xa8\xe6J#2\xb2|\xadse\xc4v\xd0\x0ds!\xda\xf0u7\xden/\xbb\xee\xdb\xc8\x9b\xf4\\.\xd6\xba\x96\xf0\xb8\x11\x8f(\xd4\xdf\x1d1\xa6W\xf47-\xcc:%\xdd\xa7\x02\xceJ`\xc6&cN\xca_h\x9e\x19|\x8c{\xad\xa1\xbf\xa4\xee\xd79p\xb0\"\xa1\xb6\xa2\xe6\xbc\xb0\x81\xad\xa9\xc5j\x95K\xb4\x14e3\x10;\xb5\x85\xc8\x84\xdeM\xdcJ\x1c\x8aUvo\x81\x97\xf2\x1cW\xe8\x12\x89\xe4Pl\xf2r\xaa\xb7J\xdf\xed\x18\xf9\x83\xd2w4P\xbb\x9d\xb7\x94y\xa5\xde2\xf3\xa3\xb7\xcame\xe5\xa6\xb2\xe2\x89\x00~\xcfe\xcag\xa9\xb7\xe7\x1a\xc2D\x88\x88\xa8b1w\xfa\xc2\xad\x9doET\x1e\xa5\xea\xf9\x10bDQ\xa0CH|\x12\x86\xe3\xc4\xf7Oy\x06\xe2\x0b_\xe5)\x05re\xe0\xe6j\x7f\xdd<\x17Y\"\xbf\xc0L\xa4\xea\xe1\xcc\xcd\xbc'\xb4\xbc\xe7\x85\xbc\x17\x80B0'\xdb+\x8d\xad\xb7\xcf\xdbM\x1a\x9b\xb1\xf3\xf6\xe3\x9dq\x83\xeb\x94\x91\x81\xd5k|\x16u\xb0\x1fZ\x1c\xd4\xf3\x87\xa5\x8c\x97\xde\xb8E\"\x0b\xa5\xd1|\xb5\xb8\x97\xb4j\xa8\xa4\x99*\x9c\x01\x80H\xf9Li\xff[U\xba\xac\x9b \xb6\x84NI\x18\x91\x15$k\x8e nJ\n\x0fJ\xcb\x85\xccx\xda\xb2\xbc\xbb\x80J\x883o\x98s\x04\xdb\"s\x12C}u+Em;\xc0\xd7b\xc5\xa5\xb5:\x91sM\x1a\x81\xb2\xa0\xd1\xaf\x84\x16\xe9\x06R\x99\xdd\x91\xb0f2#}\xc0\x98\xff\xcc\xaf\xaf\xcc\n\xa1\xe7<&|\x8f\xbcK+\xa5\xb83\x1c\x94\x88Ps\xb7\xc0\x17~GQ\xaa\xacuq\xb7U\xbc4D\xdfS)1gI\xde\xef\x95#\xc0\x96\x1a+@Z\x9a\xb8H\x81\x9aQV\x18\xf4\x8a\xd2\x8f\x8e9\xaa\xe9|\x81\x80\xad2\x9e\xa6\x04\xbaf=s;\x00\x85\x02\x1f\x17\x90\n\xd1\x80my(\xab\x06F(\xbc\xe3\xf9iA\xc9;=\x89\xf2\xf5(\x02a\x95\xfaF\x8d\x9e\x89%O\xe7\xa0\xe6\xac=\xb28\xcc'\xc3I9\x9b\x13l\xc8z\xe5\x12W\xd5\x1cD*\xe2B\xabL\xc6\x11\x8a}\xc6S\xd2\x17_\xfe\xc6\xe0`\x9d9q\x03\xeay)eQ \x07eC{3\xce\x16H\xe0&z\xd2\x85X \xaa\xb7\xae\xb2\xdah`\xc5e\x8ao\xa6\xd2\x14&j\xec\xa3\xf88\xc5lL!V\xa6\xc4`i\xccZ \xfa\xc7\xe4\xd2\xdc\xd7v\xa5i\x9b\x86\xa2\x892\x04\xaaK9\xf2\xc8\xd0X\xf0\x9axQV\x894\xf1\xda\x90;\xa6\xeeV\x84|.\xa8\xbb%\xf8r.E|\xf1\x13oN\xd1+]\xac2\x93\xcbx\xad\xd6&\xdd\xc0\x8a\xeb;\xc41]\x85.\xd8H\"\x8c\\d\x84\xdc2\xa3\x15!I\xb6\xaa\x1b\x82\xcf\xc9P\x15\xc0\xa1n\x87\x9d\x93-\xdb\xdc\x8ap\xcb\xd9z\xebz:\x1e\xa9K\xcc\x96\xf2\x9a\xdd\xc1\x92\x1b\x98 \x91\x81\x16\xb1 4\x9em\x1a\x9d8\x033\xe2\xfb\xb5\xc8\x8a\x14;\x8c\x95\xce\x95u\xad\x18x\xd6L\xab\xc3\xd8\xbb\x0e|\xc4h\x07;\xac\n\x1a>\xe0\x81I\xb3J\xd8\x9a?x\x13\xaa#\xab\xe0\xf1\x12jBi\x14#\xc8\x81\x7fVk\xe0\x18u\xe5\xa2X\xf3\x94t\xecA\xe94y\x90\x18\x0ed*{C\x8bl\xe4=\xfd\xfa\xc6\x97\x85\xb5\xda\xf0\xb4\xd8\xbc\x99k!\"\x90Z\x8b{\x15#\x187=\xaf\xdf.-T\xb5\x1f\x17a|\x96\xa3\xa6\xee\xc0\x96\xc3c*\xce\xc6\xe9\x06U1O\xf9&\xaa\xfe\x92\x0bm\x9d\xe3V\xad\xb6Y\xa7\xa1Q\x94xJ\xe1\xeaN_-\xae\x97\xe0\xa2\xc3\xd8ok\xcbq\xcd\x118\x7f\xbdkq*\xbe\xc4\"/\xd0rL\xe1\xad\xccV\xb2l\x02r\x06\xb9\x9dbm\xadV\xfcND\xb0\xe4\xf7\x82\x82/\x1a\n%\xa7j>\xc7\xd8KQ]\x82I\xdbec\xa7?+!\x1e?\xb2aO\"\x9e\xf23;\xbb\xb5)`\x81\xc3\xc4Q\xd9(_\x8bX\xe6R \xfc\xd4CP\x9b\x81\xe1ggr\xe5\xa6_cq\xbe%\x97G\xbd\xcdj\xbd\xd9zG\x15\xccb\xd2B\xfb\x7fT\x0b\xd1\xa8'Z\xadd\x86\xca`34\xe3;F\xa4*\xd5\x15\x1b\xb4{\x97\xee@\x066R\xeb3\xae\xf5i\x8f\x9dD>r\xade\xc4\x14\x96g\x9b\x9d9\xf9.\xcb\xae\xea\x1b\x82\xae\xbcn\x9dY\xe447BhK\x04\x863\x91w\xf6\xf8\xe1EeDn>\xfe$\xc6\xceH\x1a\x98\x08\x8dP\xca\xc2\x9fo\x80\x86\x95(\x8a*s\xa1\xed\xa1\x1a\xb7%\xcbu\xe1\\\x0d\xb8\xe8y{r5)%g\x08<\xe5\"\xbb\xcc\n\x97\xf4d8\x9a\x0e.\xfa'P\x88/\x05I\x17\x8d\xc9\xb5N\xa7(]\x0fu\x9b\xa9\xd9s\x8b \xec\x88\x92V\xc7\xb7\xe3\xb3:\x0eZ\xf0\x842\xb8J\xadD\xab\x1c\x11^\xb8\xccD)l\x07Ld\xe6v\xfc4\xf2\xe8\x10A\xfa6\xda\xe5\xd9*H\xd2(^@*\xb8\xc1\xc4\xa5\xacK\xbb\xe7+\x03\xccS\xcc,\xbf\xf1\x03\xe4~t\x95p+\xa9T\xaac\x9e\xec\xfd\xdb:\x0e74\xa94\xd5f\xb9\x06\xe4\xbcB\x0cto\x8b\xcaa\xed6\xaet\xb4%V\xee#\xafZA\xc8E\xe4-\x92\x99\xd7\xad\x80\x1c\xfc\xbd\xd0vi\x8a\xa5\xd4\xc9\x1b\x9c\xdb\xa6\\\x89L\xe9\x15f\xa1n\x1b\xabCg\x9fp\x81\x11\x89\xb6\xe4Z[Z\xf0\x9bn2+\xcb`<\xad\xe5\x85\x18>\xd4\x06\xe2\x8c\xc6n\xe7AQ+H\x97p\xcf\x93\x04\x7f\xd6\x98\\\xd4\xd5\xce7\xe1G\xec\xa4r\x88\xa2GV\xdcF&\x95\x8aP\xda\xc23\xecNd\xc9z\xe5c\xc7\x86fx\xa0\xb0 \x96_\xbc\x06:\x91D}\x1d\x80\xa7\xed\x86B\xe5\x1d\x98 \xeb\xaa\xf5\xba\xa1dV\x18\xad\x05\xfaV\x99T\x81<\xc5\x8eT\xa1\xb6>z\xabF\xe4\x05\x8f-\xb8\xb1\xd7GJ\xfb\xa8\x18:6\xe2\xcc\x96\xd0\x99\xd9\xe2W\xcbN\x08\xd4\xf7b]t\xb6;\x8e\xc8\x99\x84\xdb\x9c}$\xf4\xaf\x97\xb0J3\xa1\xc6\xb0_\xe6\xea]U\xd7;;0\x0dwYF\xbc\xb1Z\xd9H\x16\xf5\x85\x95\x05\x8d2-\xd8\x8a\xbf+\xf1\xff\x9e\xd2\n\xbf\xc9K9`\x15\x90\x99\x0e\xdcd\xa90\x86\x96H|\xc9S\x19K\xcc)\xa9\xb9\xda6\x00\xa3\xfa\xc0f;\x9a\xab\xd5}jE\x9fG\x0b=\xcc\xc6\xd7\xd8\xd7v\xfd\xa3\xbb\x95S\xad\xe9\xfc\xed\x12#\xe7\xa6\x1d\xb2\xfa\x8e\xd7\x93\x9bG>&\x8c\x97J\xd9\xc2 \xd5\xff\xaa\xdd`*@\x02\xa7\xb3ns\xa5#\xe046\x9e\xc5\xc2\x8e=\xb7\x95A\x87c\x1bR.\xb1\xcada\x0d\xad\xdcpL\xfd\x90A\xcdRW\xb3\xa1\xb8\xe2\x1ca\xc4\x9e\xe7E\x95\x93\x86\x9c\x8bKf\xe8\xfeH\x15\xd6\x7fR\x0f\x98y\xd8\\\xad\x14\x12 \xb0\xd6j5-:K\x91\xa5\xbe\xe6_F\xbd\xae\xf8O\xe5L\xf7g\xc4\xc3\n\x0di\xa4\x14\x89T{\x05\x0e\x92\xab\xeaJm\xb9]i\x14\x13\x149\xb7\x18\x8bfl\xad\x98\xe41\xb7\xf2H\xc4\\d\x89}|\xa9\xd2\xa4\xa5j\xcc\xf5\x8a\x90\xc5G\xb8\xa5\xe4\x9c\x91\xae\xb5\xae\xf6~\\\xf5\x94\x1b#4\x9a\x86+*F\xbb\xe5\xd3\xd9\xc6\x85\x04n\x1e\x1b\x9cu%\xc42\x96~\xa8\xa9\\-\x8e+G\xd1a\xac?\xb4\xc7\xf0[\x0eT1\xd6\xbd\xbe\xee\x0f{\x83\xbf|\x83\xabE\x99w\x9e\xa76=k\x1e\xfc\xc2\xefh\x10\x0fv\x8b\x04\x00\xa6\x07>\x1d\xb9-}hd\xe6\xd8\xc2L\xc9T\xe8\xb7\xb2\xef\xb3\xebv\xbe\xc2\xe8\xfb\xb7\x11\xfc&\xff\xfe7\xf5J\x8aa\xd7>\x96\xaa\xbdsa\xdf\x81\xf7)\xbf\x13p%\xff.4\xcf6\xc1CrxYH\xfe\xc8]|\x08\x19\x8e\xb7]\xb1}y8\xbe\x1d\xa7\x1e\x19\x8e\xc3\xcf\x15\x8eC\xb8p\xfc\xd9w\xf1!T(~\x00\xe1\xca\xc1\xa18\x84 \xc5\x1f\x01\xc9\x17\x86\xe2\x104\x14\xff\xc9\xee\xf2\xe6w\x8bs\xa15bP\x0b\x12\xd6\xbe\xdd\x87v\xfb>\xbbh\xf8\xfb\xc8]\xb8_\x8aLl\xdc}\xfb\x98~\xe9d\xa2\xf8\xd3+\xb7\xd5!\xd1\xf0?%\xb7U\x80\xe0\xf6\xd7\xce&\xd56\xcb\xc7\xa3[vPt{\x10\xc5\x14{\"\xba}&\xc5\x14k\x8fn\xe1\x05\xd1-{\x8cb\xeaE\xd1-\xdb\xa5\x98\xfa'\x8bn\xf3\x95\xf8;\xd7\xc9\xf9B\xbdI\xe4|\x9e\xcaY+\xbe\xef>\xb5\x0f\xc7\xf7}Z\xd8\xa4\"\xb8\xe6\x18\xfe\xdd\xc1\x15u\xf7K\x07\xf6\xaa\xd8r$\xb4\x1f_k9\x1e\xd9\x8f\x1a\x83\xc3u\xf6\xb2R\x0b\xec\x94ZJ\xcaB_E\x81\x9d*\xca^\xf2B\xd6ZIy\x16u!\x0b]IAg\xc3\x8e\xaa\xa4xdeGUR\xa0\xcb\x02TR\xf69\x9b\x7fP)\xa5!\x92\xfd\xce\xe6\x91RJ\xe9l\xd8\xe1\xce\xe6Q>C\x18}x\xa4`\x7f@)%,\x9f!\xfb\x059\x1b\xcd\xef6izN7pZ\xb9v\x9b\x0f\xecs!\xfb>\x16\x9a\x9f\xfc\x1cH\x08\xf4|N\xa0\xfd\xdb\xf0\xf6\xd8\xc9Q\xcc@\x00\xd0F\x0e\x14\x90\x1f((EP(\x96\xa0\x17\x13\x05\x05\xe2\n\nG\x17\x14\x841(\x0ciP\x10\xde\xa0`\xd4A\xc1\xd8\x83\x8e&\x10z!\x87PH\x1a\xa1@LB\x87\x92 \x1d\xcf'\x14\x82R(\x04\xab\xd0\xb3\x88\x85\x82p\x0b\x05\xa2\x17\n\xc00\xf4B\x92\xa1p\xdc\xae(\x9f\x00 \x04\xeb\x13\x05L\xff@\xe2'\xb3\x94Z\xad\xcf\x17*7\xebB\xa6m\xa7\xa1\xb7\x1f\xd9w\xdey\xdf\x87\xf9\x96\xb6\xd7\xc8N\xf6\xfd\xa4W\xa6\xd5\xe5\x06NbO\x87uZ\xfe1\xe4\xdfEp\xdb\xfds\xf7s\xf7\xaa\x0b\x13\x1a\xeaOva\xa7Q?\x8a\xd8K/\xec\xb8\x9b\x98Gs\xa3l_\xc5|\xeeu\x99N\xdb\x10\x9e}c\xa7v\x17\xf3\x98K;\xbb\x07E_zo\xa7\x9d \x05\x7f.\x15\xcf\x9d\x1fkeJi\xdc\xf1a\xaeT\xf9\x02\xb2\x94\xf6+>\xd8\xe0?\x88/\xa5\xfeob\xb3\xa3n\xf9l\xf3\xa5\xb0g\xde\xf2 q\xa5\xf4\x00\xbe\x14\xb6\xf7\x92\xcfA7J\xcb\x7fS\xfb\xf8\x1b\xa5\xd5%\x1fv\xec\x8d\xd2\xe6%\x1fv\xe4\x8d\xd2\xb0|)\x81.\xf9x\xcf\xc2\xe8\x1ci\xc6\xd3s{E\xe1\xdc\x02Rg\xa1\xbbP\xf7G\xd8\xfc\x07\xb6\xcf\x9a\x90\x18\x04\xde\xd8\x91\xfc\x81,\x00\x7f {\x12\xde\xe0 xc\x07\xc0\xdb\x1e\xfe@v\x18\xbc\xed\xe1\x0fd?\x19\xbc\xb1\x9f\x9b?\x90\x1d\xcf\x1f\xc8^\xc4\x1f\xc8\x0e\x83\xb7}\xfc\x81\xec0x\xdb\xc7\x1f\xc8\x9e\x05o\x8f\xf1\x07\xb2\x17\xc1[`\xfe@\xaa\x04\xd0\x9e\xc4\x97s\xb3\xa9Q\x07n\x7f\xb1\x0f\xb4\xf6}^\xcb\n\xafe\x85\xd7\xb2\xc2kY\xe1\xb5\xac\xf0\xeb.+\x84v:_\xb69k\xdb\xbe\xdc\xe7\\\xf6}v#\xeaW\xe7\xf32\xdc\x7fu>\xaf\xce\xe7\xd5\xf9\xbc:\x9f_\xad\xf3\xf9\xff\x01\x00\x00\xff\xffPK\x07\x08\xcb\x92\xa2?W\x1c\x00\x00\xd8\xae\x00\x00PK\x03\x04\x14\x00\x08\x00\x08\x00\x00\x00!(\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00 \x00schema/flows.sqlUT\x05\x00\x01\x80Cm8\xbcTQo\x9b0\x10~\xe7W\xdc[\x83F\xa4!\x17.\x995\xb0\x91\xedd\xda\xbf\x9f0\xa1\xc4YF\xbaU\x9a_0\xba\xfb\xee\xfc}\xf7\xd9QJBJ\x80\x86\x9f\x16\x04\xe2;HV\x14\xc8c\xbc\xa6kh\x94,Pk\xd40\xf1\x00\xa0\xff\xcfy \xcf|\xabQqV\xd9\xfc$[,\xe0!\x8d\x97a\xfa\x04\xf7\xe4)\xb0\xe9\xbc\xd9\xbf\xb7_\x81\xe6%\xad\x0b5[^v!\x83[TC\x91\xe8\x0b\x89\xeeab\xe3\xb770\xf3aN\xee\xc2lAa\x16\xc0tj\x8173\xa8\x91 \x0d\x1b\xc6\xab\x9dB0\x12\n\xd6\x98v{8\"p\xb1\x91\xaaf\x86K\xd15\x14\xacF\x00\xd83U|cj\xf2a\xe6\x0fM\xfb\x16WW\xb6\x07]\xcdW\x1f\xe1]Q\x97\x15\x17h\xe1\x85Bf\xb0\x04\xc3k\xd4\x86\xd5\xcd\xef\xe0(KS\x92\xd0\x9c\xc6K\xb2\xa6\xe1\xf2\xa1c\xbak\xca\x7f@Zh\x96\xc4_3\x02\x93V\xc7\xc02\x0f:\x1e\xbe\xe7_{\xdet\n\x85\x14\x02\x0b\x03\x9a\x97\xe8\x8d\x0c\x92\x15\x86\xef1\x17\xb2|\x99e\xbb\x7f\xed \xdd\xb9s1L\x13RrGR\x92D\xc4q\xcb\x00\xf0a\x95\xc0\x9c,\x08%\x10\x85\xeb(\x9c\x93\x13vG\xb9=\xad\x8ak\x83\xe2\"\xab\x86i\xfd&ZR\x99Q\x13\xb6\xf1[\x98\xf9\xffU\x85\xc0\x9e\xcbjq\xe0\x1e's\xf28\xc6=o\x11\xf9w\xfc\xd9\xb6qU\xc9\xd6q\xf2\x19\x9e\x8dB\xec\x08\xb5\x12\x8fh\xba\xa9\xe4\x8f^\xcbv\x9fw\xf7\xd4Y\xaf\xd1V\xcb\x9d*\xbaC8%F\x94sMz@\x9eU\xae-T\xa26\\\xd8\x0b\xeet\x19\x1b\x8d\xeb\x97K\x1d\x0e\x97\x8bK\xa1\x1d\xfa\x7f\xb2\xcbq\xfe\xe0\x9a\xfe\xe58]\x7f\xf7\x1e\xc0\xd1K\xf2\xb6J\x8e\xeb\xdc)\x05\xe7D\xbddDk\x98\xfc\x0c0w\x8b\xf7\xf6\xec\x0c\xe6\xd8\xf2\x0c881\x90\x7f\xed\xfd\n\x00\x00\xff\xffPK\x07\x08\xa2#+\xbd\xf8\x01\x00\x00\xa8\x06\x00\x00PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xcb\x92\xa2?W\x1c\x00\x00\xd8\xae\x00\x00\x07\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x00\x00\x00\x00CREDITSUT\x05\x00\x01\x80Cm8PK\x01\x02\x14\x03\x14\x00\x08\x00\x08\x00\x00\x00!(\xa2#+\xbd\xf8\x01\x00\x00\xa8\x06\x00\x00\x10\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x81\x95\x1c\x00\x00schema/flows.sqlUT\x05\x00\x01\x80Cm8PK\x05\x06\x00\x00\x00\x00\x02\x00\x02\x00\x85\x00\x00\x00\xd4\x1e\x00\x00\x00\x00" fs.Register(data) }